About me

Music producer, (ex-)DJ, electronics tinkerer, Linux enthusiast and coder.

LED wall control with Raspberry Pi, part 1


My IR camera project has been on hold for a while, because I've come up with other more interesting ideas, such as a LED wall. Initially I was inspired by the Aurora LED wall project, but I've realized that with the power of a Raspberry Pi and some Linux audio magic (PulseAudio and GStreamer) I could do much more.

Here's the Aurora wall in action:


Choosing LED type

Looking at the build details, I'm thinking of using LED strips instead, to avoid a lot of drilling and to keep the wall as thin as possible. There are many types of strips, though, and many of them don't allow individual LED control, so specifically a WS2812B (PDF) or compatible strip is needed.

Each WS2812 LED pixel has a built-in controller chip (WS2811, to be exact), and they pass incoming serial data along to each other. The older WS2801 (PDF) used in the Aurora project is a separate chip that requires a clock signal in addition to data, and strips with them are around three times more expensive, so I decided to go with WS2812.

LED density is an important factor, and I believe a strip with ~3cm spacing will look good without consuming too much power.

Interface electronics

Choosing WS2812 created a problem, though, as it's not compatible with SPI, which would otherwise be the ideal control interface. I want to avoid bit banging, as it'd waste a lot of CPU cycles. I'm a little worried if a Pi Zero W is powerful enough to perform signal processing even without such extra load, but at least I can throw in a Pi 3 without any changes in software, if need arises. Edit: I ran some tests, and a 512-band spectrum analysis at 30fps consumes less than half of the CPU time of a Zero W, so I think I can stop worrying.

Fortunately I found an ingenious little clock shaper circuit that converts a SPI signal into a WS2811/WS2812-compatible one with a single transistor and a few passive components! It just needs some modifications to make the circuit compatible with the 3.3V logic of Pi GPIO.

SPI clock speed must be kept near but not above 800kHz to stay within WS2812B timing limits (a slow signal will turn every LED fully white), and I've read about some problems with CPU throttling affecting the SPI clock, but there seem to be workarounds for recent kernel versions. By the way, there's a handy reference table for adjusting clock frequencies and such.

Audio stuff

I'm thinking of reading audio data from a Ubuntu HTPC running Kodi. PulseAudio makes this easy, because it provides a monitor source for every audio output, and those monitors can be recorded over network. Once PulseAudio is configured for network access, reading the sound output on another computer is easy with GStreamer, for example:

gst-launch-1.0 pulsesrc server=htpc.local device=MONITOR_SOURCE ! autoaudiosink

Change the server hostname to match your environment, and find out the name of your desired MONITOR_SOURCE name with pacmd list-sources | grep name: on the server (usually something like alsa_output.pci-0000_00_1b.0.analog-stereo.monitor). Note that in Raspbian you need these packages installed: gstreamer1.0-tools gstreamer1.0-pulseaudio gstreamer1.0-plugins-good

GStreamer has bindings for several programming languages (I'm planning to use Python) and even provides frequency spectrum data that can be read to provide the numbers for LED visualizations. With this you can check what the data looks like:

gst-launch-1.0 -m pulsesrc server=htpc.local device=MONITOR_SOURCE ! spectrum interval=400000000 bands=10 threshold=-100 ! fakesink

A PulseAudio server can also run on Windows, but it was a pain to configure and lacks zeroconf and other handy features available on Linux platforms, so I'm not even going to try to get this working with Windows.

User interface

My LED wall will be mostly autonomous, but of course it needs a UI to switch between mood lighting, text notifications, visualizations and whatever I'll come up with. As nice as that iPad controller for Aurora looks, I want the user interface to be device-agnostic, so the best choice is a HTTP service, which can even be built within the controller software. I've already written a combined HTTP+WebSocket server in Python, and it will be perfect for this job, as it only loads a single page containing a bunch of JavaScript, which can then receive and send real-time data through a WebSocket connection.

Perhaps I'll also connect a few switches to GPIO pins for changing display modes manually.

What should I call this thing?

Now I just need to come up with a catchy name as I start looking for parts and materials. "The Blast Screen", perhaps?

0 comments:

Post a Comment