Jeija / ESP8266-WS2811-LEDs

ESP8266 driver for WS2811 LED Strips
34 stars 6 forks source link

Great work #1

Open jonshouse1 opened 7 years ago

jonshouse1 commented 7 years ago

Not had time to try this code yet, but it looks fantastic. I plan to modify an H801 lighting controller to use with this.

Very very minor thing, should the comment "Fill tape with color data, 32bit of color data per color" be 24 bits of color data ?

Jeija commented 7 years ago

No, I think 32 bits should be correct, though I have to admit it is kind of poorly worded. I assume you are somewhat knowledgeable when it comes to the pixel format the WS2812 / WS2811 LEDs use, since you seem to have a repository doing that on your GitHub.

Basically, we need to encode the color data as ones and zeros, where those values are represented by different HIGH and LOW times on the single data wire: WS2811 timing

So in order to generate those timings, we can approximate them by saying the 0 code and the 1 code take approximately the same amount of time in total, just different HIGH and LOW times. So in this project, I'm encoding a logical 1 as "HHLL" and a logical 0 as "HLLL":

#define WS_BIT1 0b1100
#define WS_BIT0 0b1000

These High / Low values are directly written to the output pin by the I²S hardware. So in order to store the data for 1 color channel (= 8 bits of data), I need (8 data bits) * (4 output pin values per data bit) = 32 bits of space in the "tape".

jonshouse1 commented 7 years ago

Ok, I get it now, thanks :-) I was getting confused betwen the 24 bits per pixel format and the line format.

I am using the driver from your project now in my own code, works great. Only snag is I want to drive >300 LEDs. I am not sure I know enough about the DMA I/O on this chip to cascade the buffers and update them. I've modified an H801 lighting board to provide the WS2811 output in place of one of the 5 LED channels, seems to work ok, except for pacmans missing head after pixel 300. ws2811panel

. I assume you are somewhat knowledgeable when it comes to the pixel format the WS2812 / WS2811 LEDs use, since you seem to have a repository doing that on your GitHub.)

Yes and no, I did not write the driver for ws2811 in the project. I took from this project, the guy is a genius: (https://www.youtube.com/watch?v=6zqGwxqJQnw) I will have a quick look at his code to see if it drives more LEDs, the snag is it just a modified version of an I2S driver and really needs a clean up, the driver from your project is much nicer.

I did write my own 2bpp driver for RPI, but that was a while back :-) (http://www.jonshouse.co.uk/ledsign.cgi)

Your code works great, just need to figure out how to cascade those DMA linked lists. I don't get as much free time as I would like so that sometimes limits how much I can do for any given project.

Thanks, Jon

Jeija commented 7 years ago

Nice work on that LED panel 👍!

I see two different solutions to your problem: The cleanest solution probably is to cascase the DMA buffers, this should be doable by adding a second slcRxDescriptor and linking the first one to the second and the second one to the first, I thing you need to modify this line for the current slc descriptor and add a similar line for the second one:

slc.next_link_ptr = (uint32_t)&slc;

The problem here is that noone really knows much about the DMA subsystem on the ESP8266 (at least at the time I wrote this code), because the documentation doesn't seem to be out there.

The other solution is to use different encodings for the data bits. Instead of using 4 bits "HHLL" / "HLLL", 3 bits "HHL" / "HLL" might also just suffice. If your LEDs are tolerant enough for those three-bit timings, you should easily be able to drive your 360 LEDs without changing any critical low-level DMA code.

jonshouse1 commented 7 years ago

> slc.next_link_ptr = (uint32_t)&slc; Yes, I found that. I assume I make an array of "static struct slcRXDescriptor slc" or just a second instance of the struct and point the two structures at each other. I just know deep down I will be looking crashes for the next N hours if I try it though !

Does making HHL/HLL 3 bits rather than 4 make the timings 25% faster ?

Thanks, Jon

Jeija commented 7 years ago

Yes, every bit will still take the same time on the wire, so timings will be faster when using just three instead of four bits. However, you can adjust the time each output bit lasts by changing the values of I2S_BCK_DIV and I2S_CLKM_DIV in the ws2811dma.h header file. If you happen to have an oscilloscope / logic analyzer, this should be really easy to test. Otherwise, it's kind of trial and error.

jonshouse1 commented 7 years ago

I have a digital scope, I will go and play. I've yet to try your UDP generation code but it looks great so I will try and find time to play with that this week.

Huge thanks your code and help :-)

ajvpot commented 6 years ago

How did you modify the H801?