|
|
View previous topic :: View next topic |
Author |
Message |
thefloyd
Joined: 02 Sep 2009 Posts: 46
|
help with high speed serial output (WS2811 IC, driving LEDs) |
Posted: Tue Sep 11, 2012 1:24 pm |
|
|
Hi!
I've been lurking here for many years, and have gratefully used some of the code examples given by others for various pieces of hardware on my workbench.. now I need some rather specific help
I'm looking to drive strings of LEDs based on the WS2811 IC. This IC is different from the standard SPI ICs such as the WS2801 and the LPD8806, both of which I've easily been able to write to using SPI. This IC has no clock line..
Instead, the data is sent using only a single wire - the protocol has been described as NRZ or Manchester (don't think it's exactly either, see http://doityourselfchristmas.com/forums/showthread.php?19654-WS2811-pixel-compatibility/page2 for more details). There's a datasheet floating around (google ws2811).
Anyway, my question is how best to attempt to send data out to these strips. I can clock a PIC at 20 or 40mhz, which should give me the ability (at least in theory) to reach 100ns accuracy (obviously not including the C overhead, etc) using things like delay_cycles(). If I wanted to clock out 24 bits of data - and needed to fit the timings given below - what's the best approach? (note there's some conflicting info. The DIY Christmas site lists different timings for the WS2811, the timings I have below are from the actual data sheet).
HS mode: 1250us
0 = 250ns h + 1000ns low
1 = 600ns h + 650ns low
I don't know if anything uses low speed mode, but just for giggles:
LS mode: 2500us
0 = 500ns h + 2000ns low
1 = 1200ns h + 1300ns low
Any thoughts/suggestions/pointers/help would be sincerely appreciated. I'm definitely not experienced enough to be able to clock out data with this level of precision.. my best effort would be to do something like output_high(pin) ; delay_cycles(...) ; output_low(pin) and I'm sure I'd be completely unable to achieve the timing required using this method.. I'm afraid this is a case for some handcrafted assembler, but that's way out of my league..
[edit] the more I look at the timings on that datasheet, the less I feel like they're legit (a 1 has a longer 'low' period than 'high' period?). From the DIY Christmas website:
The WS2811 recommended timing essentially divides the bit cell into fifths. A 1 is sent as 1000ns high (4 segments) followed by 250ns low (1 segment), while a 0 is sent as 250ns high and 1000 ns low. The fact is that either approach will work, the only thing the pixel chip really cares about is the state of the data line at 625ns.
Either way.. I'm still trying to solve the same problem. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19557
|
|
Posted: Wed Sep 12, 2012 4:05 am |
|
|
You can drive the WS2801, with SPI.
I've used the 1804 chip, which is at the core of this device.
I was using a processor at 48MHz, Using Timer2 to feed the SPI, allowed me to select 4Mhz as the SPI clock. (prescale=1, postscale=1, PR=2).
What I did, was send byte patterns for the data wanted, as:
zero=0b011000000
one=0b11110000
On the SDO line, you then get patterns with 500nSec high, 2000nSec low when you send the 'zero' byte, and 1250nSec high 1250nSec low when you send the 'one'. This was happily accepted by the chip.
Hope you can get it to work as well.
Best Wishes |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9249 Location: Greensville,Ontario
|
|
Posted: Wed Sep 12, 2012 5:03 am |
|
|
use Google and you'll find a couple of sites that use SPI as Ttelmah says.
one was on the first page ! |
|
|
thefloyd
Joined: 02 Sep 2009 Posts: 46
|
|
Posted: Wed Sep 12, 2012 6:56 am |
|
|
Awesome idea! Thanks! I'll see if I can get that working tonight. |
|
|
thefloyd
Joined: 02 Sep 2009 Posts: 46
|
|
Posted: Wed Sep 12, 2012 7:04 am |
|
|
Just an aside, it looks like your timings are for the low speed mode of the 2811. Not sure but I think most stuff these days uses the high speed mode where those timings are cut in half. (1250ns is the length of the whole period not 2500). |
|
|
thefloyd
Joined: 02 Sep 2009 Posts: 46
|
|
Posted: Wed Sep 12, 2012 8:28 pm |
|
|
And finally, a follow-up. Thanks for your help! I got my string of 50 LEDs working using this method. Next stop will be the SMD5050 LEDs with integrated WS2811 ICs that I'll be receiving soon..
I changed my approach a hair. I had a PIC 18F46K22 part on my desk. I ran it with a 64mhz internal oscillator and used SPI_CLK_DIV_16 to achieve the 4mhz SPI clock. Worked like a charm!
Also, my set of lights behaved a bit differently. I had success with:
0 = 0b10000000
1 = 0b11110000
Hope this helps anyone who might try this next.. :D Some relevent code bits are below..
Code: |
setup_spi( SPI_MASTER | SPI_L_TO_H | SPI_CLK_DIV_16 );
spi_write(0b11110000); // write a one
spi_write(0b10000000); // write a zero |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19557
|
|
Posted: Thu Sep 13, 2012 3:23 am |
|
|
I'm having a 'sneaking suspicion', that your chip is using the high speed mode, as already mentioned by another poster. You've had to reduce the high pulse for a '0' to 250nSec, which suggests the sampling point, is perhaps about the 310nSec used by this mode.
As you have found though, provided the signal is right at the sampling point, the protocol is very forgiving.
You could probably increase the SPI clock rate, and go back to the older data layout, but if it is working, the time saving is going to be insignificant.
Glad it got you going.
Best Wishes |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|