Can i limit the amount of Channels that i receive thru the API ? #111
Replies: 9 comments 8 replies
-
To answer your question: no, there is currently no way to reduce the size of the DMX frame that is received. The DMX driver will automatically receive the entire DMX frame whether it is 1 byte long or 513. Is it possible to store an array of partial DMX packets in RAM and then, after the recording is finished, disable the DMX driver and write the arrays to flash? It would use a lot of RAM but it might be possible depending on how many DMX slots you are recording. For example if you are recording 32 DMX addresses for 10 seconds at 44Hz, this would use ~14KB. You should be able to heap allocate or statically initialize this memory. Are you using ESP-IDF or Arduino? If you are using ESP-IDF, you should be able to configure your ESP32 to place the DMX interrupts in IRAM. When interrupts are in IRAM, DMX will continue to be received even when writing to flash. Unfortunately, this option is not available on Arduino due to how Arduino configures the ESP32. This sounds like a very interesting use-case. I am interested in supporting it if neither of these solutions work. Let me know your thoughts! :) |
Beta Was this translation helpful? Give feedback.
-
But how does it work ? when i call dmx_receive() and it wait for a full packet or until the timeout, (or more correctly if a frame has been received since it was last read since it was enabled i guess) but what is used to end that process, a simple counter ? (to 513) or are there other conditions to be met. If it's just a counter then a simple modification would do the trick. It isn't really possible to store received packets in RAM unfortunately, since that would limit the length of the recording, which ever way you look at it. Even SPIFFS is to limited for this, only an SD-card will do the trick. (Seconds or minutes of stream are not the goal, hours is what we want) It is a bit compounded by the fact that i actually record the output and un-compressed. The idea was to just simply record the output stream regardless of whether that is actually changing. As i said, when Art-Net is the source, this works just fine. The time that it takes to store a frame of 2Kb is significantly less than 20ms, even at moderate speed, but once the SPI speed is at 32MHz, which is fine for the SD, there is no problem.
I am using the Arduino core. I thought i could place any ISR in IRAM, is this not true ? could you elaborate on this, The ESP32 is a rather complex MCU with the 2 cores and all those peripherals, it is a little beyond me at times. So if there is a way to trigger the frame-complete flag at a point where, say only 256 slots have been received (or even less) and processing including writing to the SD, can continue and can be completed so that before the next break arrives, the driver can be re-enabled, that would be the goal. |
Beta Was this translation helpful? Give feedback.
-
So anyway i've done some modification, i added to hal.h bool dmx_driver_enable_rxsize(dmx_port_t dmx_num, uint16_t rx_size) { dmx_driver_t *const driver = dmx_driver[dmx_num]; driver->rx_size = rx_size; // Initialize driver flags and reenable interrupts return true; |
Beta Was this translation helpful? Give feedback.
-
Ah, you could have pointed it out, but i think i've found it. |
Beta Was this translation helpful? Give feedback.
-
Hmm well whichever way i do it, the only way to get (near) 40Hz reception is by leaving the driver enabled, which causes a conflict with some of the other stuff, also callbacks to from the WiFi webserver (probably the WiFi causing it) although that would still be OK, i can just skip the received frame if i have to. The code is just to complex for me to fiddle with i guess. With other methods i have tried i find that disabling the UART RX interrupt is not as straight forward on an ESP32 as it is on an ESP8266 (switch the pinMode) or an AVR (disable the interrupt) I am now looking at using an extra MAX485 transceiver that is used to find the break(i can mange to find the break just fine) and enable the one connecting to the UART. This is completely outside of your library of course, so unless you have other suggestions on dealing with the issue i am having i shall not bother you with that. |
Beta Was this translation helpful? Give feedback.
-
Actually come to think of it, i am only getting the 40Hz reception if i do a very sketch, and even then it is blocking in nature. |
Beta Was this translation helpful? Give feedback.
-
Yeah thanks for that, i am of course thinking and pondering,
Ok, so does that mean that if i do call it, it always waits for the 'next' complete packet or if a complete packet has arrived already it will just be a dummy call ? I am actually suspecting that the use of the hardware timers is an (the) issue, The I2S method for the ws2812b signal may use the same timers or prescaler, i am not sure, and this may cause frame errors and so forth, i can't quite tell what is going on, but i am going to explore another avenue, where i will try do a simple reception of Serial, and use an external timer to find the break. Basically i am adding an ATtiny13 to listen to pin state changes and change the state of it's output pin when no change has been observed for at least 80us, Hooking it's output pin to an ESP32 input pin should remove the need for a hardware timer altogether if i am not mistaken ? (except maybe for the reception timeout, but that seems less important to me) Hardware timer are a resource that is often used by all sorts of things, and if they can not be placed in IRAM that causes issues of course. I was playing with the ESP32TimerInterrupt.h library and found that even calls to it conflicted with analogWrite(), probably because of the IRAM thing, but i can't be sure, still taking that part out of the equation should have a positive effect. To implement that in your library is a fair way beyond my skill level. Messing with someone else's code is always more tricky, more so when it involves fairly low-level programming and with fairly extensive features. I recon i should probably be able to get a basic version working, but of course it would be better if you could support the idea. |
Beta Was this translation helpful? Give feedback.
-
So anyway i got the break detection to work on ATtiny and i do have some basic sketch that does receive the data accurately,
and if i hook it to an Input pin, pin change interrupts will signal the ESP that the break is found. As said i have a basic sketch working, but i don't really know how to manipulate the UART, it's fifo and it's buffer, I gonna ask on the forum a bit, not having direct access to the RX buffer is rather disturbing, Normally speaking setting the head and the tail to the same value flushes it, which is of course what i want to do, although, actually reading from the FiFo, well i set the FIFO to 1 byte to circumvent these issues, bit that is not very efficient of course. So anyway you are much better at this and i am wondering if you are willing to support this method with external break-detection ? |
Beta Was this translation helpful? Give feedback.
-
Anyway did another little test and found that with these settings, the break detection fires for anything over 88us
this allows for the extra cycles of the counter. and the minimum delay makes sure it fires with something like a few us accuracy. |
Beta Was this translation helpful? Give feedback.
-
Ok a little bit of background, first of all i somehow don't think so or i wouldn't be asking, but i might have missed something.
The reason i want to do this is as follows. I have a sizeable program that in essence is sending WS2812b signal and the signal is generated based on incoming data, which can be DMX or Art-Net and there is a standalone function included. All great all works without issue, The DMX too thanx to this library. Now in the Program there is also the possibility to record the output on an SD-card and play it back. For Art-Net & standalone this all works like a breeze after some tweaking here and there. The WS2812 signal is sent fully in the background using I2S (Neopixelbus) with 4 universes of output my maximum framerate is close to 50Hz which is easily enough time to write a frame to the SD-card and receive Art-Net , but when i write to the SD-card, the DMX frame gets corrupted, basically i think a break is recognized that isn't there, but it could be something else, so anyway if i disable the dmx-driver during the SD-card write stage all is still good, but then my reception framerate drops by half, since the first brake passes before i switch it on again, and so i loose a whole frame. A DMX frames takes roughly eh.. (1 / (250.000 / 12) ) * 513 + break time, say 25ms , 40Hz that looks fine, 20Hz is not to good. (actually i think may even be losing 2 frames, can't really be sure of that though) Now since usually when dealing with DMX i will not be using all channels, and when recording that situation is even less likely, i figure i could do it the same way when i was Using an AVR & bit-banging. Wait for the break, read the channels i want, start doing what i want to do and if i'm done in time for the next break then all is good. But this system requires the reading of a whole frame, so i was wondering can i just reduce this ?
driver->rx_size = DMX_PACKET_SIZE_MAX;
Beta Was this translation helpful? Give feedback.
All reactions