RGB Led Strip

I first heard about these RGB LED strips from a post on instructables.

They consist of a flexible strip with RGB LEDs and controller chips attached. The controllers work like shift registers and you clock data in at one end and it cascades down the strip, then you can flag a latch and the LEDs display the colors accordingly.

]

By using various techniques all sorts of amazing patterns and chaser effects can be displayed. You can't actually display RGB values as such but each RGB LED can be set to be ON, OFF, Fade up, or fade down in any combination of RGB.

I've written a neat library to use them (example usage included)
http://bliptronics.com/projects/rgbstrip.zip

I have the strips for sale here:
http://bliptronics.com/item.aspx?ItemID=83

Enjoy!
Ben

I ran this last night and it works great.

Thanks again blip! You are able to make all the new chips run, sweet stuff.

Received my 0.5-meter, 20-LED strip on Saturday. Good hues from the
LEDs and quite bright! I'll be writing a few more "needed" methods for
the RGBStrip class in the next day or two. :wink:

I will say that a 24-LED strip would have worked out better for me as
more numbers will divide evenly into 24 rather than 20. Oh well.... :slight_smile:

@Rusty. Any luck making advanced functions for the strip?

Here is some updated code .. using the op example.
This version works by just updating the LEDCount, there are extended (more colors) and a slower rainbow added. Also include two functions, "allTo" and "blinkAll".

  • The two rainbow additions were done in a way that is more for explanation than good implementation practice.
// Example code for the RGBStrip library used to drive a strip of LEDs using the HL1606 Controller.
// Written by Ben Moyes, Bliptronics.com
// June 28 2010
// ben@bliptronics.com

#include <RGBStrip.h>
#define LEDCount 20    //Set how many LEDs we'll be driving.

//-- NEW - Added this to show the loop count for the LED rainbow effect is not related to the led count
#define RAINBOW_RUN_COUNT 25  //Set how many times the rainbow action will run
//-- END NEW

//We'll use this to store commands before sending to the LEDs.
unsigned char Disp[LEDCount];

//Some constants we will used to create a rainbow pattern.
//A LED following this sequence will phase through a rainbow of colors.
//The S pins needs to be pulsed 128 times to allow each transition to occur before changing to the next step
//in the sequence. 
unsigned char rainbow[4] = {
Commandx2 | RedOn   | GreenUp | BlueOff,
Commandx2 | RedDown | GreenOn | BlueUp,
Commandx2 | RedOff  |GreenDown | BlueOn,
Commandx2 | RedUp | GreenOff | BlueDown
};

//-- NEW - Added this to create a longer rainbow .. color details below
unsigned char longRainbow[6] = {
Commandx2 | RedOn   | GreenUp | BlueOff,   // red to yellow
Commandx2 | RedDown | GreenOn | BlueOff,   // yellow to green
Commandx2 | RedOff | GreenOn | BlueUp,     // green to cyan
Commandx2 | RedOff | GreenDown | BlueOn,   // cyan to blue
Commandx2 | RedUp  |GreenOff | BlueOn,     // blue to majenta
Commandx2 | RedOn | GreenOff | BlueDown    // majenta to red
};
//-- END NEW

//-- NEW - Added this to create a longer rainbow that runs slower (Updated to Command from Commandx2)
unsigned char longSlowRainbow[6] = {
Command | RedOn   | GreenUp | BlueOff,   // red to yellow
Command | RedDown | GreenOn | BlueOff,   // yellow to green
Command | RedOff | GreenOn | BlueUp,     // green to cyan
Command | RedOff | GreenDown | BlueOn,   // cyan to blue
Command | RedUp  |GreenOff | BlueOn,     // blue to majenta
Command | RedOn | GreenOff | BlueDown    // majenta to red
};
//-- END NEW

RGBStrip strip(2, 3, 4, 5, LEDCount,   Disp);  //Create instance of RGBStrip library, tell it which pins are connected to the strip 
             //S, D, C, L  #Leds Buff          //how many LEDs, and a pointer to an array where we can store LED commands.

void allTo(int cmd){
     for(byte a=0;a < LEDCount; a++)
    {
      Disp[a%LEDCount] = Command | cmd;
    }
    strip.displaySend();
}

void blinkAll(int cmd, int times, int blinkRate){
  for( int i = 0 ; i < times ; i++ ){
    allTo(cmd);
    delay(blinkRate/2);
    allTo(0);
    delay(blinkRate/2);
  }
}

void setup()
{
  //This will fill our array with the command for all LEDs off.
  strip.displaySetSection(0,LEDCount-1,Command);
  strip.displaySend();  //Send out the values to the LEDs and latch in the values.
}

void loop()
{
/*
  blinkAll(RedOn,5,1000);
  blinkAll(BlueOn,7,1000);
  blinkAll(BlueOn | RedOn ,3,1000);
*/  
  unsigned int a,b,c;
  
  //Send out an empty command to all the LEDs to turn them off.
  for(a=0;a<LEDCount;a++)
    strip.sendByte(Command);
  strip.latch();
  
  //Send some colors.
  for(a=0;a< 1+ LEDCount/7;a++)
  {
    strip.sendByte(Command | RedOn);  
    strip.sendByte(Command | BlueOn);
    strip.sendByte(Command | GreenOn);
    strip.sendByte(Command | RedOn | BlueOn);
    strip.sendByte(Command | RedOn | GreenOn);
    strip.sendByte(Command | BlueOn | GreenOn);
    strip.sendByte(Command | BlueOn | GreenOn);
  }
  strip.latch();  
  delay(2000);
    
  // **** Do a rainbow.****
  // This is a little mind-bending, I'll try to explain:
  // Led 0 performs a color transition/fade, but when it is only 1/4 done, we push in a zero
  // which doesnt get loaded into led 0, but then gets loaded into led 1
  // the trasition continues and we repeat the sequece of pushing a zero and continuing to do the transition two more time.
  // When LED0 is finished the transition, we then load it with another transition and repeat the whole sequece above.
  for(a=0;a < RAINBOW_RUN_COUNT; a++)
  {
    strip.sendByte(rainbow[a%4]);  //modulo will give us values of 0 to 3 as we step through loop..look it up!
    strip.latch();
    strip.runfader(16,2);  //Fade to 25% (there is 64 fade steps in a 2x command, 128 in a normal command
    strip.sendByte(0);     //Zero never gets loaded into a LED
    strip.latch();         //Load the LEDs.
    strip.runfader(16,2);  //fade to 50% done
    strip.sendByte(0);
    strip.latch();
    strip.runfader(16,2);   //fade to 75%
    strip.sendByte(0);
    strip.latch();
    strip.runfader(16,2);   //fade to 100%
  }

//-- NEW
  blinkAll(RedOn,1,500);

  // **** Do a long rainbow.****
  for(a=0;a < RAINBOW_RUN_COUNT; a++)
  {
    strip.sendByte(longRainbow[a%6]);  //modulo will give us values of 0 to 5 as we step through loop..look it up!
    strip.latch();
    strip.runfader(16,2);  //Fade to 25% (there is 64 fade steps in a 2x command, 128 in a normal command
    strip.sendByte(0);     //Zero never gets loaded into a LED
    strip.latch();         //Load the LEDs.
    strip.runfader(16,2);  //fade to 50% done
    strip.sendByte(0);
    strip.latch();
    strip.runfader(16,2);   //fade to 75%
    strip.sendByte(0);
    strip.latch();
    strip.runfader(16,2);   //fade to 100%
  }

  blinkAll(BlueOn,2,500);


  // **** Do a long slow rainbow.****
  // -- updated from 16 to 32 below to run twice as many steps in the fader
  for(a=0;a < RAINBOW_RUN_COUNT; a++)
  {
    strip.sendByte(longSlowRainbow[a%6]);  //modulo will give us values of 0 to 5 as we step through loop..look it up!
    strip.latch();
    strip.runfader(32,2);  //Fade to 25% (there is 64 fade steps in a 2x command, 128 in a normal command
    strip.sendByte(0);     //Zero never gets loaded into a LED
    strip.latch();         //Load the LEDs.
    strip.runfader(32,2);  //fade to 50% done
    strip.sendByte(0);
    strip.latch();
    strip.runfader(32,2);   //fade to 75%
    strip.sendByte(0);
    strip.latch();
    strip.runfader(32,2);   //fade to 100%
  }

  //Set some groups of LEDs.
  //They are set in memory first, then values for all leds are sent out with displaySend()
  
  //Set LEDs 0 to 19 to fade up to blue at double speed
  strip.displaySetSection(0,LEDCount-1,Command | BlueUp);
  strip.displaySend();    //Send out to LEDs
  strip.runfader(128,5);  //Pulse the fade line 128 times with a 2mS delay each time.
  
  // Fade DOWN from blue.
  strip.displaySetSection(0,LEDCount-1,Command|BlueDown);
  strip.displaySend();
  strip.runfader(128,5);
  
  //Fade up to RED
  strip.displaySetSection(0,LEDCount-1,Command|RedUp);
  strip.displaySend();
  strip.runfader(128,5);
  
  //Fade down from RED.
  strip.displaySetSection(0,LEDCount-1,Command|RedDown);
  strip.displaySend();
  strip.runfader(128,5);

  strip.displaySetSection(0,LEDCount-1,Command);
  strip.displaySend();

  //Bounce a blue LED up and down.
  for(b=0;b<5;b++)
  {
    for(a=0;a < LEDCount; a++)
    {
      Disp[a%LEDCount] = Command | BlueOn;
      strip.displaySend();
      delay(50+ a*a/5);
      Disp[a%LEDCount] = Command |BlueOff;
      
    }
    for(a=LEDCount-1;a > 0; a--)
    {
      Disp[a%LEDCount] =  Command | BlueOn;
      strip.displaySend();
      delay(50+ a*a/5);
      Disp[a%LEDCount] = Command | BlueOff;
      
    }
  }  
}

Note: I am not working with the strip much, opting for the pwm versions. With this strip, I was able to get a fading and specific colors without using the fade function (software PWM) .. but only in the loop.

Interested to see what you come up with.

Well, I didn't promise anything "advanced". :slight_smile: The last few days I've
been diverted by some WiShield ideas. Still, I played with my RGBStrip
to add a little more functionality. At first I had several rotation methods
but, in the end, I realized how much my rotation routines could be
simplified into just one additional method of the RGBStrip class.

void RGBStrip::displaySetRotate(unsigned int startled, unsigned int endled,
                        unsigned int times, unsigned int direction)
{
    unsigned int b, c;

    if (startled < endled) {
      for ( ; times>0; times--) {
          if (direction == INWARD) {
            c = Display[startled];
            for (b=startled+1; b<=endled; b++)            // Use memcpy() ?
                Display[b-1] = Display[b];
            Display[endled] = c;
          }
          else if (direction == OUTWARD) {
            c = Display[endled];
            for (b=endled; b>startled; b--)      // Use memcpy() ?
                Display[b] = Display[b-1];
            Display[startled] = c;
          }
      }
    }
}

And this is the addition to RGBStrip.h:

//    INWARD means towards LED zero
//    OUTWARD means toward LED _LEDCount
#define OUTWARD             1
#define INWARD            -1

and

    void displaySetRotate(unsigned int startled, unsigned int endled,
                    unsigned int times=1, unsigned int direction=OUTWARD);

and here's a short sample:

    strip.displaySetSection(0,LEDCount-1,Command);
    Disp[0] = Command | RedOn;
    Disp[LEDCount-1] = Command | BlueOn;
    strip.displaySend();
    delay(200);
    for (a=0; a<100; a++) {
        strip.displaySetRotate(0, LEDCount/2-1, 1, OUTWARD);
        strip.displaySetRotate(LEDCount/2, LEDCount-1, 1, INWARD);
        strip.displaySend();
        delay(100);
    }

which causes a red and blue dot to appear at opposite ends of the
RGBStrip and move towqrds the middle. When getting to the middle
they are moved back to ends.

Your thoughts and idears are welcome!

Thanks for the code. I really need exact colors and complete control, so I gave the strip to a friend to play with while I do other stuff, so I can not test / play with the code at this time.

Just curious ...
Have you tried any other other LEDs on the site? They just added naked versions of the pixels (no plastic case and not wired) for 1.49 each. My thinking has been, strip runs almost a buck per LED and you have limited functionality and are stuck with the 2 LEDs at a fixed distance. While the strip do have good uses, you may find having the PWM controllable chips makes all the difference in the world, it has for me.

I have played with almost every LED on this site and most of the LEDs (except the strip) are using an IC that allows for 32 levels per color. I have been able to daisy chain the 8mm and 22mm versions together as they use the same chip, just the RGB order is different. I was even able to include the (12v) 50mm dome in the same daisy chain (minus power naturally) .. controlling them all with 2 wires.

If you have yet to try the other LEDs (outside the strip), you may want to give them a whirl.

Have fun!

@marklar -- Can't say that I've tried Bliptronics' other LEDs as this RGB
strip was my first order. I may try more as time and money make
themselves available. For now, the RGBstrip can be coaxed into doing
what I want for now and the price/LED is hard to beat. If only we could
get the ShiftBrights on a flexible strip...