Category Archives: Electronics

RGB addressable LEDs (WS2811, LPD8806)

Last year, I was involved with a large Halloween project that involved upgrading the lighting in a haunted house attraction to DMX controlled RGB LEDs. We spent many, many late hours running 12V power through the entire attraction to power all the lights, and Ethernet cable to carry the DMX (RS485) control signal. The end result was the ability to set the lights to any color without having to change bulbs.

Changing the bulbs would have been much easier.

A year before this project, the manager there had introduced me to HolidayCoro.com. This site resells LED lighting mostly for Christmas light displays. (The manager had one of those synchronized Christmas light displays at his house and he was in the process of converting the entire setup to RGB LEDs as well, which he did in 2013.)

Like many things here, one thing seems to lead to another, and I want to share some information in “addressable RGB LED lights.”

Adafruit.com sells a number of RGB LEDs, including their Neo Pixels which allow each light to be individually controlled. I first learned of this type of technology in 2010 when some GE Color Effect G-35 Christmas lights were introduced and quickly hacked so they could be controlled by an external computer. In 2010, this was cutting edge, but today, there are several off-the-shelf ways to do this.

An Arduino controls a strip of 32 LPD8806 RGB LEDs.
An Arduino controls a strip of 32 LPD8806 RGB LEDs.

There are two main LED chipsets I see being used:

  • WS2811 – Adafruit calls these Neo Pixels, and the lights run in series and are addressed over a one wire connection (power, ground, data) using a special protocol. The library for Arduino to do this is very clever and involves specific assembly language timing to toggle the data line at the proper frequency to send the data.
  • LPD8806 – this version uses a two-wire interface (SPI protocol) to talk to the lights (power, ground, clock and data). These lights are far easier to address and less timing sensitive.

At Adafruit, a string of 60 Neo Pixels (1 meter) runs $24.95. You can find similar strips (same chipset, same number of lights) on e-Bay shipped from China for around $18, or bid on auctions and get them for less than $10 each.

At Adafruit, the LPD8806 strips of 32 LEDs (1 meter) run $29.95. A coworker at my day job just bought one of these, which is where I first saw them in person.  On e-Bay, you can find these for $20 on e-Bay with free shipping from China. To find versions with 52 lights per meter (to get light density similar to the WS2811 version), the cost is around $30.

If you want to experiment with the LPD8806 lights without spending a ton of money or waiting weeks for a shipment from China, check out this seller on e-Baykbellenterprises is located in Missouri and will sell a 1-foot strip of LPD8806 lights for $12.99 (with free shipping). They also sell Arduino clones, power supplies and other items at near-China prices (you can get an UNO clone for around $10). You can get one of their strips and hook it up to an Arduino with four wires and safely power the 32 LEDs. (They say you should be able to power up to 2 feet off an Arduino’s 5V 500ma output. More lights than that requires an external power supply.)

As you can see, the LPD8806 lights are about 3 times the cost of the WS2811. The LPD8806 lights are “smarter” (in a way) and easier to work with, without needing specific timing code like the WS2811 require.

For casual play, both work the same way — in fact, Adafruit has posted libraries for each type of light and they both use the same API. You simply set some pixel colors (RGB) and then display them:

strip.begin();

// Set the first 10 LEDs...
for (i=0; i<10; i++)
{
strip.setPixelColor(i, strip.Color(127,0,0));
}
strip.show();

There are some limitations to using these lights on an Arduino. First, the libraries require a buffer of 3-bytes for each LED on the strip  (one byte for red, green and blue). An Arduino with only 2K of RAM can only handle 500 or so lights (more or less, depending on how much RAM your sketch uses, and any libraries you use). This severely limits how useful this is for anything other than just blinking a small strip of lights. My old 1990s BetaBrite LED sign, for instance, is made up of 80×7 LEDs (560) so I couldn’t replicate that using an Arduino and these types of lights using the standard library. More on this later…

There are dedicated controllers (Look for the T1000S, around $43 with free USA shipping, or less from China) that can display light sequences on up 2048 LEDs from an SD memory card. You don’t get any computer control this way (all sequences are made ahead of time using special Windows software), but this would be a much better way to drive a large amount of lights than trying to do it with an Arduino.

But what if one really wanted to use a 2K Arduino? Could you actually make a scrolling LED sign similar to a BetaBrite?

Perhaps.

In coming weeks, I will be sharing some embedded programming tricks that might allow controlling far more than 500 or so LEDs from an Arduino.

Check back…

2N2222 transistor from Radio Shack links Arduino UNO and Teensy 2.0

This screen shot may not seem like much, but it marks the first time I have ever used a transistor:

Reading Transistor Switch

My Tandy joystick project has two goals. The first is to allow an analog Tandy joystick be used as a USB device for a modern computer. This part is easy, since the variable resistors in the joysticks can be easily read from the Arduino/Teensy’s analog inputs, and the joystick buttons can be read on a digital pin.

The second part is a bit trickier. The idea is to use a modern input device on an old Tandy 1000 or Color Computer. To do this, the USB device’s analog position (if it is an analog stick or a mouse) has to be turned in to a resistance value that the old computer can read through it’s joystick ports. I found a tutorial on the Arduino site that shows doing this with an AD5206 digital potentiometer chip:

http://arduino.cc/en/Tutorial/SPIDigitalPot

That seems easy enough, but I wasn’t sure how to make a digital output pin from the Teensy turn in to a dry contact switch. A bit of research led me to a few useful tutorials dealing with transistors and optoisolators:

…and I found various projects where they were using these devices to simulate a button press on a camera, to automate it:

http://www.zipfelmaus.com/blog/hack-a-canon-camera-and-controll-it-with-an-arduino/

The above project is precisely the type of thing I want to do, so I wired up an Arduino like his layout, and then instead of running wires to the switch of a Canon camera, I ran them to a digital input of my Teensy 2.0 and its ground. Using the Fritzing program, here is a diagram of what I did:

Hooking digital outputs to digital inputs.
Hooking digital outputs to digital inputs. (Diagram done with Fritzing)

I hacked a bit of code on the Arduino side that just toggles that digital pin HIGH and LOW (basically, I hacked the LED blink example to also do pin 12):

int led = 13;
int transistor = 12;

// the setup routine runs once when you press reset:
void setup()
{
    // initialize the digital pin as an output.
    pinMode(led, OUTPUT);
    pinMode(transistor, OUTPUT);
}

// the loop routine runs over and over again forever:
void loop()
{
    digitalWrite(led, HIGH); // turn the LED on (HIGH is the voltage level)
    digitalWrite(transistor, HIGH);
    delay(1000);            // wait for a second
    digitalWrite(led, LOW); // turn the LED off by making the voltage LOW
    digitalWrite(transistor, LOW);
    delay(1000); // wait for a second
}

Then, on the Teensy, I wired up to the transistor similar to the Input Pullup example (which reads a button) and reports if the status of the pin had changed. Here’s some quick and dirty code:

void setup()
{
    // Initialize the serial port.
    Serial.begin(9600);

    pinMode(3, INPUT_PULLUP);

    pinMode(LED_PIN, OUTPUT);

    Serial.println("Ready.");
}

int oldStatus;
int status;

void loop()
{

    status = digitalRead(3);
    if (status != oldStatus)
    {
        Serial.print("Pin 3: ");
        Serial.println(digitalRead(3));
        oldStatus = status;
        digitalWrite(LED_PIN, status);
    }
}

Now, with both devices running, on the Arduino, every time the LED turns on, it is also turning on the pin connected to the transistor. On the Teensy, that pin connects to digital input 3. (I started at 3 since that is just passed the three pins used by SPI, which I will be needing for my real project.)

When the light on the Arduino goes on, the light on the Teensy goes off. I would need to change how I wired them (active high versus active low) to make them sync. But, it works.

I have much learning to do on all this, but this proof-of-concept gets me one step closer to what I am trying to do. I will be next be trying the same thing using optoisolator chips, though I am not sure there really needs to be any isolation between the joystick buttons and the Teensy.

More to come…