The LPD8806 protocol for Adafruit RGB LED Strips

by ericgu 4. January 2012 06:56

I bought a meter of addressable RGB LED strip from Adafruit. It uses the LPD8806 driver chip to drive LEDs. I didn’t find a writeup of the protocol, so here’s a quick overview.

Each LPD8806 has 6 PWM outputs and can therefore drive two RGB LEDs. It has two lines for SPI input (data & clock), and two lines for SPI output (data & clock).

It is implemented in a very simple way:

  • When it receives a zero byte, it resets its byteCount to 0, and writes a zero byte on the output.
  • When it receives a byte with the high bit set (ie ORed with 0x80) and its byteCount < 6, it uses the lower 7 bits of the byte to set the output of one of the PWM outputs. It then increments byteCount to move to the next PWM output.
  • If byteCount == 6, it just sends the byte to the output.

When these chips are chained together, with the inputs of the second chip connected to the output of the first chip, they are quite easy to use. You just send a total of 3 bytes per LED, and bytes 1-3 go to the first one, 4-6 to the second, and so on.  The byte order is not GRB instead of RGB, which is presumably done so that the PCB layout is simpler.

The color value is 7 bits per color, for 128 * 128 * 128 = 2,097,152 colors.

That’s about it.

And just to repeat the note in the tutorial…

  • Adafruit buys the strip in 5 meter lengths, with connectors at both ends. When you buy a shorter length they cut it off the longer length, so if it has a connector on it, the connector may be the one on the end rather than the one on the start. If you try to hook up to a connector on the end, it won’t work.

  • Tags:

    Electronics

    It's Alive! Alive I tell you!

    by ericgu 2. January 2011 03:23

    Previous posts contain more information and pictures.

    After a bunch of work, the EL Snowman is up and running, and it's pretty nice. Here’s a video, though the video looks jerky on the faster animation rates (the actual animation is smooth), and the colors are off (the hat is blue and the arms are yellow).

    The controller construction took about as much time as I expected. Here are a few shots (the full gallery with higher-resolution shots is here):

    This is an early-stage view of the board. The 40-pin DIP socket for the 8515 microcontroller is on the left, and the series resistors for each channel of the 16 channels (connected to port A and port C on the 8515) is next to it. I have 4 of the 8 16-pin sockets hooked up – each will hold two triac relays.

    The blue wire is 30-gauge wirewrap wire, nice and flexible and heavy enough to carry the 5mA it takes to trigger each relay.


    Sixteen triac relays, AQH2223. You drive them with 5mA of current (5V and a dropping resistor), and that gives you a bunch of isolation between the microcontroller and the inverter that drives the EL. There are cheaper options but I had one on hand and could verify that it worked before I ordered them. About $2 each.

    The back of the completed board. Functional, but not even close to pretty. So why does it look like that?

    Well, there are a few options for construction:

    The nicest option is to do a PC board. That’s a fair amount of work for a one-off project and I would have to deal with the turnaround time for creating the PCs and probably having to iterate to get the design to work. If I was doing something that required high-speed signals, it probably wouldn’t work with this sort of messiness, but we’re only talking a few KHz maximum here.

    A second option would be to do a wire-wrapped board. I’ve done a few wire-wrapped designs and they work pretty well, but wire-wrapped sockets are *expensive* – about $2.50 each for a 16-pin socket, about 10x what a solder-tab socket costs.

    So, that leaves point-to-point wiring. One technique that I use here to connect passive components (such as the resistors here) is to use a hand wire-wrap to wrap a piece of wire-wrap wire around the lead of the passive component. That isn’t sufficient on its own (wire wrap sockets work because the leads are square and the wrapping actually creates a gas-tight weld to the socket pin), but with a tiny bit of solder you get a very clean joint.

    I’ve built 5-6 projects using this sort of construction, and they’ve worked well over the years.


     

    The completed board in the project box. We have, from left to right:

    1. The EL wire inverter, potted in epoxy (it comes that way). It takes 12V in.
    2. An LM7805 linear regulator and filtering capacitors to give me 5V for the microcontroller.
    3. Above that, a small capacitor to provide some load to the inverter when all segments are off. I also connected a 3’ extra length of white EL wire to provide some load and to act as a pilot light. EL inverters don’t like operating without a load on them.
    4. The bank of 16 triac relays. The ribbon cable is wired in pairs – you have a switched wire from one of the triac relays, and then a wire that goes back to the inverter. The common wires are joined together and become the green wires that head back to the inverter.
    5. The empty socket for the microcontroller.

     


    Here’s the completed display with the back spray painted white.

     

    And a disturbing picture of the back. For each of the animation frames, I had to join 5 segments (two arms, 3 balls) together with the ribbon cable wire for that channel, and there was no nice way to do that (though there certainly could have been a nicer way than what I chose), so that’s the ugly yellow shrink wrap which is then sealed with hot glue.


     
    The mess during the construction. The display was done in a different room.

    Code

    The code is written in C. I started out the project using CodeVisionAVR, a nice IDE that has a *very* useful wizard that will make the initial setup of the processor easier – code like this:

    // Timer/Counter 0 initialization
    // Clock source: System Clock
    // Clock value: 7.813 kHz
    // Mode: Normal top=FFh
    // OC0 output: Disconnected
    TCCR0=0x05;
    TCNT0=0x7D;
    OCR0=0x00;

    So I can just choose 7.813 kHz as a refresh rate rather than figuring out that I need to set TCCR0 to 0x05. That’s a big timesaver.

    The big disadvantage of CodeVisionAVR (beyond that you have to pay for it) is the way that they handle licensing. When they release a new version, they’ll send you a email with a link to the download site and the decryption key for that version, but they don’t keep additional versions around on their website, so if you don’t download the version and miss a later email, you are SOL – the decryption key doesn’t work on the version that’s available on the website. When my laptop cratered, this was pretty annoying – I couldn’t download the version that I bought from the website so I had to pay for an update even though I didn’t care about the updated features. And when you do install a version, you have to send them a code in email, and then they send you the key that unlocks the product so you can finally use it. Their turnaround is pretty fast but it doesn’t help when you want to use it *right then* – you need to wait overnight, typically. They do have great tech support, and if you’re dealing with unfamiliar AVR variants the code wizard is a big timesaver.

    Anyway, while I was waiting for my new unlock code to show up, I tried the AVR studio/gcc combination, and decided to stay with it for this project. The language is slightly newer (I can write “for (int i)” instead of having to declare “I” earlier), though programming is a bit more time consuming with more UI actions (there may be a way to make this easier).

    Tags:

    Electronics

    Juggling Snowman Update…

    by ericgu 9. December 2010 08:42

    I’ve put in a fair amount of time working on the snowman and have made some good progress, though weekends are now a bust since last weekend and next weekend are full of ski instructor training.

    Getting all the EL wire segments fabricated was a bit of a challenge – there are 48 of them, each with either the EL wire or the attached wire a specific length. I had some of the wire go bad on me (arc between the corona wire and the middle wire) so I had to re-order some of the stuff – I think its possible that it got over-driven by the inverter I’m using, so I switched over to using my tiny AA powered one to test out segments. I also make a long section of white that will be the pilot segment – the inverters don’t like running without a load.

    Thanks to somebody with burning man experience, I found out a good way to finish off the wires. Before you put the heatshrink tubing over the wire, put some hot glue around it and then put the tubing on and shrink it while the glue is still hot. This fills in the area around the corona wires and gives you a generally more robust connection. I did the same at the far end, and the act of doing it seems to prevent arcs as well (hot glue is a better insulator than air.

    Then it was a whole lot of hot-gluing. The circles and head go on first, followed by 8 arm segments on each side, followed by the 24 ball segments. Sometimes they are on top of other segments. The result looks like this:

     

    Yes, it’s very, very messy, with all 48 circuits visible.

    Yesterday I spent the evening running outside every 20 minutes to add another coat of spray paint (krylon plastic-specific paint). I suggest wearing a good respirator even if you are outside – I didn’t when I was younger and now get an intense headache if I don’t wear one.

    Tonight I drilled holes and routed all of the wires through the the back and then fixed a few segments of wire that needed a bit more glue. I may add more glue to all of them to make it more secure. I tested all 48 segments and am happy to report that they all work. Here’s what it looks like now:

    Next up will be to group the arm and ball segments together. Each frame has 5 segments – 2 for the arms and 3 for the balls in the air. When they are grouped together I will have 8 frames and 8 other segments. Then it will be off to do fabrication of the controller.

    AFAIK I have all of the parts for that now. I had originally planned to go with raw triacs (and had even ordered some) but decided that since I was dealing with a fair amount of voltage I’d use something with isolation. I ended up using the same Panasonic AQH2223 SSR relays that I used in my last project – there are some cheaper options now but I had a couple extra of the AQH2223s in my parts box and I could verify that they will work for this application. They are designed to be driven from 5V so that will work out just fine.

    I’ll also get started on the animation software. The offspring has giving me a few ideas for things to do.

    Tags:

    Electronics

    (12 - 5) x 0.850 = ouch

    by ericgu 17. February 2010 07:04

    I recently finished the construction on my landscape lighting base station, putting everything into the boxes I have, and wiring everything up.

    Turned the power on, pressed the buttons, and the relays worked fine. Turned on the remote, and it worked as well. Win.

    And then I did the important heat test, where you grab the components to make sure that they weren't overheating. The relays were fine, the transistors driving the relays were cool, and the avr was also cool.

    Then I burnt myself on the 7805 voltage regulator. Which isn't very surprising. The 4 relays pull about 750 mA in total, and along with the xbee and everything else, the total current draw is 0.85 amps. The regulator itself is rated up to an amp, so it's fine, but since the input voltage is 12V, that means we need to get rid of (12Vin - 5Vout) * 0.85A = 6 watts. Not a ton of heat, but waaay too much for the regulator by itself. I dug out the data sheet, and found that the 7805 is rated up to 125 degrees C at the junction which is pretty darn hot. I modded a heatsink into the side of the case, hooked it up, turned everything on, and let it bake for a bit. My IR thermometer says that the heatsink stabilizes at about 74 degrees C. This is okay for the device, but hot enough that you don't really want to be touching it.

    So, I'm thinking about the option. There are really two that I've considered...

    The first option would be to rework the output board. If I had been thinking ahead of time, I would have used 12VAC relays, driven then from triacs with opto-isolators that connected to the AVR. That would have dropped the per-channel current down to perhaps 24 mA, and the overall current to perhaps 200mA. But that's still going to dissipate over a watt, and still require a heatsink - though it would be a lot cooler.

    The better option is to switch to a switching regulator. Those run at high enough efficiency to not need a heatsink, and they come in drop-in replacements for the 7805. A bit pricey, but certainly a simpler choice.

    Tags:

    Electronics

    Landscape light update

    by ericgu 26. January 2010 07:13

    I've been pretty busy with skiing, but have made some good progress. I've played around a bit with the available commands, and have made a few decisions.

    First, I've decided to use the xbees in their simple serial replacement mode. In this mode, it just acts like there's a serial cable between the two modules. The more complex stuff looks interesting for future stuff.

    Second, I've figured out what I want to do to handle the handshake between the two devices and how to structure the code. I'll share some code when I get it written.

    Base station:

    1. The main loop will constantly send out a heartbeat with the current status of the lights. It will send “EG0” if the lights are off and “EG1” if the lights are on, at an interval of 1 second. I'll either do the loop with a simple delay routine (delay_ms() from the standard library), or I'll piggyback on the short-period timer that I'll use to debounce. Probably the former.
    2. The interrupt service routine for the xbee will look for commands and process them. If it sees S0 it will turn the lights off, and S1 it will turn the lights on.
    3. The interrupt service routine for the pushbuttons (“all on”, channels 1-3 on individually, “all off”) will handle servicing the buttons. I'll probably use the short-period timer to debounce the pushbuttons
    4. The interrupt service routine for the long-period timer will handle turning the lights off after a time period.

    That's going to use up most of the capability of the 2313 I’m using. I decided to do 3-5 output channels, each with a dedicated 30A relay to do the actual switching. The relays will be driven off of the avr using a transistor to get the necessary current, which is something like 200mA, far more than you can get from an AVR.

    The xbee unfortunately runs on 2.8-3.4V, not the 5 volts I bought for the power supply. The adapter boards that I bought down-regulate the voltage, but I don't want to waste them on a project like this. I could put a nice 3V regulator on it if I have it, but I'm thinking of just putting three silicon diodes in series, which would give me 0.65 * 3 volts - almost perfect - and it will work fine assuming I don't pull too much power through them.

    Remote station:

    This one is going to go in a tiny project box, which an on/off switch, a link LED, a status LED, and a pushbutton. I'm going to fit all that into a tiny project box, along with two AA alkalines (or maybe AAA if I don't have the space).

    The code will be something like the following:

    1. On startup, blink the link LED a few times.
    2. On the interrupt service routine for the xbee, look for the EG0 or EG1 data. If it's there, turn on the link LED, and turn on the status LED if the command was EG1. Set the short-period timer for about 900 mS.
    3. On the short-period timer interrupt, turn off the link LED. This will have the effect of blinking the link LED off for 100mS as long as the remote is receiving data from the base station.
    4. I'll use the long-period timer to debounce the switch. On that interrupt I'll send S0 if the current status is on, and S1 if the current status is off.

     

    Lights

    I mounted three sets of three lights on trees over Sunday, so this weekend I'll be able to wire them up to the transformer and see what voltage I need to use for each zone.

    Tags:

    Electronics

    Outdoor Lighting Project

    by ericgu 7. September 2009 07:01

    I have a lighting issue at my ski place that I need to solve.

    If the weather's good, we just drive up, unlock the gate (in the car's headlight), and wait for the motion detector lights to kick on.

    If there's a little bit of snow - say, 3" or so - the Outback handles it fine, and I get out the snowblowblower and clean off the driveway. Except once I get about 50' away from the house, I can't see anything any more, and snowblowing in the dark isn't a lot of fun.

    If there's more snow, we can't get into the driveway, and have to park out in front, unload in the dark, and then walk across the meadow and through the woods to the house. In the dark.

    Seems like we need some lights.

    The first choice is whether to go with line voltage or low voltage. Really simple in this case - I need to get the power to two locations about 150' from the house, and I need to get the lights up into the air. That means a whole lot of trenching through the woods and putting up poles to attach the lights to. Or, it's running some zip cord through the woods and then mounting some lights up in the trees. So, we're going the low voltage route.

    Which has some problems of it's own. One of resistance.

    The transformer for the system will mount in the house, and that means about 150' of wire to each of two remote locations. Let's say we buy 12 gauge wire, just to make it easy. We have 300' of wire total, and if we look up the resistance, we find that it's 1.588 ohms/1000 ft, putting us right about 0.5 ohms for the 300' of wire.

    That doesn't seem like a lot of resistance, so let's look at some numbers. If we want to run two 20 Watt lights, that will take 40 / 12 = 3.3 amps, so we'll lose 0.5 * 3.3 or 1.6 volts. With 12 volts running into the run at the start, that means we have 10.4 volts into the lights. If they're halogen lights, they don't like that - halogens require full voltage or their lives are reduced considerably. If we bump up to 2 50 watt lights, it's much worse - we're pulling 8 amps and losing a full 4 volts in the wire.

    The professional low voltage transformers have taps at higher voltages, so we'd hook up the 14 volt tap for the 20W lights, and the 16 volt tap for 50W lights. Unfortunately, the pro transformers are fair bit more expensive than the ones I'd like to buy. Another option would be to go with thicker wire 10 gauge only has about 2/3 of the resistance, but it's also half again as much copper, so it's a lot pricier.

    As an alternative, let's consider a system with LED bulbs instead of halogen ones. You can now find 3-5W LED MR16 lamps that in the $20 range, producing the same amount of light as a 20W (ish) halogen. It's about 5 times more efficient, which means that if you put two of those out, you are only pulling 1 amp, and you only lose 0.5 V. I can probably step down to a smaller wire gauge with the right transformer.

    Not sure which way I'm going to go yet. But I do have the control system designed. That's up next...

    Tags:

    Electronics