Monday, September 30, 2013

Adding some color with NeoPixels

For the traffic light project, I will require different colored LEDs. Rather than going with single color LEDs, I decided to use RGB LEDs. There are a wide variety of RGB LEDs available, but I wanted to try my hand with the popular SMD 5050 RGB LEDs using an integrated WS2812 driver. The marketing term coined by Adafruit for these is NeoPixels, and I learned a great deal about how to work with these from Adafruit's NeoPixel Überguide.
Close up of SMD 5050 showing the integrated WS2812 IC and separate RGB LEDs

The NeoPixels themselves come in a wide variety of form factors, from individual LEDs to being pre-mounted on a board, to long ribbons or chains. I found what I wanted at a significant discount from various eBay sellers and ended up purchasing two kinds: a handful of individually mounted LEDs and a chain of 50 that were covered with a diffuser to soften and disperse the light.


What makes NeoPixels Über-Awesome is that each pixel within a chain of them can be individually addressed by your code. That is, if you have a serial chain of 10 NeoPixels, your code sketch can have the first Pixel light up one color, the second light up another color, and the third... etc. all the way down the chain, all controlled from a single pin from your microcontroller. "Ordinary" RGB LEDs connected to a single pin would all show the same color because the pin would only be able to control the entire chain as a whole. This can lead to some amazing effects even though the wiring is relatively simple. An entire string of NeoPixels requires only three connections: power, ground, and a single wire data/clock channel. (Note that there is a different kind of RGB pixels distinguished by the fact that they require separate pins for the clock and data, in addition to the power and ground lines. You may see reference to the WS2801 driver for these kinds of pixels)

The details of how this is accomplished by the microcontroller are far beyond the scope of this blog post (but explained nicely in this Sparkfun WS2812 Tutorial), but one of the great things about the Arduino community is the existence of publicly available code libraries that do all the hard work of making neat stuff happen. You just have to include the library in your sketch and learn some syntax for how to call the various functions. For these NeoPixels, the go-to library is of course the Adafruit NeoPixel library. This library also includes a good sample sketch called "strandtest" that demonstrates the library functions and this page in the überguide breaks down the strandtest sketch and explains how these functions work.

Over the weekend, I started trying to put together a basic circuit using the long 50 NeoPixel strand. I wired everything up in accordance with the tutorials I found, using a separate power source for the LED strand because the current draw for all 50 LEDs would be significantly more than the Arduino Uno I was using could muster. One tricky part was figuring out how to load the Adafruit NeoPixel library into Codebender. I followed the instructions to do this from a Codebender support page and uploaded the example strandtest sketch to the Arduino and... nothing!

The troublesome part was that there were multiple possibilities for why it wasn't working: perhaps there was a loose connection somewhere, or the power supply wasn't providing enough current or voltage, or I had a wire in the wrong pin, or there was an error in the sketch (though not one that was caught by the compiler). And so I spent a long, frustrating night trying to debug everything to find what was wrong, switching components, testing with the other kind of LED, and finally calling it quits at midnight with nothing to show for the time than a few brief flickers from one LED.

The next day I brought out the big (debugging) guns: a multimeter that a former student had given to me. It's an electronic tinkerer's best friend.
I should have thought of using this the previous night. With the multimeter, I was able to determine that the circuit was fine, all voltages were as they should be, with the exception of the data pin from the Arduino, which wasn't outputting anything. This led me to conclude that there was something wrong with the code, and I began to suspect that it had something to do with the workaround way of including custom external libraries in Codebender. On a hunch, I installed the original Arduino IDE, loaded up the Adafruit NeoPixel library for it, uploaded the strandtest sketch to the Arduino again, and then sat back to enjoy the light show.



Acronym Glossary:
LED - Light Emitting Diode
RGB - Red Green Blue, for the three individual color LEDs that actually make up the RGB LED
SMD - Surface Mounted Device


1 comment:

  1. Very interesting post, Ken, and informative. I bought some neo pixels to use for my next project, but haven't done anything with them yet. I may be coming to you with questions :)

    ReplyDelete