I’m controlling everything in this project with a Raspberry Pi 2, a system on a chip. Essentially it’s a really tiny Linux computer that you can use for most anything you could use a full-size computer for. It’s just not quite as powerful.
I was afraid, when I first started this project, that I would need to attach an Arduino to the Pi, to use as a slave to control the LEDs. The Adafruit NeoPixels, that I had picked to light the tiki mug shelves, are very sensitive when it comes to the timing of their communication, so if you’re not sending data to them at just the right speed, they won’t show the colors you want them to show (or maybe they won’t light up at all). The Pi, being a modern multitasking computer, might be busy doing something else, and not be able to communicate to the NeoPixels on the schedule it wants. The Arduino, on the other hand, is a real-time microcontroller, which means it can schedule its communications on a real-time clock and communicate at the required speed all day long.
Thankfully, someone much more clever than I figured out a way to drive NeoPixels consistently from the Pi by combining the Pi’s PWM (pulse-width modulation) module with its DMA (direct memory access) module, so that the NeoPixel data signal can be sent without being interrupted by the Pi’s multitasking operating system. The resulting library, rpi_ws281x, was exactly what I needed, and Adafruit’s tutorial on setting it up is killer.
The only thing that’s different in my setup is that I used a different level shifter chip to get from the 3.3V Pi logic level to the 5V logic needed by the NeoPixels. I used a Sparkfun PCA9306 Level Translator Breakout, which was also quite easy to set up. You just need a reference voltage attached on either side of the breakout, and then connect the data wire to each side, and the voltage gets shifted up or down as necessary. Here’s my circuit layout:
Anyway — success!
Surprisingly, the bigger challenge was getting the pixels I already had hung from the air duct to be controlled by the Pi as well. Those LEDs are controlled by older chips, the WS2801, which use a different communications protocol. It should have been just as easy, but I really started looking in the wrong place, and it led me down this path of trying to deconstruct these really convoluted projects that were doing way more than I needed. I’m sure they’re great for the folks who made them, but man, I was way more confused than I needed to be.
Eventually, my salvation came in realizing that the Pi’s Serial Peripheral Interface bus would be the best place to connect these pixels, and a rough test code file from Adafruit pointed me in the right direction. The test code worked great, but the functions didn’t match up with the NeoPixel functions, so I spent a decent chunk of the afternoon writing a new library for the SW2801 Pixels that I’m calling PaleoPixel. (Because they’re older!) That way, once I load both kinds of pixel strips into my eventual master control program, I can issue the same commands to pixels of either type, and they’ll react the same, even though the underlying hardware is different.
Controlling just the PaleoPixels with the Pi, here’s my circuit:
And the latest version of my PaleoPixel code can be found on Github.
The upshot of all of this is now I can get rid of the Arduino entirely, and save both communications overhead and a big chunk of space inside my project box. Now, I just need to control them together… next time!