Question about programming the WS2811 RGB LED.
NWCCTV
Posts: 3,629
So I was showing off the WS2811's that I picked up from Pololu (http://www.pololu.com/product/2536) to my grandson. When I explained to him that they could be programmed to display up to 256 million colors he says to me " so make them do all of them"!!!! This got me to thinking, is there a way to have 6 of these LED's advance to the next color after a few seconds? I know there would be a limit but what is that limit and how would I program them to do this. This can be my End of Year, Start of Year project just for him!!!!

Comments
Sorry to disappoint you but there aren't 256 million colors. There are only 16,777,216. That's if you count all off as a color.
You could certainly start a loop with a variable incrementing by one and send the variable to the WS2812 driver to be displayed. This is incredibly boring. If you scrolled through ten colors a second it would take 19 days to get through all the colors. And when the colors are displayed with just an incrementing number, it's very uninteresting to watch (guess how I know).
Try something fun like my hypno rings code (MirrorWheels in post #2 of the following thread).
http://forums.parallax.com/showthread.php/149822-Fun-With-NeoPixels
I wrote the "MergeColors" method to make it easier to display sections of the rainbow. There are a variety of other rainbow type demos available. I'm sure I could help you with a simple demo if you don't find one you like. How many LEDs do you have?
http://obex.parallax.com/object/703
but here is Peter's interactive Tachyon code for the WS2811
http://forums.parallax.com/showthread.php/157792-Interactively-test-WS2812-NeoPixel-LEDs-with-Tachyon-and-serial-terminal-Matrix-demo?highlight=ws2811+tachyon
if you are not afraid of Forth.
http://propaneandelectrons.com/blog/the-difference-between-ws2811-and-ws2812
looks like one is the driver chip, the other the LED with the chip.
So Peter's code should work for a very impressive interactive demo.
http://en.wikipedia.org/wiki/Web_colors
You can send these to your array, however many at a time as you like. You will find that many many of them just appear white because the apparent luminosity is very non-linear.
This can be partially fixed by dividing each color value by whatever it takes.
But the bottom line is, in my experience, that these devices can actually display only a few tens of distinguishable colors.
I would suggest that the devices can display the entire range -- our eyes, however, are unable to discerns subtle differences between them.
It cycles through all the possible colors, but can increment by more than unity AND doesn't take each color value up to 255. Depending on the StepSize and MaxColor, it takes "a few minutes" to run.
It would be interesting to put a Ws821X and a TCS3200-DB Color Sensor in a light-proof box to see have many color values can be generated. But, "A difference is a difference only if it makes a difference". How many can the viewer distinguish is what really counts.
{WS2811 Driver Demo} CON _clkmode = xtal1 + pll16x 'Standard clock mode _xinfreq = 5_000_000 '* crystal frequency = 80 MHz NbrLEDs = 10 'number of leds in a string WSPin = 16 'data into LEDs SyncPin = 4 'scope sync '++++++++++++These are the two values to experiment with+++++++++++++++ StepSize = 3 'how much to vary each color + MaxColor = $3F 'max color value + '++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ColorField = $FF 'each color's field size BlueShift = 0, GreenShift=8, RedShift = 16 'position in color word VAR long Frame[NbrLEDs] 'data for LEDs long Command '<> 0 says => display frame long MyParm[6] 'passing addresses, etc to display driver byte Cog long symbol, random long color 'current color OBJ pst : "parallax serial terminal" PUB main pst.Start (115_200) 'start up ser terminal pst.str(String("hello, world ")) 'runs in cog 1 pst.NewLine waitcnt(clkfreq/10 + cnt) MyParm[0] := WSPin MyParm[1] := @Frame MyParm[2] := NbrLEDs MyParm[3] := @Command cog := cognew(@PCog, @MyParm) 'start up the output cog pst.str(String("Panel Cog: ")) ' pst.hex(Cog,1) pst.NewLine waitcnt(clkfreq/10+cnt) repeat symbol from 0 to NbrLEDs-1 frame[symbol] := 0 repeat color := color + (StepSize<<BlueShift) 'increment blue if (color & (ColorField<< BlueShift)) > (MaxColor<<BlueShift) 'test if blue is greater than maximum color := color & (MaxColor<<GreenShift | MaxColor<<RedShift) 'clear blue color := color + (StepSize<<GreenShift) 'increment green if (color & (ColorField<< GreenShift)) > (MaxColor<<GreenShift) 'test for green overflow color := color & (MaxColor<<BlueShift | MaxColor<<RedShift) 'clear green color := color + (StepSize<<RedShift) 'increment red if (color & (ColorField<< RedShift)) > (MaxColor<<RedShift) 'test complete color := 0 frame := color command := $40 'write display pst.hex(Color,8) pst.newline repeat until command == 0 waitcnt(clkfreq/10 + cnt) DAT PCog org 0 'This PASM drives up to 32 LEDs mov AdPar,Par 'get the address of input parameters rdlong Pins, AdPar 'get the pin number add AdPar, #4 rdlong Adframe, AdPar 'address of frame buffer add AdPar, #4 rdlong MyLC, AdPar 'MyLedCount add AdPar, #4 rdlong AdCommand, AdPar 'address of command long mov work1, Pins 'get the pin number and work1,#$FF 'Data IN pin number mov DataMask, #1 shl DataMask, work1 or dira, DataMask 'data pin starts out low or dira, syncmask '*********************wait here for something to do************************* top andn outa, syncmask 'not busy rdlong MyCommand, AdCommand wz 'wait for a command if_Z jmp #top 'just hand here or outa, syncmask 'busy ' test MyCommand, #$40 wz 'refresh display ' if_Z jmp #top 'command not recognized '*************get a copy of the frame buffer into cog memory and release boss cog test MyCommand, #$01 wz 'which frame buffer if_Z mov FBPointer, Adframe 'frame buffer0[0] if_NZ mov FBPointer, AdFrame1 'framebufferother[0] mov SLn1, GSLInst 'nice fresh copy of read instruction mov LedCnt, MyLC 'we are gonna move data for 32 LEDs SLn1 rdlong MyFrame, FBPointer 'modified instruction add SLn1, NextLong 'points to next long in MyFrame add FBPointer, #4 'next long in hub memory djnz LedCnt, #SLn1 'however many LEDs wrlong zero, AdCommand 'finished fetching frame buffer '******************now write the string from my frame buffer*********** mov Fetch, GSL2 'initialize the fetch instruction add Fetch, #1 'to get the second long mov LedCnt, MyLC 'Number of Leds GSL2 mov DLong, MyFrame 'get the first long to send shl DLong, #8 'align the first bit at bit 32 mov BitC, #24 'bit count for the first word OneB or outa, DataMask 'set it high. 'we come here every 100 machine cycles or 25 instructions shl DLong, #1 wc 'get this bit into carry latch and align next bit if_NC jmp #ZeroBit 'jump if sending zero call #CkEnd 'this is a one. 'fetch data for the nextLED if needful, decrement LED count if needful 'this takes exactly nine instruction times (36 cycles) including the call mov Delay, #4 'this is high time for a "one" djnz Delay, #$ 'burn an extra seven instructions andn outa, DataMask 'data pin goes low mov Delay, #1 'this is low time for a "one" djnz Delay, #$ test LedCnt, #$FF wz 'see if we just finished the string if_Z jmp #top jmp #OneB 'do the next bit (might be for next LED) ZeroBit mov Delay, #2 'this is high time for a "zero" djnz Delay, #$ andn outa, DataMask 'set it low call #CkEnd mov Delay, #3 'this is low time for a "zero" djnz Delay, #$ test LedCnt, #$FF wz if_Z jmp #top jmp #OneB 'ditto CkEnd sub BitC, #1 wz 'see if this is last bit for this LED if_nz jmp #CKDelay 'no, go spend some time sub LedCnt, #1 'reduce the LedCnt Fetch mov DLong, MyFrame 'fetch the next long (for the next LED) add Fetch, #1 'prepare for still another shl DLong, #8 'align first bit at bit 31 mov BitC, #24 'set up to do 24 bits CkEnd_ret ret CKDelay mov Delay, #2 djnz Delay, #$ 'burn an extra four instructions jmp #CkEnd_ret ' zero long 0 'constants GSLInst rdlong MyFrame, FBPointer 'Get Scan Line NextLong long $200 'next location in myframe as destination of readlong SyncMask long 1<<SyncPin 'scope sync AdPar res 'address into parameter list Pins res 'the pins Adframe res 'address of frame buffer AdFrame1 res 'other AdCommand res 'address of command byte DataMask res 'mask for LED pin MyCommand res 'my copy Work1 res 'generally useful BitC res '24 bits to each LED DLong res 'variable being shifted LedCnt res 'counts LEDs MyLC res 'number of leds to do FBPointer res 'points into frame buffer in hub memory Delay res 'used to count out delays MyFrame res 32 'my copy of the frame buffer FIT 200Make sure and let us know if you want some help. There are obviously lots of willing helpers around here.
Is there a way to poll the light string to see how many lights there are? I am assuming the controller is a broadcast only setup with no response? I suppose you could feed the last cell back to the Propeller for counting the LED's. Then if you send out a string for 20 leds and you get back 15 of them then you know there are 5 LEDS?
I am asking because I am seriously looking at making a 60" light bar for my truck doing different things but will use the modules to test out the software.
Rodney
You're correct in assuming you can't poll the LED directly. Your idea of monitoring the output of the final LED to see how many LEDs are in the strand should work.
Using JonnyMac's object it would go something like this. What this does is fill the stip slowly, showing the current LED count on the PST. It fills it with white to ensure you're testing the maximum current the strip can consume.
Keep an eye on your power consumption as the count increments to ensure there is enough power available. You can increase or decrease the delay to speed things up or slow them down.
PUB Test_All count := 0 repeat strip.fill(0, count, $7e_7e_7e) 'fills the strip with white one at a time DEBUG.dec(count) 'displays the last LED illuminated on PST DEBUG.str(string(" ")) 'make it easy to read on PST count := count + 1 'increments the count waitcnt(clkfreq * 1 + cnt) 'one second pauseAm I just measuring the current to make sure any voltage regulation I integrate is big enough to power the strip or am I missing something?
And I am assuming I would test this with a standard VOM amperage tester? (Mine has a DC 10amp limit tester in it that I am assuming I would put in series with the DC supply since I have never used it.)
Rodney
Example:
1 LED = 80ma
80% of Power Supply Max Rating = 1A
1A / 0.08A = 12.5 LEDs
So around 12 LEDs you'd want to start being aware of your power supply. If you buy a strips it is best to parallel them with heavy gauge +5 and ground. Looking back I noticed 60" light bar, I was thinking a lot more than that. There are strips of 72 WS821x LEDs on eBay pretty cheap. If you buy a strip it should say how many LEDs are on it. If you buy the individual LEDs I'm sure you'll know how many there are because you'll have to wire them all
I will likely be purchasing a 2 meter length light bar and cut it down (They sell by 1 meter increments but the light bars are made in 2 meter lengths and you can cut them down. ) I am not sure yet what density I want to use. I MAY play with the 144led/meter bars. The 96 LED bars are cheaper but I want as bright as I can get and try to make it not look so much like it is an LED bar.
Rodney
-Mike
Rodney
http://www.digikey.com/product-search/en?KeyWords=OKX-T%2F16-D12N-C&WT.z_header=search_go
There's also a surface mount version that wouldn't be hard to wire to
Question though.. Does that handle an automotive environment well? It showed max input of 14 volts and I know normally you can have spikes up to 30 in a vehicle. Would be a nice easy way to do my voltage regulation for any of my projects though when a simple regulator is not big enough.
Rodney
I've also worked with the MIC261203 which takes up to 28v puts out up to 12 Amps. There's an evaluation board for $41 at digikey. These are also good if you have old laptop supplies around (15~20v DC)
It does cost $70 for the unit but that also includes a protective cover for it. I may just go that route because of the simplicity.
This is the unit here:
http://store.mp3car.com/collections/our-products/products/dcdc-usb-200-intelligent-dc-dc-converter-with-usb-interface-for-programming
Rodney
That's funny I have almost the same supply you linked. It has been rock solid in the past two vehicles I used it in.