Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Great work #1

Open
jonshouse1 opened this issue May 27, 2017 · 7 comments
Open

Great work #1

jonshouse1 opened this issue May 27, 2017 · 7 comments

Comments

@jonshouse1
Copy link

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
Copy link
Owner

Jeija commented May 27, 2017

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
Copy link
Author

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
Copy link
Owner

Jeija commented May 27, 2017

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
Copy link
Author

jonshouse1 commented May 27, 2017

> 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
Copy link
Owner

Jeija commented May 27, 2017

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
Copy link
Author

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
Copy link

ajvpot commented Dec 9, 2017

How did you modify the H801?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants