Controlling an LED strip with Arduino
Controlling an LED Strip with Arduino and Processing
The Idea
When my San Francisco roommate, Aubrey Wahl, (who took the above photo) bought a strip of LED lights like this to decorate our otherwise overly-normal-looking home, the first thing I noticed was that the pins that connected the LEDs themselves to the controller box looked like they would fit in my breadboard. A lot of my projects start with the realization that two things look like they might fit together, actually...
The original controller can receive input from a small remote control and can change the colors of the lights or manipulate them in pre-set patterns. If I could control the lights with my Arduino, I figured that I could make the strip do something cooler, though exactly what I wanted it to do was not immediately obvious.
I decided to break the project into three parts:
- Figure out how to control the RBG value of the strip (it's all one circuit so the strip must always be one solid color) from the Arduino.
- Have the Arduino read the desired RGB value from a computer over a serial connection, essentially allowing the computer to control the LEDs. This modular approach allowed me to mess around with the lights using just to computer, without having to re-upload my program to the Arduino over-and-over again.
- Think of something cool for the computer to do to the LEDs. I eventually settled on trying to have the LEDs react to sounds, including spoken word and music. I had the computer analyze ambient sound with a FFT and turn the results into an RGB value for the Arduino.
The Result
Here is the end product. This is a video of my roommate and I grooving to an XXYYXX song. The lighting in the room is controlled entirely by the computer picking up and reacting to the music with its mic. There is no software connection to the device playing the music.
You can see that the LEDs are pretty good at reacting to the beat, which made this device pretty fun at parties. The color changes are a little less predictable, since the very simple FFT-based analysis is not really sufficient to capture to essence of a musical phrase-change, but no one complained because the beat-following worked so well, and the color unpredictability was rather fun.
The Arduino and Circuit
The circuit: (I wised-up after this and starting supporting real Arduino. Forgive me.)
I won't talk about the circuit too much, since I basically borrowed the design from Adafruit. Instead here are some fast facts I learned:
- Power transistors and pulse-width modulation are a powerful combination! With one 5V pin, you can control the 0-255 intensity of red, green, or blue on the 12V LED circuit by basically using the transistor to flip on and off the 12V supply fast enough that our eye interprets the result as, for example, 128/255 brightness.
- The Arduino gets its instructions from the computer by reading a single byte. Depending on which pre-defined range the numerical value of the byte falls into, the Arduino understanding it as containing a change to the red, green, or blue values, or a fourth, additional modification of overall brightness (not really necessary, but it made tinkering easier). I sacrificed some precision, both because of byte-loss and because there wasn't enough info to represent full 0-255^3 detail, but it was really fast, which made the system more responsive. Totally worth it.
The Computer
The computer runs a simple Processing script, which is fun because anyone can walk over and play with the parameters. Check out the repo.
Basically, the code runs a FFT (fast Fourier transform) on incoming sound, and then aggregates the waveform breakdown into experimentally determined bins. The size of the lower (bass) bin affects the proportion of red light, mid controls green, and treble controls blue. The idea is that at least some shifts in some songs are marked by big shifts in these three bands (bass drop, high instrument comes in, etc.). In practice, songs are so complex and there is so much noise pollution that it's never this simple. The color would change rapidly, which was unsettling, and it seemed to be nearly uncorrelated to the song.
I fixed this by introducing a continuously-normalizing factor for each color. No matter what sound is playing, if it remains unchanged the color will slowly regress to white, as each bands "baseline" adjusts to the current level. This allowed the device to pick up on many more musically-relevant shifts. Since it's always comparing the level to the moving average level, it's way easier for it to notice a bass-drop, for instance. It also introduced some randomness, since the function now had some "memory" its output was dependent on what it heard for the past x seconds. Is the song shifting a lot? Did you say something to your friend 15 seconds ago? That will affect the lights. So, they still missed some pretty obvious musical shifts, but they looked a lot smoother and sometimes lined up pretty well.
I also introduced the overall brightness parameter I mentioned earlier. This bypassed the FFT and was just a function of continuously-normalizing sound intensity. Since I wasn't trying to decompose the sound wave, it was a lot more consistent at reacting to obvious changes in volume only. So, the lights would flash to the beat or dazzle you when the singer came in, which was great, even as they were somewhat-randomly shifting colors.
Conclusion
My roommate and I took this system to a party with us, thinking we would be the coolest guys there. Instead, we were the guys that brought a computer to a party, and people were too weirded out to really get into playing with the system. Understandable.
In the end, we taped up the lights in the kitchen, where they flashed along with normal conversation, bluegrass-band practices, and pop music at small gatherings. They were really fun to have around until some moron stuck his laptop charger into the Arduino thinking it was the 12V power supply and the circuit caught on fire. The LEDs were actually unharmed thanks to the power-transistor setup, but my roommate decided to protect his original purchase by taking away my mad-scientist privileges.