Menu

WS2812 LED Demonstration Code - really cool device!

Anobium
2016-08-17
2019-12-27
1 2 > >> (Page 1 of 2)
  • Anobium

    Anobium - 2016-08-17

    I have completed a demonstration of Great Cow BASIC supporting the WS2812 LED devices.

    This demonstration contains three operational demonstrations, and two methods of driving the WS2812 LEDs.
    The demos have a speed control using a pot, this pots adjusts the timing. A switch change the demos in operation.

    Demos are:
    1. Chaser - LED chaser
    2. Flash All LEDs
    3. Xylon Chaser, also known as Knight Rider

    Methods of driving the WS2812:
    1. CLC approach using the Microchip Configurable Logic Cells (CLC) to create a specialised SPI signal in terms of timing
    2. Bit Banging a SPI signal, again in terms of timing.

    Operation:
    By default the Chaser (#1) will be operational when applying power to the microcontroller and the WS2812 LEDs.
    Pressing the Switch will change the operational to the Flash All LEDs (#2), pressing the Switch again with return to Chaser operation.
    To select the Xylon Chase press the switch when applying power to the microcontroller and the WS2812 LEDs.

    Selecting the the specialised SPI signal method:
    Using the Microchip CLC method as detailed in AN1606.
    This method can be selected by defining the constants as follows.

            #define UseWS2812PWMSendData
            #define WS2812SendData WS2812PWMSendData
    

    Using the bit Banging method.
    This method can be selected by defining the constants as follows.

        #define UseWS2812BitBangSendData
        #define WS2812SendData WS2812BitBangSendData
    

    These methods are mutually exclusive - choose either CLC or Bit Banging, define the TWO constants. The constants ensure the code is configured correctly.

    Configuration:
    WS2812 DIN is connected to PORTC.7.
    Pot is connected to PORTA.4
    Switch is pulled high and connected to PORTA.5

    General commentary:
    The use of CLC is detailed in AN1606. Please review this document.

    The timing of the WS2812 is absolutely critical. Please review the WS2812 datasheet for the specific timing that are required.

    The Chaser demonstration simply writes to the WS2812 (for the number of LEDs) and indexes through the LEDS enabling the select color on each pass through the sequence.
    The Flash ALL LEDS simply writes to all the LEDS the same color.
    The Xylon Chaser uses an ARRAY to hold the pattern. When a bit in 1 then the LEDs with be turn on.

    This demonstration can be further developed - have fun.

     

    Last edit: Anobium 2016-08-17
    • Anobium

      Anobium - 2016-08-21

      Youtube video see here

       
  • viscomjim

    viscomjim - 2016-08-17

    Forgive my ignorance, but where can I find the code for this?

    P.S. This is awesome!!!

     
    • Anobium

      Anobium - 2016-08-17

      I was planning to include in the next release. If you want it now... Please send me a personal message.

       
  • Anobium

    Anobium - 2016-08-31

    Even better!!! More fun... I feel a wearable device for the Holidays on!

    https://youtu.be/7otfRlVJ1Nc

     

    Last edit: Anobium 2016-08-31
  • Anobium

    Anobium - 2016-09-02

    So, I took the demo code. Changed the Chip to an 18fand the output port - it worked.

    Then, I did tidy up, get the switch port correct, sorted the pot port and change the timer.

    Works are treat using Bit Banging - I have the 'Chaser and Flasher Working' - no point getting the Xylon Flasher working. :-)

    I have posted the code to the demo/LED folders and it will be included in the next build.

    P.S. I used the PicKit2 Low Pin Count demonstration board - the WS2812 LED ring just plugged in. :-)

     

    Last edit: Anobium 2016-09-02
  • Peter

    Peter - 2016-09-21

    I have got this working in bit banging mode with an LED strip off eBay:

    http://www.youtube.com/watch?v=7ader9oTBOc

    Initially I could not get the demo code (WS2812 LED using CLCorBitBanging) to work, however it was late at night and I managed to plug my PIC Kit 3 into 12V which fried the thing and I had to wait for a replacement.
    I found the WS2812 LED using BitBanging in the files repository on SF which is basically a cut down version of the other program and is what I was trying to achieve anyway. With a few alterations (I2C GLCD for debugging, changing ports/pins) it worked pretty easily - I was surprised!

    I couldn't get the potentiometer to work (is there a typo in the code - AN0 should be Potentiometer?) so I have a fixed speed in the code which suits me.

    As this particular device runs off 12V, I have a 7805 voltage regulator in the circuit to provide 5V to the PIC and 12V for the LEDs. The LED strip says that it needs 5V logic signals and I'm not sure how tolerant it is of undervoltage (e.g. 4x NiMH cells is 4.8V). Something else I was mindful of is the fact that the strip comes with a +12V/data/GND plug, but also 2 flying wires for +12V/GND and I had to tape them up to ensure they didn't touch and short.

    Current consumption is 250mA 300mA depending on which LEDs are lit. There are 30 LEDs on this particular strip. This is one of the cheap strips where 1 chip controls a block of 3 LEDs - there are some strips available where each LED can be controlled individually.

    My next plan is to use a 15m long strip with individually controlled LEDs for a project - 900 LEDs!!

     

    Last edit: Peter 2016-09-21
    • Anobium

      Anobium - 2016-09-21

      That is a cool strip!! Very good!!

      Surprised. LOL.

      Post your code. I will look at the pot issue.

      WELL DONE!!!!

       
    • Peter

      Peter - 2016-09-21

      Code attached.

      Lines 132, 137 and 142 referenced AN0 for the pot in the example code on SF.. I was trying to use AN7 on pin RC3 of a 16F1825 as I defined on line 47. I think the reason the pot didn't work for me is probably because I'd connected it up wrong.

      I also noticed that only 4 of the colours were being used. Line 64 should be CurrentLEDColorSequence = ( CurrentLEDColorSequence + 1 ) mod NoColours (noColours = 6 in my case) - it was hard coded as mod 4 in the example code.

      Everything else worked fine - great little bit of code.

       

      Last edit: Peter 2016-09-21
      • Anobium

        Anobium - 2016-09-22

        I think you just need to change the mydelay = readad10( AN0 ) to mydelay = readad10( AN7 ) - do not past the port.bit to the readad10 function.

        I like the other change!

        Nice change.

         
  • Peter

    Peter - 2016-09-23

    I was having a play with the code and changing the CPU frequency:

    • 32 MHz works (as used in the demo code)
    • 16 MHz or less doesn't work properly - only the first out of the 10 LED modules gets controlled although the GLCD works fine.
    • 4 MHz doesn't do anything (no GLCD or output on the LED strip)

    If I find the time I might try setting up an external oscillator to try 20 Mhz to see if that works.

    Is it worth including a note in the header of the demos to say a minimum frequency of 32MHz is required?

    Obviously I'm using bitbanging mode, CLC mode might work better at lower frequencies.

     

    Last edit: Peter 2016-09-23
    • Anobium

      Anobium - 2016-09-24

      You are correct. This code cannot work below 16 Mhz.

      Post a some nice words as a 'user warning' and I will add to the source code.

      Anobium

       
      • Peter

        Peter - 2016-10-01

        I think this should suffice:

        Requires a clock speed greater than 16 MHz to generate the required signal.

         
  • Peter

    Peter - 2016-10-01

    My big, long LED strip arrived yesterday so I've hooked it up and programmed a couple of new patterns for it.
    The strip contains 300 LEDs, but the GCB demo can only control 255 of them at the moment. My code for the patterns is attached.
    The 'bounce' pattern is running at full speed. Using fewer LEDs makes it run faster and presumably so will a PIC with a higher clock speed.

    This particular strip runs at 5V and my multimeter was recording 1.5A with the whole strip illumitated in a secondary colour (e.g. magenta). I didn't measure it with the whole strip lit white.
    The voltage drop along the strip was noticeable: if all the LEDs are set to white, they fade to orange then to red by the other end as the voltage along the line decreases.
    The strip can be powered from any point on the strip (but only connect the data at one end). If less power is being used, the drop is not noticeable.

    My circult also had a 470uF capacitor across the power supply to help attenuate the initial surge when powering up, and also a 330 ohm resistor between the PIC and the data connection on the strip to prevent any surge/spike damaging the first LED (see here - https://learn.adafruit.com/adafruit-neopixel-uberguide/power ). In the video the whole thing was running from 3xAA NiMH batteries however due to the current a power supply is probably a better idea.

     

    Last edit: Peter 2016-10-01
  • Peter

    Peter - 2016-10-13

    Here's another demo with the LED strip, this time using a potentiometer to control how many LEDs get lit.
    As the number of lit LEDs increases, the colour changes to red because of the voltage drop due to the current being drawn by all the LEDs.
    I'm wondering how easy it would be to connect up an audio input to the ADC instead of a potentiometer and create a huge VU meter....

     
  • viscomjim

    viscomjim - 2016-10-14

    Hey Peter, I hooked up a MSGEQ7 to an ADC of a pic16F1825 to use for another application. It works SUPER well. I have looked up ways to play with audio without that component, but at the end of the day for a couple of bucks more, the amount of fun to be had with 7 different frequency values provided by this chip was well worth it. I would love to see a combination of the WS2812 code along with the MSGEQ7.

     
  • Peter

    Peter - 2016-10-15

    Looks like an interesting device. It sounds relatively easy to program however I'm not sure how easy it would be to drive 7 strips with 255 LEDs each.it could be quite sluggish!

     
  • viscomjim

    viscomjim - 2016-10-16

    I agree that would be sluggish. The way we used it was to drive 24 "channels" divided as 8 channels of Red, Green and Blue channels. Here is the code we used to read the MSGEQ7. Once the values were in the array, you can do whatever you want with them.

    Lots of good explanation here... http://www.eetimes.com/author.asp?doc_id=1323030

    #define Eq7AD portC.3           'Pin 7 C.3, AN7 - EQ7 output
    #define Eq7Stb portA.0          'Pin 13 A.0 - EQ7 Strobe
    #define Eq7Rst portA.1          'Pin 12 A.1 - EQ7 Reset
    
    dir Eq7AD in
    dir Eq7Rst out
    dir Eq7Stb out
    
    set Eq7Rst off
    set Eq7Stb on
    
    dim EqValue(7)
    
    do
    'call read MSGEQ7 sub
    RdMSGEQ7
    'do stuff with array values
    loop
    
    sub RdMSGEQ7
    IntOff
    set Eq7Rst on
    wait 1 us
    set Eq7Rst off
    wait 75 us
    
    for Eq = 1 to 7
    set Eq7Stb off
    wait 40 us
    EqValue(Eq) = ReadAD(AN7)
    if EqValue(Eq) < 30 then EqValue(Eq) = 0 'filter noise
    set Eq7Stb on
    wait 40 us
    next Eq
    IntOn
    end sub
    

    With the WS2812 and this you can make a VU meter with a few leds in the strip. Here is just one example (arduino unfortunately) but you can get the gist of it. Just use one strip instead of 7.

    https://plus.google.com/wm/1/116700996827719272404/posts/2fk6SiuUKig

     

    Last edit: viscomjim 2016-10-16
  • Peter

    Peter - 2016-11-09

    I wrote a big long post explaining this but sourceforge lost it so I'll edit tomorrow. Edit below

    I've sped up the WS2812 LED strip using a PIC running at 64MHz (video at end of the post). It required some alteration to the demo code, but it worked in the end.

    I did some experimenting to see how fast I could make it run using bit banging.
    The first thing I tried was commenting out all the code associated with Timer0 and the associated interrupts for controlling the data rate, and introducing a fixed delay at the end of each chain of data. I made the delay as short as I could without corrupting the data, but it didn't really speed things up at all.

    I then cranked up the chip frequency to 64 MHz and it didn't do anything. This was because the data pulses were too short for the WS2812 chips to detect so I changed the demo code as follows to double the length of each pulse and it worked:

    Sub WS2812BitBangSendData ( in ColortoSend as long )
    
                  repeat 24
                    IF ColortoSend.23 ON THEN
                      'High for to 1 bit
                      SET DIN ON
                      SET DIN ON    ''
                    else
                      'High and Low as fast as practical
                      SET DIN ON
                      SET DIN ON    ''
                      SET DIN OFF
                      SET DIN OFF   ''
                    END IF
                    ROTATE ColortoSend left
                    'Low for the 1 bit
                    SET DIN OFF
                    SET DIN OFF    ''
                  end repeat
    
    End Sub
    

    This seemed to be the best way to increase the pulse length, because I think using timers and interrupts would slow the code down.
    I think the bulk of the speed increase is in the code that generates the pattern on the LED strip: the loops and the if statements so doubling the clock speed will speed this up.

    The big LED strip that I bought was this one. It is the White PCB, 5m long and 60 LEDs/m and runs on 5V. You can get them on eBay and other websites.
    https://www.aliexpress.com/item/DC5V-1m-4m-5m-ws2812b-Smart-led-pixel-strip-Black-White-PCB-30-60-144-leds/32337440906.html
    There are other variations available. If you're buying one make sure each LED is addressable and check the voltage because 5V is much more convenient if you are sourcing power from a USB socket. The strip used in my first post only allows blocks of 3 LEDs to be controlled and runs off 12V, with a 5V data signal which is a bit of a pain.

    The IP67 version I have comes in a silicone sleeve which is full of mastic at each end. You can cut the strip at predetermined points to make it shorter, and you can also solder on additional power connections to reduce the voltage drop from end to end.
    The strip seems to tolerate 6v (the supply voltage is stated as 5v) which gives some compensation for the voltage drop when all the LEDs are on. The DIP packaged PICs seem OK at 6v too.

     

    Last edit: Peter 2016-11-12
    • Anobium

      Anobium - 2016-11-10

      Very very good!

      That looks very cool. Can you post the link to the LEDs? etc.

      WOW!

       
  • Peter

    Peter - 2016-11-13

    Additional mode for the LEDs (recreated one that was in the demo I think), and inside a tube now to give a nice effect.

     

    Last edit: Peter 2016-11-13
  • Anobium

    Anobium - 2016-11-13

    Ok that's   very good. It's disco time!!!!

     
  • Anobium

    Anobium - 2016-11-13

    Ok that's   very good. It's disco time!!!!

     
  • Peter

    Peter - 2017-11-26

    The WS2812 LED demo code also works perfectly with PL9823 LEDs.

     
    • Anobium

      Anobium - 2017-11-27

      Post you code... We want to put up on the website. Please. Please.

       
1 2 > >> (Page 1 of 2)

Log in to post a comment.