Shop OBEX P1 Docs P2 Docs Learn Events
Question about programming the WS2811 RGB LED. — Parallax Forums

Question about programming the WS2811 RGB LED.

NWCCTVNWCCTV Posts: 3,629
edited 2015-01-13 21:58 in Propeller 1
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

  • Duane DegnDuane Degn Posts: 10,588
    edited 2014-12-31 20:31
    NWCCTV wrote: »
    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!!!!

    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?
  • xanaduxanadu Posts: 3,347
    edited 2015-01-01 08:24
    Also JonnyMac's object. The demo has a color wheel and a few different ways of showing it

    http://obex.parallax.com/object/703
  • tomcrawfordtomcrawford Posts: 1,126
    edited 2015-01-01 08:50
    And here's another:
  • MJBMJB Posts: 1,235
    edited 2015-01-01 09:56
    I don't know the exact difference between the WS2811 and the WS2812.
    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.
  • tomcrawfordtomcrawford Posts: 1,126
    edited 2015-01-01 10:27
    Attached is a list of color definitions from

    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.
  • JonnyMacJonnyMac Posts: 9,105
    edited 2015-01-01 11:39
    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.
  • tomcrawfordtomcrawford Posts: 1,126
    edited 2015-01-01 14:40
    JonnyMac's comment got me thinking: How many colors can one distinguish on one of these WS281x devices? Here is a program to help one decide:

    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 200 
    
    
  • NWCCTVNWCCTV Posts: 3,629
    edited 2015-01-01 19:29
    Thanks for all the great advice. And Duane, I thought I was wrong about the amount and figured someone would chime in with the exact color count!!! I will work on this and find the best way to demonstrate it to my grandson when he comes back in two weeks. Thanks everyone.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2015-01-01 19:49
    NWCCTV wrote: »
    I will work on this and find the best way to demonstrate it to my grandson when he comes back in two weeks. Thanks everyone.

    Make sure and let us know if you want some help. There are obviously lots of willing helpers around here.
  • NWCCTVNWCCTV Posts: 3,629
    edited 2015-01-02 18:54
    I will do that Duane. Thanks again.
  • xanaduxanadu Posts: 3,347
    edited 2015-01-02 20:18
    The number 256 is somewhat synonymous with 16.8 million colors because you have 256 shades of Red Green and Blue :)
  • redheadedrodredheadedrod Posts: 78
    edited 2015-01-03 10:53
    Cool, I just got confirmation that I was sent the last 5 "broken" prototype boards and I had them add 5 of the WS2812 modules to the order so I am looking forward to playing around with this stuff shortly.

    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
  • Duane DegnDuane Degn Posts: 10,588
    edited 2015-01-03 11:11
    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?

    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.
  • xanaduxanadu Posts: 3,347
    edited 2015-01-03 13:28
    If you're working with a large strip you can take care of two issues at once, power supply current and counting LEDs.

    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 pause
    
  • redheadedrodredheadedrod Posts: 78
    edited 2015-01-09 17:46
    I am curious about this measuring the current...

    Am 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
  • xanaduxanadu Posts: 3,347
    edited 2015-01-09 19:19
    You could measure the current of one LED on full brightness using a multimeter or bench top power supply. Then take 80% of your intended power supply max amps output and divide by the max current of one LED. I supposed there is a datatsheet somewhere that lists the LED's max current.

    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 :)
  • redheadedrodredheadedrod Posts: 78
    edited 2015-01-10 22:50
    I bought 5 of the Parallax RGB "boards" to play with but yes... I guess it will actually be a 48" light bar but still the same idea.. I will have to figure out a power supply to power +5 volts to the light bar and the prop board. I will be using Automotive 12 volts to power it with. I may just go with overkill and get a $70 power supply for easy of use. It will have more than enough power to power everything since it is an automotive DC-DC supply and can handle what appears to be 120 watts. (10 amp at 12 volts) It is designed to run a PC with but can run just about anything from it.

    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
  • pmrobertpmrobert Posts: 673
    edited 2015-01-11 07:39
    Rpodney, if you're going to use your VOM to confirm current draw, be aware that some VOMs have duty cycle rules when measuring current more than the mA range. For example, no more than 2 minutes of current flow followed by a minimum 15 minute rest.

    -Mike
  • redheadedrodredheadedrod Posts: 78
    edited 2015-01-11 21:47
    pmrobert wrote: »
    Rpodney, if you're going to use your VOM to confirm current draw, be aware that some VOMs have duty cycle rules when measuring current more than the mA range. For example, no more than 2 minutes of current flow followed by a minimum 15 minute rest.

    -Mike
    Ok thanks, was not aware of this. With this being a cheap $10 VOM I am sure that is likely the case..

    Rodney
  • TubularTubular Posts: 4,702
    edited 2015-01-12 01:17
    I've been using these 16A converters, and have been really happy with them
    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
  • redheadedrodredheadedrod Posts: 78
    edited 2015-01-12 16:39
    Thanks Tubular That will certainly do the job for me..

    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
  • TubularTubular Posts: 4,702
    edited 2015-01-12 17:49
    Don't know, Rodney. It talks about an abs max of 15v and an external 22uF input capacitor. You could try a supressor like used with car radios, but you end up spending extra money when you might be better with an alternative.

    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)
  • xanaduxanadu Posts: 3,347
    edited 2015-01-12 19:26
    I would look for something with low voltage cut off, and a remote on/off that can be triggered via accessory or toggle switch inside the cabin.
  • redheadedrodredheadedrod Posts: 78
    edited 2015-01-12 22:03
    The original option I was looking at is intended to run a PC that is using a single input voltage. It can control the PC via the motherboard power switch and does allow turning on and off based on an external input. It is self contained and puts out roughly 125 watts at one voltage. That voltage is configurable. They are used a lot when someone makes a car pc with a laptop motherboard that needs a single voltage DC into it.

    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
  • xanaduxanadu Posts: 3,347
    edited 2015-01-13 21:58
    I was going to recommend a mini-ITX PC based supply because you get 12v, 5v and 3.3v. The stuff is expensive though.

    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.
Sign In or Register to comment.