Snippet - WS2811 Led Strip SPI driver

WS2811 Led Strip SPI driver

Uses SPI bus at 3.2Mps to address 800kb/s models or 1,6Mb/s for the 400kb/s one (untested), dynamicaly creates a 1kB lookup table for fast transcoding. Datasheet available here : http://www.nooelec.com/files/WS2811.pdf

The demo uses an old Rhino GHI board, and 4 meters / 240 RGB leds from adafruit. Sorry for the quality, the leds are too bright for my Camera. Also at the end you will see the rainbow running at full speed for 5s (too fast to see) then with an extra 20ms delay before each shift for 5 more seconds.

For more details, please read the comments in the code !

6 Likes

Very nice! I need to get a led stip like that…

Well done

Awesome!

Cool!

Thank you all for your support !

Updated v0.2 online

Pl, this is not a stuitable code for the led strip you are refering to, which is using a ws2801 chip and requires a clock.

But you are lucky : Eric (Ransomall) provided some code for that : http://www.tinyclr.com/codeshare/entry/259

Working flawlessly on a cerberus and an adafruit neopixel rgb strip, even beyond my expectations in speed and response time. (The product description for the strip on adafruit heavily insists that it works only with arduinos, don’t believe it).

Just a question : as it is high speed clocked on the spi bus, how does it impact other modules on the bus, like, say, the ethernet module, are they still usable ?

Regards and thanks you very much for sharing this code.

@ Fradav - Will be interesting to see, but i would think you cant run anything else on the bus - try using it with the Ethernet firmware if you arnt already…

@ Fradav,

Unfortunately, I don’t think it will work with other devices on the SPI bus. Because this is not really SPI (no use of the CS signal to select a particular SPI device on a bus), we are using SPI to bitbang a WS2811 compatible signal, therefore the strip won’t be able to make the difference if you are sending the data to it or to another device on the bus.

So, when you are sending data to the ethernet device, it will work, but at the same time the strip will show random pixels.

One way to bypass the problem would be either :

  • to use a second SPI bus dedicated to the led strip (old GHI boards like the panda have 2 available, I don’t know for the cerberus)
  • to add a little more electronics (maybe just an AND gate) to devalidate the data going to the strip when the CS pin for the ethernet device is selected.

Good luck :slight_smile:
Nicolas

Like this but running MOSI thru the AND Gate instead of SCK…

@ Justin - Is this schematics available as a module/breadboard somewhere ?

@ Fradav - i am going to send that one and another design for the 2811 off to fab in the next day or so…

@ Justin - If would to buy 3 of those breakouts if they are avalaible soon.

I see that in your design you take pin3 as the “active” bit for validating data, wouldn’t it be more consistent to take the pin 6 (CS) for the sake of SPI logics ?

@ Fradav - I assume you want the WS2811 version? - Will take about 10 days to get the boards.
Ping me an email justin at ingenuitymicro dot com
Unless i am looking at it upside down CS is on Pin 6 as per SPI specs…

@ Justin - forget it, I misread the pin labels.

I suppose that to “gadgeteerize” Nicola3’s code, I have to replace its spi init by :

                 
               // Initialize SPI
                _WS2811SPIConfig = new GTI.SPI.Configuration(false, 0, 0, false, true, (uint)speed);
                _WS2811SPI = new GTI.SPI(_Socket, _WS2811SPIConfig, GTI.SPI.Sharing.Shared, this);

Right ?

@ Fradav - Yes it would like you code.
Once i have the boards i will write a Gadgeteer driver based on Nicola3’s code

I have ordered a 4m strip and a swag of 5050 2812 leds so once i get them will hook it all up and post the end product…

I’m getting a “Exception was thrown: System.ArgumentOutOfRangeException” error in this method.

        public void Set(int index, byte r, byte g, byte b)
        {
            // Transcode
            Array.Copy(_WS2811Table, g << 2, _WS2811Buffer, index * 12, 4);
            Array.Copy(_WS2811Table, r << 2, _WS2811Buffer, index * 12 + 4, 4);
            Array.Copy(_WS2811Table, b << 2, _WS2811Buffer, index * 12 + 8, 4);
        }

Has anyone had this issue?

Oh and I’m using Adafruit’s new NeoPixel (40 pixel) shield. Nice piece of hardware.

@ JerseyTechGuy - How many pixels have you set?

 int NumberOfLeds = 240;

is the default in example