If you've seen my previous Instructable on RGB LEDs, then you have a pretty good foundation on the ability to put three separate light sources into a single package in your builds.
Time marches on, and so does technology! One of the most innovative new things about RGB LEDs is the addition of a discreet Integrated-Circuit (or IC) inside of the shell to reduce the burden of their use. With a standard common-cathode Push-Thru-Hole (PTH) RGB LEDs, you need three pins per LED with a common ground. The Arduino Uno has only 6 PWM pins so you would be limited to a maximum of two RGB LEDs on it. To use more, one needs either a larger Microprocessor, the addition of shift registers, or even daisy-chaining a network of microprocessors together.
Addressable LEDs only require one signal pin, power, and a common ground. The power can even be from a separate supply. This makes products such as this (from SparkFun.com) and this (from Adafruit.com) not just possible but practical for the hobbyist.
Step 1: The Basics, How Is an Addressable RGB LED Different?
At a glance, these LEDs look very similar to their older cousins. One has to delve into the epoxy to find the differences. There is a tiny-tiny little chip in there, it handles a lot of things for you. It manages the voltage to the LEDs and listens for its instructions before passing along the message. That little silicone brain also is able to figure out where in the sequence of LEDs it is, so that you do not have to configure anything in the LED itself to string a whole bunch of them together.
With a standard RGB LED, you have three pins providing the power to the Red, Green, and/or Blue elements and a common return pin. The pins themselves are often arranged in a Red-Ground-Blue-Green configuration. They come in Common-Anode and Common-Cathode types, each with slightly different needs and configurations.
With Addressables, you have a Data In pin, a Power pin, a Ground Pin, and a Data Out pin. Additionally, they understand Red - Green - Blue color codes easily so you don't have to worry that long habit has you transposing the Green and Blue values.
Both types have a flat side of the lens housing to indicate the polarity of the units.
Step 2: How Does It Work?
The WS2812 IC inside these Addressable LEDs acts just like a shift register. In fact in some datasheets they are called Shift Register Programmable LEDs. Its this tiny chip that makes the magic in the secret sauce. Its more than just a Shift Register too, it includes the current limiting resistor all LEDs need, as well as regulates the input voltage to what the specific LED elements need. You can learn more about Shift Registers here on Wikipedia.
In my previous Instructable, I went into some detail about LEDs and how that altering voltage was a good way to kill LEDs and that if you wanted to dim them, you needed to use a Pulse-Width Modulating signal. What Pulse-Width Modulation does is turn the LED on and off so fast that it changes the average light level. The more time the LED is off, the darker it looks. The reason you don't see it that way is that the LED is switched on and off so fast, your eyes cannot detect it.
Addressable LEDs are neither controlled by voltage, nor Pulse-Width Modulation. They are controlled by a carrier signal. This 800kHz signal has a format that describes to the chip what each of the colors should be, what the brightness should be, and also what every LED in the chain downstream should be too.
When the WS2812 receives the signal, it decodes its own data from that carrier signal, then sends out the rest of the data downstream to the next LED and so forth.
In the Arduino, this is accomplished by the use of a rather clever library written by the fine folks at Adafruit, who sell the NeoPixel line of products that use the WS2812 chip. In fact when you look at the guts of that library the actual data is sent to out with a series of carefully timed DigitalWrite() commands. This means that any of the 13 digital pins could be used, not just the six PWM pins.
Step 3: Building the Demostration
For the demo I've put together, I've placed five addressable LEDs in a breadboard. Connected the Power and Ground rails of the breadboard to my Arduino Uno, and then daisy-chained the LEDs together, one Data Out to the next Data In. I've also added a little piezoelectric buzzer just for some extra fun. The first LED's Data In pin is connected to pin 6 on my Arduino and the piezo is on pin 8.
While pin 6 is a PWM -- or Pulse Width Modulation pin -- on the Arduino Uno, we will not be using PWM with this demo. In fact, I could use one of the six analog pins and the demo would still run fine. If you build this setup be sure to try moving the jumper wire from pin 6 to Analog 0. In the Sketch (which I provide in a later step) be sure to change the pin assignment to "A0" and see for yourself.
Depending on what else you have your Arduino doing at the same time, you may find that pins 0, 1, 3, and 11 might not work right. Additionally, Analog pins 2, 3, 4, and 5 shouldn't be used if your using any I2C components.
Ok, you've got the five LEDs in your breadboard, linked to each other, ground, power, and your the signal pin from the Arduino, what next? Your in luck, your almost done, all you have to do is load the sketch and I've done the typing for you.
Step 4: The Code of the LED
The Adafruit library has two specific calls that you need to understand to use these LEDs. The first sets the colors to encode into the signal, and the second actually sends the signal.
Remember that like with most things in programming, you start with ZERO as the first item of the count, so... if I wanted to show a rainbow of colors on my five LEDs, I'd do this:
strip.setPixelColor(0, 255, 0, 0); // Red
strip.setPixelColor(1, 255, 69, 0); // Orange
strip.setPixelColor(2, 255, 255, 0); // Yellow
strip.setPixelColor(3, 0, 255, 0); // Green
strip.setPixelColor(4, 0, 0, 255); // Blue
The four values in the parentheses are: LED#, Red Color, Green Color, and Blue Color. The LED# starts with 0, and makes the use of a For Statement in programs easy. In fact in the example code that comes with the library, all of the calls to the strip.setPixelColor() command are nested in For Statements.
This series of commands would not be visible until you actually send the signal out, and you do that by this simple command:
If you need help figuring out what values to use in your projects, you can start here with standard HTML color codes using the Decimal Code column. Its also a fascinating look at the history of Web Colors and desire to have a consistent result displayed on the vast number of different type of monitors in the world.
Step 5: Showtime!
So, now its time to see these little guys in action! With apologies to Steven Spielberg and without further adieu...
Here's the video.
Step 6: Wrapping It All Together...
Here is the code I've used in my demo. It was very easy to throw this together quickly, and after you spend a little time learning how to talk to the WS2812 chip, all sorts of possibilities open up. From large arrays of LEDs forming an ad-hoc Display, or just a touch of color where you want it, Addressable RGB LEDs really make it easy.
I've tried to keep my code readable, and for that reason I've not made use of arrays of color data, or For statements like in the provided examples with the Adafruit NeoPixel library. This is so that you can see each step easily. I've only touched the tip of the Iceberg here, Adafruit's example code shows you how to fade between colors smoothly, get that chasing 'theater' effect, and more.
I should point out that Adafruit suggests a decoupling capacitor between
the power supply and the LEDs as well as a single current limiting resistor between the Arduino and the first LED's Data In pin, as well as keeping the wiring as short as possible.