LPD8806 RGB LED Strip - Reverse Engineer (with pics) questions/feedback

citlee:

Cranium:
For those interested in the strips I found to be cheaper, it is here:
http://www.alibaba.com/product-gs/505148128/LPD8806_digital_RGB_colorful_led_strip.html

The description states 12v but after inquiring about this, I found out these are actually a 5v model. The group several types together with different ICs (specifically 6803, 8806, & 2801).

The quote I was provided for 10 meters shipped was $145. I did not buy from them because they wanted a wire transfer or western union. I did not trust this.

If anyone does decide to go this route, please post pictures and user experience. :slight_smile:

Funnily enough, this is the exact same thing that I found a few days ago and have ordered from this supplier, before seeing this thread (I am currently trying to work out how a different strip works in another thread, without much joy). I've already paid them via Western Union, total of $75 for 5 metres and DHL shipping. They claim to be having trouble with my address - which is entirely plausible given my location, but we shall see. I am expecting to hear back from them next week, should have the strip within two weeks. The 8 hour time difference is a bit of a problem when it comes to resolving issues.

Cranium and Citlee, I am in the same boat- I want to buy some from Alibaba but I'm not sure about it. I'd love to hear your experience in particular, Citlee, because if yours come OK I would buy some from that seller! Can you provide a link to the seller/item you paid for? Much appreciated, please keep us posted!

theavianbrain:
Cranium and Citlee, I am in the same boat- I want to buy some from Alibaba but I'm not sure about it. I'd love to hear your experience in particular, Citlee, because if yours come OK I would buy some from that seller! Can you provide a link to the seller/item you paid for? Much appreciated, please keep us posted!

I'm afraid I can't provide a link to the exact item, but the supplier is "clenled", http://clenled.en.alibaba.com and http://www.clenled.com/en/ - the sales manager is "Andy", who is very helpful (his native language is definitely not English but bear with him). My item arrived today after a mishap with the courier being unable to find my address (not clenled's fault!).

I can't provide a link because frankly I don't know which product I have - I was chatting to Andy, initially asking about another product, and then I remembered seeing somewhere that an LPD8806 driven strip is what I really wanted, so I asked him if he had any and this is what I ended up with. I don't think it's the product in the url posted previously because it doesn't quite match up - the sections are 6 LEDs a piece, and the red wire is connected to "DA", for example. Let me show you what I mean, through interpretive dance!

Actually, maybe some photos would be better.

Here's the chip:

A section:

The join between the two sections:

I am waiting for the spec sheet from Andy, when it arrives, I'll post it here.

The text on the label on the anti-static bag it came in is as follows:
Part no: CL-FW5050RGB18-8806
IP67 waterproof color: RGB
Voltage: DV12V, 8.6W/M
Qty: 36 LED/M, 5M/roll

I am a complete and utter newb when it comes to this stuff (Arduino, controlling LEDs, using electronics on this level) so any advice appreciated. To be honest I'm not sure what to do next to actually get some light out of it - should I just go ahead with the Adafruit LPD8806 tutorial, or does that carry a risk of blowing stuff up? I do have a 12v 5a power supply that I ordered and have tested with a different (dumber) strip, which I am planning to use to power this.

Thanks for the post and pictures of the strip. Very informative. It is interesting that they are using 12V rather than 5V that the 8806 needs. Looking at the resistors and layout, it appears that this strip will have limitations.

You can use the arduino for the CLK and DA pins and then use your 12V power source to power it. The LPD8806 library should work with this strip.

I think with this configuration, you will only be able to control colors every 3rd LED rather than every LED as with the strips on Adafruit. The LEDs on each side of the 8806 appear to be in series with an additional resistor for each to drop voltage further. The max power dissipation of the 8806 is 600mW so with 6 RGB LEDs, it would be able to supply a maximum of only 6.7mA to each leg of each LED. This coincides with the 180 ohm resistors for the green and blue legs in the pics. These resistors would limit current to around 6mA for each color. This would mean it would not be as bright as the strip on Adafruit that can supply the full rated 20mA to each leg of each LED.

But this is all based on looking at the photos and my limited knowledge of these things. You won't really know until you hook it up and find out. :slight_smile: Please post a follow up on this.

Unfortunately, of the dozens of electronic components (ignoring the mystery bag of semi-random ICs) that are neatly organised, my collection doesn't include a DC power socket, so short of butchering the power supply I have no way to power the strip! I have ordered some from rapidonline.com and they should be here next week.

Cranium:
I think with this configuration, you will only be able to control colors every 3rd LED rather than every LED as with the strips on Adafruit. The LEDs on each side of the 8806 appear to be in series with an additional resistor for each to drop voltage further. The max power dissipation of the 8806 is 600mW so with 6 RGB LEDs, it would be able to supply a maximum of only 6.7mA to each leg of each LED. This coincides with the 180 ohm resistors for the green and blue legs in the pics. These resistors would limit current to around 6mA for each color. This would mean it would not be as bright as the strip on Adafruit that can supply the full rated 20mA to each leg of each LED.

But this is all based on looking at the photos and my limited knowledge of these things. You won't really know until you hook it up and find out. :slight_smile: Please post a follow up on this.

More knowledge than me, that's for sure!

The power sockets have arrived, and after killing one (I don't think I could solder to save my life) it's alive. I followed the ladyada.net tutorial for the LPD8806 and it works, with a minor adjustment.

As you surmised, the LEDs are unfortunately controlled in batches of three rather than individually. :frowning:

With this strip there are 10 segments. Each segment has 18 LEDs, but as they're controlled in groups of 3, that means there are essentially 6 pixels/segment. So you need to:

LPD8806 strip = LPD8806(60, dataPin, clockPin)

to control the entire length of the strip in the way that you would expect.

So not exactly what I was after (I still don't have the spec sheet), but it's 1/3rd the cost of the adafruit strip, is good enough for what I want, and gives me a relatively easy way to control the colours using the LPD8806 library.

I hope this is of some use to someone!

Very useful. Now let's get some video of the strip. :slight_smile:

I did a wheelchair project with the 2m I had and put together some basic sequences...17 in all. If you'd like any of the animations in the video, let me know....

Sure, post 'em here for everyone to see! Although I don't think they're going to look as good as in your video, as they'll essentially be stretched out three times...

#include "LPD8806.h"
#include "SPI.h"

#define button 8
#define stripSize 64
int butPush = 0;
int currentMode = 17;
int numModes = 17;

// on Arduino 168/328 thats data = 11, and clock = pin 13
LPD8806 strip = LPD8806(stripSize);

void setup() {
  // Start up the LED strip
  strip.begin();

  // Update the strip, to start they are all 'off'
  strip.show();
//  Serial.begin(9600);
  pinMode(button,INPUT);
}
int micLevel;
int colorLevel;
int numLeds;

void loop() {
  if (butPush){
    if (currentMode++==numModes) currentMode = 3;
    butPush=0;
    while (digitalRead(button)==1){
      //don't do anything else until the button is released
    }
    for (int i=0; i < strip.numPixels(); i++) {
      strip.setPixelColor(i, 0);  // turn all pixels off
    } 
    strip.show();
    delay(250);
  }
  modeSelect();
}

void modeSelect(){
  switch (currentMode){
    case 1:
      music(0);  //sound sensitive mode with variable LEDs lit
      break;
    case 2:
      music(1);  //sound sensitive mode with ALL LEDs lit
      break;
    case 3:
      colorChase(strip.Color(127,0,0), 20);  	// full brightness red
      colorChase(strip.Color(127,127,0), 20);	// orange
      colorChase(strip.Color(0,127,0), 20);		// green
      colorChase(strip.Color(0,127,127), 20);	// teal
      colorChase(strip.Color(0,0,127), 20);		// blue
      colorChase(strip.Color(127,0,127), 20);	// violet
      break;
    case 4:
      // fill the entire strip with...
      colorWipe(strip.Color(127,0,0), 40);		// red
      colorWipe(strip.Color(0, 127,0), 40);		// green
      colorWipe(strip.Color(0,0,127), 40);		// blue
      break;
    case 5:
      rainbow(25);
      break;
    case 6:
      rainbowCycle(0);  // make it go through the cycle fairly fast
      break;
    case 7:
      caution(600);  //flash red and blue
      break;
    case 8:
      police(115);  //flash yellow
      break;
    case 9:
      circlinglights(20);  //flash yellow
      break;
    case 10:
      allon();  //all white
      break;
    case 11:
      ran(20);  //random lights
      break;
    case 12:
      ran1(15);  //random lights
      break;
    case 13:
      shiftwhite(100);
      break;
    case 14:
      kit(1);
      break;
    case 15:
      rand2(50);
      break;
    case 16:
      allon1(50); // white flicker
      break;
    case 17:
      xmas(300);
      break;
  }
}
void xmas(int dly){
  int color=0;
  while (butPush==0){
    for (int i=0; i<stripSize; i++){
      if (digitalRead(button)==1) {butPush=1; i=stripSize;}
      if (color==4){
        strip.setPixelColor(i,127,127,127); //white
      }
      else if (color==3){
        strip.setPixelColor(i,127,90,0); //yellow
      }
      else if (color==2){
        strip.setPixelColor(i,0,0,127); //blue
      }
      else if (color==1){
        strip.setPixelColor(i,0,127,0); //green
      }
      else {
        strip.setPixelColor(i,127,0,0); //red
      }
      if (color++==4) color=0;
    }
    if (butPush==0){
      strip.show();
      delay(dly);
    }
  }
}
void allon1(int dly){
  while (digitalRead(button)==0){
    int red = random()%128;
    int green = random()%128;
    int blue = random()%128;
    for (int i = 0; i < stripSize; i++){
     strip.setPixelColor(i, red, green, blue);
   } 
   strip.show();
   delay(dly);
    for (int i = 0; i < stripSize; i++){
     strip.setPixelColor(i, 0,0,0);
   } 
   strip.show();
   delay(dly);
  }
  butPush = 1;
}
void rand2(int dly){
  //turn on lights one at a time with the same random color
  //ensure that a light is turned on each cycle
  //then turn off the lights 2 at a time
  int lights[stripSize];
  for (int i=0; i<stripSize; i++) lights[i]=0;
  while (digitalRead(button)==0){
    int red = random()%128;
    int green = random()%128;
    int blue = random()%128;
    for (int i = 0; i < stripSize; i++){
      int turnon=0;
      while (turnon==0){
        if (digitalRead(button)==1) {i=stripSize; butPush=1;}
        int x = random()%stripSize;
        if (lights[x]==0){
          turnon=1;
          lights[x]=1;
          strip.setPixelColor(x,red,green,blue);
          strip.show();
        }
      }
    if (butPush==0) delay(dly);
    } 
  if (butPush==0)   delay(2000);
    for (int i = 0; i < stripSize; i++){
      int turnoff=1;
      while (turnoff==1){
        if (digitalRead(button)==1) {i=stripSize; butPush=1;}
        int x = random()%stripSize;
        if (lights[x]==1){
          turnoff=0;
          lights[x]=0;
          strip.setPixelColor(x,0,0,0);
          strip.show();
        }
      }
    if (butPush==0) delay(dly);
    } 
  }
}
void kit(int dly){
  int lmin=0; int lmax=16; int lx=1; int lcur=lmin;
  int rmin=32; int rmax=48; int rx=1; int rcur=rmin;
  int bmin=50; int bmax=62; int bx=0; int bcur=bmax;
  int fmin=18; int fmax=30; int fx=0; int fcur=fmax;
  int wlev=8;
  int lrticks=6; //number of times to loop through before moving the leds
  int fbticks=8; //number of times to loop through before moving the leds
  int tick=1;
   for (int i=lmin; i<lmax; i++){
     strip.setPixelColor(i,wlev,wlev,wlev);
   }
   for (int i=rmin; i<bmax; i++){
     strip.setPixelColor(i,wlev,wlev,wlev);
   }
  while (digitalRead(button)==0){
     for (int i=0; i<2; i++){
       //calculate brightness level for position.  Closer to the center is brighter
       //turn on 2 leds at a time
//       strip.setPixelColor(lcur+i,127/abs(((lmax-lmin)/2)-lcur),0,0);
//       strip.setPixelColor(rcur+i,127/abs(((rmax-rmin)/2)-(rcur-rmin)),0,0);
//       strip.setPixelColor(bcur+i,127/abs(((bmax-bmin)/2)-(bcur-bmin)),0,0);
//       strip.setPixelColor(fcur+i,127/abs(((fmax-fmin)/2)-(fcur-fmin)),0,0);
       strip.setPixelColor(lcur+i,127,0,0);
       strip.setPixelColor(rcur+i,127,0,0);
       strip.setPixelColor(bcur+i,127,0,0);
       strip.setPixelColor(fcur+i,127,0,0);
     }  
     strip.show();
     delay(dly);
     strip.show();
     if (tick%lrticks==0){ //Do we need to change the position?
       for (int i=0; i<2; i++){
         //turn the 2 leds back to white
         strip.setPixelColor(lcur+i,wlev,wlev,wlev);
         strip.setPixelColor(rcur+i,wlev,wlev,wlev);
       }  
       if (lx==1) lcur++;  //increment or decrement the position
       else lcur--;
       if (lcur>=lmax) lx=0; //Are we at the max?
       if (lcur<=lmin) lx=1; //Are we at the min?
       if (rx==1) rcur++;  //increment or decrement the position
       else rcur--;
       if (rcur>=rmax) rx=0; //Are we at the max?
       if (rcur<=rmin) rx=1; //Are we at the min?
     }
     if (tick%fbticks==0){ //Do we need to change the position?
       for (int i=0; i<2; i++){
         //turn the 2 leds back to white
         strip.setPixelColor(bcur+i,wlev,wlev,wlev);
         strip.setPixelColor(fcur+i,wlev,wlev,wlev);
       }  
       if (bx==1) bcur++;  //increment or decrement the position
       else bcur--;
       if (bcur>=bmax) bx=0; //Are we at the max?
       if (bcur<=bmin) bx=1; //Are we at the min?
       if (fx==1) fcur++;  //increment or decrement the position
       else fcur--;
       if (fcur>=fmax) fx=0; //Are we at the max?
       if (fcur<=fmin) fx=1; //Are we at the min?
     }
     if (tick++==lrticks*fbticks) tick=1;
  }
  butPush = 1;
}
void shiftwhite(int dly){
  for (int o = 0; o < stripSize; o++){
    for (int i = 0; i <stripSize; i=i+5){
      strip.setPixelColor((i+o)%stripSize, 127,127,127);  
//      strip.setPixelColor((i+1+o)%stripSize, 127,127,127);  
      strip.setPixelColor((i+2+o)%stripSize, 0,127,0);  
      strip.setPixelColor((i+3+o)%stripSize, 0,127,0);  
      strip.setPixelColor((i+4+o)%stripSize, 0,127,0);  
      strip.setPixelColor((i+5+o)%stripSize, 0,127,0);  
      if (digitalRead(button)){
        butPush = 1;   //Was the button pushed to change modes?
        i = stripSize;
        o = stripSize;
        }
    }
    strip.show();
    if (butPush == 0) delay(dly);
  }
}

2nd part

void ran1(int dly){
    int r = random()%128;
    int g = random()%128;
    int b = random()%128;
    int start = random()%stripSize;
    if (random()%2 == 0){
      for (int i = 0+start; i < stripSize+start; i++){
       strip.setPixelColor(i%stripSize, r,g,b);
       strip.show();
       if (butPush == 0) delay(dly);
      if (digitalRead(button)){
        butPush = 1;   //Was the button pushed to change modes?
        i = stripSize;
        }
     }
    }
   else { 
      for (int i = stripSize+start; i >=0+start; i--){
       strip.setPixelColor(i%stripSize, r,g,b);
       strip.show();
       if (butPush == 0) delay(dly);
      if (digitalRead(button)){
        butPush = 1;   //Was the button pushed to change modes?
        i = 0;
        }
     }
    }
}
void ran(int dly){
  while (digitalRead(button)==0){
    strip.setPixelColor(random()%stripSize+1,random()%128,random()%128,random()%128);
    strip.show();
    delay(dly);
  }
  butPush = 1;  
}
void allon(){
    for (int i = 0; i < stripSize; i++){
     strip.setPixelColor(i, 127, 127,127);
   } 
   strip.show();
//   delay(1000);
  if (digitalRead(button)) butPush = 1;   //Was the button pushed to change modes?
//    for (int i = 0; i < stripSize; i++){
//     strip.setPixelColor(i, 0, 0,0);
//   } 
//   strip.show();
//   delay(1000);
//  if (digitalRead(button)) butPush = 1;   //Was the button pushed to change modes?
}
void circlinglights(int dly){
  int b=0;
  int r=63;
  while (digitalRead(button)==0){
    strip.setPixelColor(b,0,0,2);
    strip.setPixelColor((b+1)%stripSize,0,0,9);
    strip.setPixelColor((b+2)%stripSize,0,0,16);
    strip.setPixelColor((b+3)%stripSize,0,0,40);
    strip.setPixelColor((b+4)%stripSize,0,0,55);
    strip.setPixelColor((b+5)%stripSize,0,0,80);
    strip.setPixelColor((b+6)%stripSize,0,0,127);
    strip.setPixelColor(r,2,0,0);
    strip.setPixelColor((r+stripSize-1)%stripSize,9,0,0);
    strip.setPixelColor((r+stripSize-2)%stripSize,16,0,0);
    strip.setPixelColor((r+stripSize-3)%stripSize,40,0,0);
    strip.setPixelColor((r+stripSize-4)%stripSize,55,0,0);
    strip.setPixelColor((r+stripSize-5)%stripSize,80,0,0);
    strip.setPixelColor((r+stripSize-6)%stripSize,127,0,0);
    strip.show();
    delay(dly);
    strip.setPixelColor(b,0);
    strip.setPixelColor(r,0);
    strip.show();
    if (b++==stripSize) b=0;
    if (r--==0) r=stripSize-1;
  }
  butPush = 1;
}

void caution(int dly){
  while(butPush==0){
    for (int i = 0; i<stripSize; i++){
       strip.setPixelColor(i, 127, 90,0);
        if (digitalRead(button)){
          butPush = 1;   //Was the button pushed to change modes?
          i = stripSize;
        }
    }
    if (butPush == 0) {strip.show(); delay(dly);}
    for (int i = 0; i<stripSize; i++){
       strip.setPixelColor(i, 0, 0,0);
        if (digitalRead(button)){
          butPush = 1;   //Was the button pushed to change modes?
          i = stripSize;
        }
    }
    if (butPush == 0) {strip.show(); delay(dly);}
  }
}
void police(int dly){
  for (int x = 0; x<2; x++){
    for (int i = 0; i < 25; i++){
     strip.setPixelColor(i, 127, 0,0);
      if (digitalRead(button)){
        butPush = 1;   //Was the button pushed to change modes?
        i = 32;
        x = 2;
      }
    }
    for (int i = 57; i < 64; i++){
     strip.setPixelColor(i, 127, 0,0);
      if (digitalRead(button)){
        butPush = 1;   //Was the button pushed to change modes?
        i = 32;
        x = 2;
      }
   } 
   strip.show();
  if (digitalRead(button)) butPush = 1;   //Was the button pushed to change modes?
  if (butPush == 0) delay(dly);
    for (int i = 0; i < 25; i++){
     strip.setPixelColor(i, 0, 0,0);
      if (digitalRead(button)){
        butPush = 1;   //Was the button pushed to change modes?
        i = 32;
        x = 2;
      }
    }
    for (int i = 57; i < 64; i++){
     strip.setPixelColor(i, 0, 0,0);
      if (digitalRead(button)){
        butPush = 1;   //Was the button pushed to change modes?
        i = 32;
        x = 2;
      }
    }
    strip.show();
  if (butPush == 0) delay(dly);
  }
  for (int x = 0; x<2; x++){
    for (int i = 25; i < 57; i++){
     strip.setPixelColor(i, 0, 0,127);
   } 
   strip.show();
  if (butPush == 0) delay(dly);
    for (int i = 25; i < 57; i++){
     strip.setPixelColor(i, 0, 0,0);
      if (digitalRead(button)){
        butPush = 1;   //Was the button pushed to change modes?
        i = 64;
        x = 2;
      }
    }
    strip.show();
  if (digitalRead(button)) butPush = 1;   //Was the button pushed to change modes?
  if (butPush == 0) delay(dly);
  }
  if (digitalRead(button)) butPush = 1;   //Was the button pushed to change modes?
}

void music(int all){
  micLevel = ((analogRead(A0)+analogRead(A2)))%1024; //read the pot value and add it to the microphone value to allow color shifting
  if (digitalRead(button)) butPush = 1;   //Was the button pushed to change modes?
  //colorLevel = (micLevel%768)/2;
  colorLevel = micLevel%384; //adjust colorLevel with the color wheel spectrum
  numLeds = map(micLevel,200,600,0,stripSize); //Adjust adjust the most use of LEDs
  
  if (all) numLeds = stripSize;
  for (int i = 0; i < numLeds; i++){
    strip.setPixelColor(i, Wheel((i+colorLevel)%384));
  }  
  delay(map(analogRead(A1),0,1024,0,250));
  strip.show();
    for (int i=0; i < strip.numPixels(); i++) {
      strip.setPixelColor(i, 0);  // turn all pixels off
    } 
  if (digitalRead(button)) butPush = 1;   //Was the button pushed to change modes?

}

void rainbow(uint8_t wait) {
  int i, j;
   
  for (j=0; j < 384; j++) {     // 3 cycles of all 384 colors in the wheel
    for (i=0; i < strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel( (i + j) % 384));
      if (digitalRead(button)) {
        butPush = 1;   //Was the button pushed to change modes?
        j=384;
      }
    }  
    strip.show();   // write all the pixels out
    if (butPush == 0) delay(wait);
  }
}

// Slightly different, this one makes the rainbow wheel equally distributed 
// along the chain
void rainbowCycle(uint8_t wait) {
  uint16_t i, j;
  
  for (j=0; j < 384 * 5; j++) {     // 5 cycles of all 384 colors in the wheel
    for (i=0; i < strip.numPixels(); i++) {
      // tricky math! we use each pixel as a fraction of the full 384-color wheel
      // (thats the i / strip.numPixels() part)
      // Then add in j which makes the colors go around per pixel
      // the % 384 is to make the wheel cycle around
      strip.setPixelColor(i, Wheel( ((i * 384 / strip.numPixels()) + j) % 384) );
      if (digitalRead(button)){
        butPush = 1;   //Was the button pushed to change modes?
        j=384*5;
      }
    }  
    strip.show();   // write all the pixels out
    if (butPush == 0) delay(wait);
  }
}

// fill the dots one after the other with said color
// good for testing purposes
void colorWipe(uint32_t c, uint8_t wait) {
  int i;
  
  for (i=0; i < strip.numPixels(); i++) {
      strip.setPixelColor(i, c);
      strip.show();
      if (butPush == 0) delay(wait);
      if (digitalRead(button)){
        butPush = 1;   //Was the button pushed to change modes?
        i = strip.numPixels();
      }
  }
}

// Chase a dot down the strip
// good for testing purposes
void colorChase(uint32_t c, uint8_t wait) {
  int i;
  
  for (i=0; i < strip.numPixels(); i++) {
    strip.setPixelColor(i, 0);  // turn all pixels off
  } 
  
  for (i=0; i < strip.numPixels(); i++) {
      strip.setPixelColor(i, c);
      if (i == 0) { 
        strip.setPixelColor(strip.numPixels()-1, 0);
      } else {
        strip.setPixelColor(i-1, 0);
      }
      strip.show();
      if (butPush == 0) delay(wait);
      if (digitalRead(button)){
        butPush = 1;   //Was the button pushed to change modes?
        i = strip.numPixels();
      }
  }
}

/* Helper functions */

//Input a value 0 to 384 to get a color value.
//The colours are a transition r - g -b - back to r

uint32_t Wheel(uint16_t WheelPos)
{
  byte r, g, b;
  switch(WheelPos / 128)
  {
    case 0:
      r = 127 - WheelPos % 128;   //Red down
      g = WheelPos % 128;      // Green up
      b = 0;                  //blue off
      break; 
    case 1:
      g = 127 - WheelPos % 128;  //green down
      b = WheelPos % 128;      //blue up
      r = 0;                  //red off
      break; 
    case 2:
      b = 127 - WheelPos % 128;  //blue down 
      r = WheelPos % 128;      //red up
      g = 0;                  //green off
      break; 
  }
  return(strip.Color(r,g,b));
}

This may be silly, but I am trying to understand how the LED (or "pixels") are identified , ie how do I know number one is the first or so. As per the library it seems to be the pixels are handled by an array and the show function just send the color info via the SPI . I am not familiar with CPP syntax (I play mostly AVR in C), but is pixels[0] the first LED ? if so how the controller knows?

Thanks for any info or direction on on this and my apologies if this is indeed silly and I must look better in the code.
Jose

The library does keep track of how many pixels (or leds) you have with the statement:

#define stripSize 64

It then initializes the interrupt to use this in this statement:

LPD8806 strip = LPD8806(stripSize);

If you want to get into the nitty gritty, look at the LPD8806.cpp file. It breaks up the data to send to the ICs and then latches it in to display. ICs in series have information overflow from one IC to the next on the data and clock pins to allow these long runs.

Hope this helps a bit...

Hmm, I have a problem with getPixelColor, basically the green value is always 7F (127). Looking in the LPD8806.cpp file,

// Set pixel color from separate 7-bit R, G, B components:
void LPD8806::setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b) {
  if(n < numLEDs) { // Arrays are 0-indexed, thus NOT '<='
    uint8_t *p = &pixels[n * 3];
    *p++ = g | 0x80; // LPD8806 color order is GRB,
    *p++ = r | 0x80; // not the more common RGB,
    *p++ = b | 0x80; // so the order here is intentional; don't "fix"
  }
}

// Query color from previously-set pixel (returns packed 32-bit GRB value)
uint32_t LPD8806::getPixelColor(uint16_t n) {
  if(n < numLEDs) {
    uint16_t ofs = n * 3;
    return ((pixels[ofs    ] << 16) |
            (pixels[ofs + 1] <<  8) |
             pixels[ofs + 2]) & 0x7f7f7f;
  }

  return 0; // Pixel # is out of bounds
}

Specifically in this case, I am trying to see what RGB colours a pixel is set to, then divide by two to set the pixel behind it to that colour, etc, to create a trail. I'm setting colours with setPixelColor(10,20,30) for example.

To get the colour of a pixel back, I am doing:

Serial.print("Red: ");
    Serial.print((strip.getPixelColor(i) & 0x00FF00) >> 8);
    Serial.print("Green: ");
    Serial.print((strip.getPixelColor(i) & 0xFF0000) >> 16);
    Serial.print("Blue: ");
    Serial.print(strip.getPixelColor(i) & 0x0000FF);

Red and blue return the right values, but green is always 127, and I just can't figure out why. The library mentions 'packed' values, but I don't understand enough about the code to understand how it's packing it. Any ideas welcome!

Cranium,

Thanks for the information, I thought the Data and Clock lines were passing thru and it is not the case each LPD8806 must push them to the next like a daisy chain. I will keep looking the code but then the protocol might be like sending the RGB data and then a latching command which will now allow go to the next controller and so on. I imagine that when the last pixel is reached there must be some kind of unlatch command so the first pixel is enabled again to receive the data.

Jose

Glad to help. Helps me learn more about it as well.

As I understand it:
When data is sent down the line, an IC will fill its buffer then start shifting data to the data out line regardless of whether there is actually another IC after it. Once the data transfer has been completed, it will then send up to 3 bytes of zeros to tell the ICs to latch the output pins. There is no unlatch command. It will then automatically start accepting SPI data again to fill the buffers of the ICs.

Thanks , I am having a clearer picture now as what you say seems to be exactly what the show() function does. Then, lets say I want to control pixel number three, I will need to send 9 bytes, 3 for the first IC, three for the second and the last three will go to pixel 3. However, the show() routine will go to ALL the pixels , then I imagine I will send unchanged data to the pixels I do not want to undergo any change.

In summary, even if I want to modify the color of pixel three, the routine will fill ALL the pixels with data then I need to keep same value for the pixels I want to leave unchanged. The more difficult to understand is the latching; provided there are less than 128 pixels, show() will send three zeroes at the end of the sequence. Then it must be that when the first chip receives 3 consecutive zeroes , it will latch and pass them thru and so on and so forth until the last chip. But if there are 128 to 192 pixels in the strip, then show() will send SIX zeroes at the end of the transfer. So the total number of pixels seems to affect the way the latch command ( zeroes) is decoded.

Thanks !

These have been very helpful posts. I imagine I might have some questions about sourcing and part selection in the near future.

I just ordered a 1m strip from adafruit. I also ordered a bunch of single led modules/pixels from Bliptronics. I plan to experiment with everything I have and see what works/looks best for that various projects I have in mind. In the mean time I'd love to hear any progress you guys have made.

Have you any of you seen this: http://www.passion-ledlighting.com/
Basically a Chinese knock-off of the Color Kinetics/Philips iColor Flex line: http://www.colorkinetics.com/ls/rgb/
Color Kinetics is basically what's being using in big video displays at many concerts and sporting events.
I have no idea about pricing for either one, but might look into it.

With some luck a friend of mine may be able to get his hands on some of the Color Kinetics LED strings and the PSU/Drivers and Video software to run them. These use a 3 conductor wire. I am not sure what protocol they use or how they work exactly. Best I can tell all the nodes are in parallel. They seem to be limited either by power or data restrictions to less than 72 pixels per strand. They get around this by having psu/driver units that can handle many strands. And then the drivers can be daisy chained in a rack set-up via ethernet. For one of the big video screens you might see at a show, they could have entire racks of power/driving electronics. I'm not interested in doing any hi-res video, so this shouldn't be an issue for me. One cool thing about the strands is that they are very weather proof, and you can place the pixels at any point on the wire. They essentially have little teeth on them that pierce the wire strand. I think attention has to be paid to sealing any open puncture holes. This stuff can get very expensive. I'm mostly interested in seeing if I can drive these LEDS using an Arduino.

So found this schematic of the LPD8806 chip, granted its in Chinese of course, but I have a question about the pins below. I am purchasing my own chips and own SMD RGB leds and making my own setup, but unsure how to hook up.

Firstly, why is there a ground (GND) pin on both sides? Do both need to be connected to ground?

Secondly, what do the PMODE, NC and OMODE pins refer to and what are the needed for when hooking up these chips?

THANK YOU!

I took a chance and purchased 20m of LPD8806 based LED strip from a China manufacturer. I had to do a wire transfer of funds and was very hesitant to do so since I have very little recourse if the product was sub-standard, didn't operate like I expected or I never received it.

But I was pleasantly surprised at the results. These are the exact same strips found on Adafruit for less than 1/2 of the cost. :slight_smile:

I have one of the two strips running with the same code I used from my previous project using the 2m I bought from Adafruit. I need to get a PC power supply rigged up to provide more amperage to run all 320 RGB LEDs on both strips and get my office lighting project built.

The company I ordered from is http://www.gree-leds.com/.

So I screwed up the two 5M strips I bought. Totally my fault. I put my power supply in series mode to get more from it but didn't adjust the voltage prior to pushing the button. I fried the strip and my arduino!

The second strip was after adjusting my voltage down to 5v but not realizing (nor was it well documented) that the display showed only 1/2 of the voltage in each so in actuality I was feeding 10v to the strip. GRRRRRRRR. Another strip fried but the arduino survived. I didn't realize what was going on until I put a meter to the output of the power supply.

So now I have 10M of the LPD8806 strip that doesn't work. Another project for myself is to fix these at some point. I already have plenty of ICs and plenty of 5050 RGB LEDs but have to figure out how to isolate the bad chips and replace just those. Fun, fun.

In the meantime, I ordered and received another 25M of these strips (5 - 5M spools). I got these all tested out and they are working great. I also hooked up two in series (both strips powered from both ends but data lines fed from one to the other) and the arduino controlled all 320 lights with no problem in any of my lighting routines.

I also bought a 20A, 5V power supply from eBay that is powering both strips very well. :slight_smile:

Anyhow, I was thinking of selling some of the latest order if anyone is interested. It would be the exact same as what is bought off Adafruit but cost much less. Not sure if I'll just throw them on eBay by the spool or by the meter yet.

can you sent for me about code program in arduino for drive two LED bar adversely with ULN 2803