An Adventure with Raspberry Pi, NeoPixels, and Audio Programming

This post is part of a series in which I’ve been sharing some of my projects and experiences at Hacker School.

About two weeks ago, I set out to create a Spectrum Analyzer on Raspberry Pi. My intention was to learn a bit about using a Raspberry Pi to drive LED based visualizations, learn more about Audio Programming, and as a bonus end up with something that would be a fun contribution to a party some of us Hacker Schoolers had been planning for the new batch.

As it turned out, another Hacker Schooler, Puneeth, was interested in building something similar. So we joined up to collaborate on the project.

We started by following a guide on Adafruit. The initial setup of the Pi and configuration of the hardware went well. Along the way, we ran a few tests and experimented with some of the libraries to verify that the LEDs would respond to appropriate commands. Then, after completing the final steps, we were ready to see the Spectrum Analyzer in action.

Excited to see it for the first time, we typed in the run command and pressed enter …. nothing.

After spending some time re-checking the instructions and tracing back our steps, we decided to dig into the code. It was quite a mess and we soon found that there were some good reasons why it was not working. Perhaps the guide was written for a different version of the libraries, in any case, we decided to create our own versions of some pieces and refactor others.

This was a fantastic way to learn. We tore apart chunks of code, re-wrote others, and experimented with new approaches along the way. Puneeth is a fantastic Python developer with impressive work ethic. At several points we would reach a stopping point at the end of the day and discuss next steps. When we started again in the morning, Puneeth would say, “oh, I decided to work some more last night and already implemented that feature.” Sweet!

By the end of a few days we had a basic version working pretty well.

First version of Spectrum Analyzer with 32 LEDs wrapped around to create 3 columns.

For the first version, we used the same LEDs as shown in the Adafuit guide (LPD8806). We were able to get them to update at 16Hz which looked pretty smooth. For the party, another Hacker Schooler offered to loan us set of 100 LEDs with a different chipset (WS2801) so that we could create a larger display.

This led us to our next challenge of adding support for multiple NeoPixel chipsets with slightly different timing and input requirements. We wrote a new driver for the WS2801 and ended up with 12 columns each 8 LEDs tall.

Here is a short video showing our initial prototype with the WS2801 LEDs.

The other change we wanted to make for the party, was to support additional types of audio input. Initially, we planned to stream audio via Apple AirPlay. To support that feature, we integrated with a library called Shairport for Raspberry Pi.

Then, while setting up for the party, we found that it would also be helpful to plug an audio line directly into the Pi. Although adding this feature initally seemed trivial, it ended up being one of the most challenging parts of the project. The reason is that the audio line was not clean. It had some static noise on it that was distorting the visualization. We’re still working on ways to filter the noise and make it support the direct audio input use case better.

As a final touch, we mounted the LEDs on foam board and covered with a translucent paper to diffuse the light.

Below is a video showing the final result.

If you are interested in reviewing the code, we’ve posted it on GitHub and plan to clean it up a bit over the next week.