The Tree is Done

A few more hours and a few more tribulations with the Arduino tree project yielded great success. As mentioned last time, I lookeed into building my own audio interface, but after a bit of snooping, found the SparkFun Spectrum Shield that cheaply built what I wanted for an audio interface. In fact, it was actually a great deal better; the Spectrum Shield has stereo input (something I planned to skip), an audio passthrough (so I could plug in speakers, saving me an ungainly additional Y-cable hanging off the end), and runs both channels through MSGEQ7 Spectrum Analyzer chips, providing ready-to-go spectrum analysis and saving me from the pain of getting some kind of audio transform like an FFT coded and working. So, what next?

First, after a week away, I coded up a new display mode with faster cycling of the lights for more of a “twinkle” effect. Then, I tried to connect the Spectrum Shield. About this time, I realized that this shield came without plugs built in for attachment to the Arduino Uno board. Or rather, I’d already realized this (and ordered a set from Amazon), but had not grasped the impact. A quick run to the local Fry’s was in order so that I could snag a soldering iron and spool of solder. Somehow, despite the fact that I haven’t touched soldering equipment in about a decade, I managed to wire things up without frying them, installed the shield, and began my Very Scientific Experimentation* with the audio analyzer chips.

* By Very Scientific Experimentation, I mean that I used Serial.println() to dump spectrum values to the debugger, and then ran the chip for a while with no input, and then again with different songs playing.

Armed with some baseline data, I came to a few conclusions. First, the range of the input was pretty arbitrary, and could swing wildly — I’d need some sort of automatic gain control (AGC) running. Second, there was a hefty DC bias; with no signal at all, I got readings from 50-80 consistently. Finally, the MSGEQ7 has 7 bands, but I only set up 4 PWM-fadable bands, so I collapsed a few together and decided on odd rules for the two digital bands. The bright white twinkling LEDs would be triggered by any single channel going very high, while the color-changing LEDs would be triggered by there generally being a stable, mid-volume signal as evidenced by the sum of all 4 bands. Finally, I would allow the PWM channels to rise very quickly based on the music, but clamped the decay rate to be fairly slow, in order to achieve a more pleasing visual effect. From here, I went on to tweak numbers. Again, this was done in an incredibly unscientific manner; I’d adjust threshold values and gain targets, and then play a few songs to see what I think of the results. I’m pretty sure that by the end of this experimentation, my code quality was suffering, but everything came out… Surprisingly, working quite well, even when things got messier and I started bringing in magic numbers (boo! hiss!), like in my AGC processing.

    if (silent == 0 && silenceLock == 1 && (time - gainTimestamp) > GAIN_TIME_TO_ADJUST)
      float newGain = 128.0 / (float)maxAudio;
      if (newGain != gain)
        gain = 0.8 * gain + 0.2 * newGain;
        gainTimestamp = time;
        maxAudio *= 0.75;

And finally, I added silence/signal detection so that the tree can seamlessly swap from music to rotating pre-programmed effects if no input is applied (and if no mode is explicitly selected with the pushbutton toggle).


I’m relatively happy with the color organ effect now. It responds very well to jazzier songs, or anything with very discrete elements. As mixes get muddier, such as with most rock and harder feels, the fading PWM effect mostly disappears, though there’s still a bit of activity in the twinkling LEDs in particular. Very quiet sections can sometimes inadvertently trigger the 5-second silence detection, and it occasionally has difficulty re-establishing a lock on incoming music (which also requires a 5-second locked period — in retrospect, perhaps the pickup period should have been slightly shorter than the drop period). Overall, though, I’m stunned at the ease with which I could hack together a functioning solution with the tools provided by Arduino. Even if it IS brutish and ugly at times.

Speaking of brutish and ugly, I’m happy to share the code I generated: xmastree.ino — bugs, ugliness, and all.

Behold the Arduino Tree as it responds to MUSIC!

About Tachevert

A cofounder of and full-time geek, Tachevert writes about whatever strikes his fancy. Despite the inherent contradiction, he can often be found videogaming or attempting to run.
This entry was posted in Making and tagged , . Bookmark the permalink.

One Response to "The Tree is Done"

Leave a reply