User Tools

Site Tools


tutorials:products:rgbledpixel:index.html

This is an old revision of the document!


LED full color (RGB) Pixels!

RGB Pixels are digitally-controllable lights you can set to any color, or animate. Each LED module and controller chip is molded into a 'dot' of silicone. The dots are waterproof and rugged. There are four flanges molded in so that you can 'push' them into a drill hole in a thin sheet materual. They're typically used to make outdoor signs.

We have two types of RGB pixels, 12mm and 20mm. They have the same controller chip and use the same power but the LED and shape differs.

Basic stats!

  • 20mm or 12mm diameter waterproof pixels
  • Approx 3" apart on 4 pin strand
  • 15 bit color (5 bits per LED, 3 LEDs per pixel)
  • 5V power, 60mA maximum per pixel (all LEDs on, full white)
  • 2-pin SPI protocol
  • LPD6803 Datasheet for the chip inside each pixel

You can pick up RGB pixels in either size in strands of 20 or 25 at the Adafruit shop. If you're in Australia, bliptronics also has a selection of various pixels

Here is a basic video showing some 12mm dots running a test pattern.

The Adobe Flash Plugin is needed to display this content.

20mm Pixels

The larger pixels are about 20mm in diameter (the flanges are a little more) so if you want to drill a hole for these to fit into, make it 20mm in diameter. These pixels use a "5050" clear RGB LED and are brighter than the 12mm pixels. However, the trade off is that they are not diffused which means that the color mixing is not as nice: close up you can see the different colors.

They draw a maximum of 60mA per pixel: 3 x 20mA per LED and there are three LEDs in each pixel.

12mm Pixels

The 12mm pixels are smaller than the 20mm, needing only a 12mm hole but they are 'longer' since the PCB sticks out back. These pixels use an 8mm diffused RGB LED and so are not as bright as the 20mm pixels but the diffused pixels color mix nicer.

They draw a maximum of 60mA per pixel: 3 x 20mA per LED and there are three LEDs in each pixel.

Pixel spacing

The LED pixels are spaced out on strands of ribbon cable, the spacing is a little different between the 12mm (3.5" between pixels) and 20mm (2.5"). If you need them further spaced, you can extend the ribbon by soldering 4 wires to 'extend' the pixels.

Note that the wires are actually 'split' the 4 wires coming are not the same as the ones going out (see the next section for more details)

Ideas

These pixels could be used for stuff like…

LED coffee tables (this one is 'hand made' but you could skip the wiring/drivers part)

The Adobe Flash Plugin is needed to display this content.

A 'strand' of LEDs like a digital LED strip but easier to control!

The Adobe Flash Plugin is needed to display this content.

A 'ball' of LEDs:

The Adobe Flash Plugin is needed to display this content.

A sign or display

The Adobe Flash Plugin is needed to display this content.

A matrix or wall could also be done

Driver chip

The pixels have a small microchip inside each silicone dot. In these, the microchip is the LDP6803, basically custom designed for this purpose. This chip is very simple - all it does is shift data in from one pin and out the other and the latest 15 bits are the brightness of the LEDs.

So if you want to write data to 10 LEDs in a strip, you would shift out 10 * 16 bits (15 bits + 1 start bit) and the first data out would be the last LED in the strand.

This chip can handle PWMing the color brightness, all it needs is a 'pixel PWM clock' which tells it how fast to PWM. The faster the PWM, the smoother the color, but the PWM has to travel all the way down the strand so it can't be too fast or itll snag the chips.

One strange thing to note, is that the PWM clock is the same as the data clock. This is nice because it saves a pin but it means that when we want to send data to the strand we have to time it so that its sent as the PWM is 'resetting' the counter so that we dont get 'flicker' effects of updating the register while its updating which could cause the register to stay on longer than we want.

Powering

An important part of running a lot of LEDs is to keep track of power usage. LEDs don't get very hot or use tons of power, but they add up fast!

Each RGB LED pixel can draw up to 60mA from a 5V supply. That means a strand of 20 can use up to 1.2 Amps, a strand of 25 can use up to 1.5A. Of course this is assuming all the LEDs are on. If you keep most of the LEDs off (by color swirling or patterns) the power usage can be a 1/3 or less.

We suggest a nice switching supply for driving LED dots, either a 2 A 'PSP charger' for a strand or two, or a slightly modified ATX power supply (you'll need to connect the green power line to ground but you do not need the 'loading' resistor) which can provide 30 Amps to power 500 or more pixels (yow!)

As shown below, connect ground to both your supply and logic microcontroller. Then connect the 5V pin to the power supply. A large capacitor (1000uF or so) is a nice addition to keep ripple down.

Wiring

The nice thing about these pixels is that they are digitally controlled. That is, even though there are only two data lines (clock/data inputs), you can put as many pixels as you'd like in a row and each one is controllable.

It is important to note that even though it looks like the 4-conductor ribbon is continuous, it isn't! The ground and 5V lines are shared but the two data input pins go to a microcontroller and the other side has two data outputs.

When connecting to a microcontroller make sure you are connecting the input pins to the microcontroller! Best way to tell is to look at the dots and find the arrow. In the large dots above, the arrow is in the top right corner. The inputs are on the left and the signal passes to the right. If you want to connect multiple strands together, make sure input goes to output

Wiring is pretty easy since there are only 4 wires. The only important thing is that unless you are sure you will be using only a few of the LEDs at a time, you should not try to power the strip from the 5V on the Arduino. The Arduino is only mean to drive about 500mA of current, and as we saw earlier, a strand can take 1000mA or more if on! For that reason, we suggest powering with an external regulated 5V supply.

Just make sure to 'share' the ground pin, and triple check that you have the voltage polarity right so that ground is 0V and power is 5V. For the arduino library we wrote, you can use any two pins.

Code!

The code to drive these dots is fairly simple, except that the PWM pin and the data clock pin is shared which means that you can't just stick the PWM pin on a hardware timer output because then its not possible to use it for the data clocking.

Instead, the library uses an interrupt that goes off every few milliseconds. If there is data to be updated on the strip, it sends that data. If not, it just pulses pin to keep the PWM going.

Note that the interrupt uses timer 1 which means the pin 9 and 10 PWMs will not 'work' for servos, please use a 'software servo' library!

This code is heavily based off of bliptronics' original code except we library-ized it and trimmed it down. You can download the library from github, then follow our library installtion procedure.

Once you've rebooted, load up the strandtest.pde example sketch, we'll go through the most important parts

First up, you'll need to make an library object to talk to the strip. It is initialized with three variables, the number of pixels and the data/clock pin. You can't change these later.

// Set the first variable to the NUMBER of pixels. 20 = 20 pixels in a row
LPD6803 strip = LPD6803(20, dataPin, clockPin);

Next we will set up the strip in the setup() procedure.

void setup() {
  // The Arduino needs to clock out the data to the pixels
  // this happens in interrupt timer 1, we can change how often
  // to call the interrupt. setting CPUmax to 100 will take nearly all all the
  // time to do the pixel updates and a nicer/faster display, 
  // especially with strands of over 100 dots.
  // (Note that the max is 'pessimistic', its probably 10% or 20% less in reality)
  strip.setCPUmax(50);  // start with 50% CPU usage. up this if the strand flickers or is slow
 
  // Start up the LED counter
  strip.begin();
 
  // Update the strip, to start they are all 'off'
  strip.show();
}

setCPUmax() configures the timer 1 interrupt that PWM's the strand. You can change this from 0 to 100, it runs in the background. The 'max' is calculated assuming the longest possible timing (when sending data) so its a big pessimistic. 50% should be plenty, you can mess with this to make the strip more or less 'flickery' You can change this 'on the fly' so for example set it to 0% just before doing a bunch of Ethernet stuff, then back to 50% later.

begin() actually starts the interrupt

show() is what updates the strand display. You'll need to call it after setting any colors to see the updates. This way you can change the entire strip at a time (it takes the same amount of time to change one pixel as it does for an entire strip because the full strip data must be shifted out at once)

Last, we'll look at an example function, colorWipe. This creates a 'chase' that fills the strip up with a color. It is basically a loop that increments through every pixel (which you can conveniently get by numPixels() ) and sets the pixel color of that pixel (incremented with i) to the color c. In this case the color is stored in a 16 bit variable. The strip output is then updated with show(). Finally there is some delay (otherwise this would happen instantly)

Below that is a little helper that takes 8 bit red green and blue and bit-mashes them into a 15 bit color. This means that the 'max' value for each color is 31.

// fill the dots one after the other with said color
// good for testing purposes
void colorWipe(uint16_t c, uint8_t wait) {
  int i;
 
  for (i=0; i < strip.numPixels(); i++) {
      strip.setPixelColor(i, c);
      strip.show();
      delay(wait);
  }
}
 
/* Helper functions */
 
// Create a 15 bit color value from R,G,B
unsigned int Color(byte r, byte g, byte b)
{
  //Take the lowest 5 bits of each value and append them end to end
  return( ((unsigned int)g & 0x1F )<<10 | ((unsigned int)b & 0x1F)<<5 | (unsigned int)r & 0x1F);
}

For example, in the loop() we call colorWipe(Color(31, 0, 0), 50) which will fill the strand with only-full-red light, pausing about 50 milliseconds between pixels.

  colorWipe(Color(31, 0, 0), 50);  // red fill
  colorWipe(Color(0, 31, 0), 50);  // green fill
  colorWipe(Color(0, 0, 31), 50);  // blue fill

Download

We have an Arduino lirbary that can be fairly easily ported to any microcontroller with two digital output pins and a interrupt timer. This code is heavily based off of bliptronics' original code except we library-ized it and trimmed it down.

You can download the library from github, then follow our library installtion procedure.

Dont forget that this library uses an interrupt on timer 1 which means the pin 9 and 10 PWMs will not 'work' for servos, please use a 'software servo' library!

/home/ladyada/public_html/wiki/data/attic/tutorials/products/rgbledpixel/index.html.1292448821.txt.gz · Last modified: 2016/01/28 18:05 (external edit)