Friday, June 2, 2017

New Project (Finished too) - LED Music Visualizer

I had built underglow for my computer that was reactive to music about 8 years ago. The system had a number of blue LEDs and would vary the brightness based on the overall volume of the music. I had a low-pass filter integrated into the circuit to make it react preferentially to bass. Unfortunately it has been gracefully failing over the last year to the point where it slowly grows brighter until the LEDs are full brightness all the time. I figured it was time to upgrade to something new and improved and started brainstorming ideas on how to build a new system.

I know significantly more about circuit design, microprocessor programming, and signal processing than I did 8 years ago (thanks engineering degree) and wanted to go digital instead of analog. I noticed over the last few years the WS2812b individually addressable RGB LED has become the go-to for cool LED projects. The LEDs typically come soldered to flexible strips which can be cut to length. RGB data is passed from LED to LED, so the number of LEDs driven by one microprocessor can be huge.

My initial plan was to just remake my original underglow setup with a few strips of the WS2812b LEDs, however I figured that wouldn't take advantage of the LEDs being individually addressable. In the middle of thinking about what to build I found a plugin for my computer's keyboard (it has individually addressable LEDs in the keys) that made the keyboard a music visualizer. It displays the frequency components of the music. With the new inspiration I started to look at "going big or going home" for the new music visualizer.

I started with some blue tape and a tape measure and started figuring out how big my wall mounted visualizer would need to be. As usual the size kept creeping up until I settled on an aspect ratio of 4:1 (left and right speakers each get their own visualizer channel with a 2:1 aspect ratio). To make the visualizer match with my computer setup it needed to be as wide as my monitors (all 3 of them) and the speakers. I ended up with a display area that is 2m wide and 0.5m tall. Strips with various LED densities can be found cheaply on ebay. I decided on the 30 LEDs per meter density. The strips are sold in 5m rolls. I discovered that the rolls were actually made from soldered together 0.5m long segments (no cutting or splicing required if the strips are only 0.5m long). The visualizer would be 15 LEDs tall, and 60 LEDs wide. This also works out to an even number of 6 rolls.

My blue tape outline for the visualizer above my desk. this is where I first realized how big this project was going to become.

I also tried to render a basic visualizer design to see how the grid spacing would look.

Now with the general concept for the visualizer I had to start working out the details. This is also where the numbers got a bit scary for me. Each LED is small and doesn't put out an enormous amount of light. At full brightness on each channel (full bright white light) one of the WS2812b LEDs draws about 60mA at 5V. Easy right? Well... I have a grid of 900 LEDs... A little math now tells me my peak current is more than 50A. That's a lot of current. It's also at 5V, so now I need to worry about voltage drops which could cause LEDs to be dimmer than expected. This means I need to more or less run each strip in parallel with a massive 5V power supply (another quality ebay find).

The 900 LEDs also puts a strain on the processor. The signal requires accurate timing of the high frequency pulses used to transmit the RGB brightness for each LED. I originally looked at using an Arduino since there are nice libraries for driving the WS2812b LEDs already written, but I concluded the Arduino just didn't have enough juice to drive that many LEDs and deal with running an FFT on two channels of audio. Then I came across the Teensy. This uses a significantly more juiced up processor than a typical Arduino. In addition, it has tons of hardware that can lift the difficulty of driving the LEDs from the actual processor. There was a prebuilt library (and breakout board) for the teensy to drive 8 strips of WS2812b LEDs in parallel using the processors DMA (direct memory access) and hardware PWM modules. I also found prebuilt libraries for sampling the audio and running FFTs on the data. These libraries also took advantage of the hardware built into the Teensy's chip to reduce the load and allow more things to be done in parallel on the processor.

One more challenge to add to the project... I had to make everything with hand tools (drill, jigsaw, file, etc...). I don't currently have any machine shop access, so I had to go manual on this. I ended up settling on a wooden frame instead of my typical metal construction. Wood ended up being cheaper than metal, easier to source than metal, and easier to work with than metal.

Here's the frame after making all the 45 degree cuts on a chop saw (I managed to find one I could use) I'm not used to making measurements with a tape measure that end up being the final part size.

I laid out the frame on my plywood sheet to check sizing

I was lazy and cut the plywood with a jigsaw in my living room...

The full frame layout including the board for mounting the LED strips

I went with a black stain on the wood. I've never finished wood before, so I ended up doing a pretty poor job. Oh well... live and learn!

This is after separating half of the strips into their 15 LED (0.5m) segments. Dealing with so many parts is really tedious.

Adhering the strips to the board was extremely time consuming. I tried to make as perfectly square of a grid as possible.

This is right after I finished adhering all the strips down. After a few hours I noticed a number of the strips were starting to peel off the board...

I tried to use gaffers tape to hold the LEDs down to the board. I figured if it is designed to stick to carpet, it should stick to wood.

I was wrong... Gaffers tape did not stay adhered to the wood. Instead it pulled the strips into a tangled adhesive mess. It took me hours to separate each strip from the adhesive roll. This was after attempting to wire some of the strips, so I had to be extra careful to not tear a solder pad off of the strip. I later determined the stain had significantly roughened the surface of the wood. A little bit of sanding and the panel was super smooth, allowing the adhesive to actually stick.

All of the LEDs remounted and stuck to the freshly sanded board really well. I also added some gaffers tape to the outer segments to make sure a single poorly adhered strip wouldn't cause the array to fail. I also finished the wiring for the strips. Every other strip is fed 5V in parallel from the power supply. Adjacent strips are paired and put in series for power. This is equivalent to driving 30 LED (1m) strips off a single 5V supply. I only used PTFE (Teflon) insulated wire. It doesn't melt during soldering and can handle higher amperage compared to wire with other insulation types. It was also much more annoying to strip compared to the usual types of wire I use.

First time powering any of the LEDs (only one of 8 groups)! The visualizer is wired in groups of 8 strips (6 strips at the very ends). The Teensy drives 8 strips in parallel, so I could make the frame rate significantly faster by dividing the number of LEDs evenly between the channels.

After testing each group of strips individually I mated the LED array with the visualizer frame and wired in the signal wires.

First test with the full grid running! Even without full brightness the array is totally blinding.

This is the sketchy ebay power supply I'm using to power the LEDs. It is rated for 70A. I question this rating given the quality of the soldering and component placement (it looks like a kindergartner assembled it). I'll be sure to lock out the visualizer from running all LEDs white at full brightness in the code. This should give a reasonable factor of safety on top of whatever the power supply was "designed" to do. There was no manual for the supply and the labels etched on the side of the supply had some poor translations. I was very careful to not electrocute myself. I checked isolation of the casing, and DC outputs from the 120V line. Eventually this will be totally enclosed and untouchable.

The final array assembly tilted against the wall (before mounting the power supply and processor).

One of my first tests running the FFT visualizer. I only had one color working at the time. I also hadn't mounted any of the electronics to the frame, so it just sat on the floor

Testing out the full rainbow effect on the visualizer. I set it on top of my speakers and tipped it against the wall. I'll mount it to the wall later (and make it centered on the desk).

I still have a few minor details left to complete the visualizer. I still need to add a diffuser to the board, so the led strips and wires are completely hidden. I also need to cover the power supply and other electronics so there is no way to touch the live lines from the wall power. Eventually I'm going to add some bonus features like games on the board (4 player Tetris, snake, pong, helicopter, Pacman, etc..). Since it's so easy to reprogram the processor I can also add new and more interesting visualizers as well.

This might be my favorite project so far. It wasn't the most work or the most complicated. It isn't the highest power output or the most dangerous. However, it is the most aesthetically pleasing. Sometimes I just want to see music and this is a great way to relax and enjoy another aspect of my favorite songs. I might also have to pick up DJing in my free time to share the fun!