bigjosh / SimpleNeoPixelDemo

A demonstration showing how easy it can be to drive WS2812 NeoPixels
MIT License
223 stars 59 forks source link

This technique may not work with GS8208 pixels! #17

Closed benpeoples closed 3 years ago

benpeoples commented 3 years ago

GS8208 pixels are in the category of pixels that work with a broad spectrum of control schemes-- they support from 400kHz to 1MHz bitrates, and the datasheet calls for a 3:1 ratio between T1H and T1L (and a 1:3 ratio between T0H and T0L). And I think they're too smart to fall for this scheme. Which is annoying.

Image of relevant bit of datasheet attached. Screen Shot 2020-11-13 at 10 36 11 AM

The 10us between code I had assumed meant that the TxL time could be up to 10us long, but that doesn't seem to be working.

I'm doing this on an 8MHz Atmega328p. Based on the (working) 800kHz adafruit code, we're looking for these values:

T1H = 875 (7 clocks) T1L = 375 (3 clocks)

T0H = 250 (2 clocks) T0L = 1000 (8 clocks)

The asm is, of course, working properly for the TxH codes, but the TxL codes include the loop time, which (having removed that asm code), is a minimum of 21 clock cycles or 2625ns.

If T1L = 2625, then T1H = 6125 (or 7875 if it's really 3:1) T0H would be 2625 and T1L would be 6125 (or 7875), less the loop time we're at 3500/5250

That's only 114kHz, which is below the minimum 400kHz, and does not work (first LED lights up white when given red...)

My working theory is that we can send either 8 bits or 24 bits at a time, with up to 10us between them. In theory I should be able to get the loop time low enough to at least hit the 400kHz timing, if not the 800kHz. I will obviously post updates here, but I mostly wanted to flag that I was having trouble getting this particular pixel working in case anyone else ran into the same issues I did.

benpeoples commented 3 years ago

OK, it's now working. The only change I actually ended up having to make was to compile it with -Ofast instead of -Os.

The binary is about 5x larger (2748 vs. about 530 bytes), but it appears to be working just fine with a ~8us interrupt firing every 4 microseconds.

The main loop looks like this:

`while(1) { _PORTB.B0 = got_data; got_data = 0; for(int x = 0; x < 50; x++) {

        cli();
        sendPixel(universe[x*3+1],universe[x*3+2],universe[x*3+3]);
        sei();
    }
    show();
    _delay_ms(5);

}`

universe[] is getting written by the ISR for the serial port, got_data is getting set to 1 whenever we get a new DMX packet, and then cleared by our loop. Makes for a very flickery LED that instantly goes out when we lose DMX data.

bigjosh commented 3 years ago

Interesting! I've never heard of these new GS8208 chips. What are the advantages compared to the WS2813 and sk6812?

Thanks!

benpeoples commented 3 years ago

GS8208 has a couple of advantages, but mostly it was offered by our supplier in lieu of sk6812 or ws2813 on this project. We'd been testing with I think sk6812 bullet pixels.

Like the WS2813 it has a backup data line, and it'll support up to 1MHz signal clock (vs. 800kHz)

I believe it has a higher pixel PWM rate than the WS2813, and the more relaxed timing restrictions are supposed to be an advantage.