Adding DMX512method to ESP32 I2S & I2Sx #825
Replies: 9 comments 10 replies
-
That number looks close. It will be easier in a few days (hopefully). I am in a middle of some refactoring for ESP32 that reduces some duplication between i2S and thew new (still not in an official release) ESP32-S3 LCD parallel feature. Lots of testing and I found a problem with the i2s x16 encoding. One of the things that got refactored was the timing. The new timing classes look like this...
So, you now set the total time in nanoseconds a single bit should take. Much easier to understand and modify. |
Beta Was this translation helpful? Give feedback.
-
Oh that does sound interesting, and a bit easier to calculate. I suppose that the 3 step or 4 step choice would apply to all the parallel channels, or can you pick per per channel ? I mean that is what is so different about the DMX512 / WS2821, which is basically 1 step, but with added start bit & stop bits. If 3 or 4 step becomes a choice per channel, then the 1 step would also be a simple choice. It is great to hear that memory reduction for the parallel methods is on the list. It was one of the reasons holding me back from using it. Generally i would want to have 4 universes (680 pixels) per channel, but already at 8 channels things were getting a bit out of hand, memory wise. A 25% reduction would be a serious improvement. My request would initially be for the single channel method, which i think would be less complex anyway, a sort of copy paste from what you did for the esp8266. On my current project i added DMX out, but the only DMX library i found has some compatibility issues, and requires almost undivided attention from the core to function properly. The ESP32 UART and the FIFO is to complicated for me to understand, To be able to send a DMX512 universe in the background on one of the I2S channels while i send 4 WS2812 universes on the other seems like a lot more efficient solution. If i ever get to a point of selling significant amount of product (oh i am such a dreamer.. ;-) ) a small donation per piece does make quite a lot of sense. On the use of the esp8266 DMX512 i am still at only 10 pieces. You know i sell the hardware for a specific purpose and give the software away for free as a part of it. |
Beta Was this translation helpful? Give feedback.
-
#828 |
Beta Was this translation helpful? Give feedback.
-
Yes i only found 3 instances where that particular variable (
With only 1 bus, and 1 architecture it is also a lot simpler i guess. The ESP32 provides functionality for different output on different busses and various architecture. The DMX512 method is in that case not fully incorporated into the methods but kept separate for the different filling of buffers it requires. (btw this must be a typo in the comments) A little hard to tell for me what is a better design or not. Quite a lot of it is beyond me you know. |
Beta Was this translation helpful? Give feedback.
-
So i had some time to have a look and test the cadence 3 & 4 step. It seems to work both, though i started out with the (at the time) un-released version 2.8.0, and i wasn't quite sure what to do on how to choose between the cadence, but anyway i am sure it does work perfectly, at least on the WS2812b's i've tested it on. Now the T_CADENCE opens the door for adding a different encoding and since for DMX512 an 11 step encoding is required (1 start + 8 data + 2 stop) as you know i thought i'd have a go and see if some small modifications i could get closer towards that. I had mentioned already that it would require to change the passing of the number of dmaBitPerDataBit to a dmaBitPerDataByte value, so i decided to see if i could manage to do so without breaking anything :-D
in ESP32_i2s.c i changed the prototype definition for
and the function
to mathc the prototype and where it calls
and within that function where it uses that variable to calculate the clock divider (i think
Now all i had to do was change the 2 existing Cadence classes in NeoEsp32I2sMethod.h
&
and the call to
as well as the construct which uses the variable
As you can tell i've been marking the places where i have made changes. Now i have started on the having a go at the implementation of the DMX512. I've had a good look and though some confusion on certain matters i have something that at least compiles and in my opinion should work.
There is a few things of course. The break, i kept it simple and since the inverted bit is not part of the encoding like on the esp8266, i think i got it right. If it's actual DMX hardware that is being used instead of the ws2821 ledstrip, it anyway doesn't matter much, since one can easily swap the A & B lines of the transceiver. There were some unknowns to me in the original code. Things i was just unsure of particularly in the construct and i got seriously confused by the 'const' in |
Beta Was this translation helpful? Give feedback.
-
So I added the SpeedBase and the typedefs and i think i got those more or less correct.
and
It all compiled, but then as expected it didn't work. I had the start & stop bits inverted, corrected that. and i got some result, but not what i wanted. The break was recognized ok. But somehow the data stream is not arriving properly, and i concluded that it isn't sent properly.
That is just 800KHz regardless of the cadenze. Hmm any chance you are willing to help me out here. It is your code, you know your way around. |
Beta Was this translation helpful? Give feedback.
-
Ok so Github is not something i use very often and the details on creating forks & branches and pull requests elude me a little. Maybe when i find so extra time and motivation on the matter. I found a more elegant way to be able to use the correct |
Beta Was this translation helpful? Give feedback.
-
Ok i will have to sort out how to use github properly. I changed a few small things to make channel 0 part of the break so ch 1, 2 3 can be RGB to the same pixel, but that had some more consequences. I also suspect now that the glitch i saw was actually caused by something else. Although there is filling of the last 16-bit word with '1' 's the buffer is 32-bit aligned, which may result in there being a a whole 16-bits of '0' , which is enough to be recognized as a 'false' break. With the break time now being more than 4 bytes, this may be even worse. The break was a perfect 4 bytes before and now ends up being 6 bytes, so chances are that the last 2 bytes will be empty and the 2 bytes before that wont be. And those last few bytes of the buffer are looping right ? They should be either all HIGH or all LOW. Best is all HIGH i guess, so i figured something like this for the construct
I will work out the branch and fork thing properly, but that will take some time. I also have an idea on how to significantly speed up the 3 step encoding, which should make it nearly as fast as the 4 step. |
Beta Was this translation helpful? Give feedback.
-
Ok so i've finally managed to create the pull-request, hope i did it all correctly
What confuses me a little is that it is required to put the break at the start of the stream. I was under the impression that the last section of the data-stream gets looped until a new stream starts, which would basically mean we could start with just the MAB, if the last few words of the stream are 0x0. If the output pin is just idle at the end that would make sense, but it appears that it just isn't, which may be the cause of the occasional glitch. I also have no explanation for the WS2812b working without any glitch, but i am confident that the internal workings on the I2S bus are beyond me, and also that the reason / cause is there. I might be wrong though. I also tried with a pullup (and with a pulldown) resistor on the output pin, just in case it is cause by the pin being temporarily in input mode for some reason, but no luck. Anyway if you have time, have a proper look. |
Beta Was this translation helpful? Give feedback.
-
As i asked you already in the old conversation But i understand a new conversation makes sense. It would probably need to structured a tad differently for the I2Sx method, the issue being the different way in which the output buffers are filled, and that within the same structure as all the other I2Sx methods hmm anyway i am also a little confused about the I2S sample rate for timing. The WS2812b method (as all others) uses 100000, but that is at 4 bytes per byte, pretty sure that is 3.2Mbps , so would 250Kbps come down to 7812,5 ? it is such a weird number.. Anyway i am sure you know better.
Beta Was this translation helpful? Give feedback.
All reactions