Sunday, November 23, 2014

Large LED Display

Over the summer, I ordered a batch of WS2812B LED strips. Each pixel has a built in controller that lets you address an arbitrary number of points in full RGB with a single data line. Despite running into some small issues, I finally got it completed last week.

Overall, the display has 690(30x23) individually addressable RGB LEDs being controlled by a single BeagleBone Black. The BBB is running Yona Appletree's fork of the LEDscape library which allows for network control of the display. By sending OPC(open pixel control) commands to the BeagleBone over Wifi, any machine on our network can light up the display!

The frame is just spray-painted plywood, with a vertical slot cut for the ends of the LED strips. Because the strips are thin and flexible, I was able to just bend the end through and expose the contacts to the back.

In order to diffuse the super bright point lights into something more smooth, I cut a sheet of plexiglass to the dimensions of the frame and used a "frosted glass" spray can finish in order to give it a diffused coating. In the pictures, it looks like a spotty and uneven coat, but its actually very smooth and does a good job.

Each LED strip from the manufacturer was 60 pixels long. I wanted the display to be 30 LED's long, so that it would fit in the space above our TV. In order to get close to a 4:3 ratio, it had to be 23 pixels tall. Therefore, I cut each of the strips in half and lined them up. In order to get the right vertical spacing between strips so that it'd be a square grid, I placed an extra strip on each side of the board and placed a strip along each LED.

In order to provide power to each strip, I daisy-chained power and ground connections from strip to strip. Each data line would be connected to a custom cape that mounts on top of the board.

Everything before this had run pretty smoothly, but soldering so many point-to-point connections proved to be more frustrating that I anticipated. I didn't have many problems with the power connections because they were on opposite edges of the strip. The data lines in the middle, however, were much harder to solder.

At this point, things stopped going so smoothly. After mounting my custom cape to the BeagleBone, I connected it to power in order to test my code. With a sad flash of light from the onboard LEDs, the board stopped responding and ceased to function.

After replacing the board and thoroughly checking all of the solder joints, I ran the rgb-test code and was greeted by a strobing mass of LEDs, only vaguely reminiscent of the soft rainbow pattern advertised.

My original design had the data lines connected directly to the inputs on the LED strips. Even though the BBB outputs at 3.3V and the strips expect a 5V signal, I found that there was a low enough threshold on the strips for them to function properly. However, as I quickly realized, this "hack" didn't scale very well to a system with many strips. I imagine that each strip had different enough properties while operating out of spec that made this kind of approach not feasible.

I fixed this problem by rewiring my board to include three eight-line 74ACT level shifters. These chips took in the 3.3V signal and output it at 5V, perfect for the LEDs.

After I had finished creating this custom board, which was a huge hassle, RGB-123 started selling a cape functionally identical to mine. I wish I could go back in time and just buy their board instead and save all of the hours I spent soldering and fixing shorts.

The next problem came up when I had to power the board. Given the scale of this project, I knew from the beginning that getting it enough amps at 5V would be difficult. According to the spec sheets for the strips, each pixel takes about 60mA at full brightness and white. With 690 individual LEDs, that comes out to almost 42 amps! Thankfully I had no desire to actually run them at their absurd max brightness.

I preformed my own test at a dimmer brightness and measured closer to 40mA per LED. Given that my Wifi module for the BeagleBone starts failing at less than 1A of current, I assumed that the entire board with Wifi consumed about 1.5-2A. Altogether, that comes out to 28A at my dimmer use case.

While testing out the board, I was using a temporary 10A power supply. Although it still functioned, the power supply began to over heat and eventually burnt itself out. At that point, I began shopping for a more permanent solution and found a 40A 5V power supply on Amazon. At first, I was a bit intimidated by the cordless form factor. With this kind of device, you need to splice in your own power supply cord and screw the three lines into a covered terminal. Even though it was a very simple setup, it was my first time working with high-voltage AC power.

Once I confirmed that the power supply was functional with my multimeter, I mounted it the the back of the display and connected it to my circuit. After running another test, I noticed that some of the strips were flickering again. After checking the voltage across the LED strips, I measured only about 4V, one full volt less than spec. I also felt the DC outputs lines coming out of the power supply and noticed that they were warm to the touch. Now that I was running more current to the display, the wires carrying it were introducing a significant voltage drop. Once I put redundant lines in parallel to reduce the resistance, their voltage drop was within acceptable levels.

Unfortunately, there were still two other sources of the flickering lights that I hadn't yet discovered. I put the project on the shelf for a few weeks while pondering the signal disruption.

Later, while checking the display, I noticed that the flickering only existed in certain orientations. While the board was placed vertically, some the lines behaved. When the board was horizontal, the same lines would flicker uncontrollably. I narrowed this problem down by applying pressure to the problem lines and found that they worked only while being pressed down.

After doing some tests on the connections, I noticed that the solder pads had actually been lifted slightly, making their connection across the flexible PCB inconsistent! I'm not sure what exactly could've caused this break, but I can guess that it was some combination of my obsessive soldering and resoldering while trying to fix the lines and the lines being bent at the ends to be accessible. I solved the breaks by simply skipping the solder pads and connecting the data line directly to the exposed terminal on the LED chip.

Finally, while researching for another project with the same strips, I realized that the author recommended putting a small 220 Ohm resistor in line with the data signal in order to smooth out the transmission. After inserting resistors into the remaining problem strips, all of the flickering resolved and the display was smooth and responsive!

In review, I encountered five different problems that caused flickering in my display. To anyone else working with these LEDs, I recommend that they follow this checklist to make sure they get good, reliable behavior.

Make sure that the data signal is at 5V. If you have to translate from a different voltage, make sure you use the right level shifter. For translating from 3.3V microcontrollers, 74ACT series chips work well.

Make sure that the strips are getting enough current and voltage. If your voltage drops too low, you'll see flickering. If you aren't providing enough current, the LEDs will be a bit dimmer and your power supply may burn out. Each LED on full white brightness pulls about 60mA, although more reserved use will only pull about 40mA.

Check your solder connections to the data lines, especially if the LEDS behave in some positions and orientations, but fail in others. Also be sure to check for lifted solder pads if you've been bending or resoldering the lines a lot.

Place a small(220 Ohm) resistor in series with your data signal in order to smooth your transmission.

Its also worth noting that you may get good behavior while operating outside of these parameters-- I did during my initial tests. However, if you're operating outside of the recommended procedures and your solution will probably fail when scaled up to different hardware with slight inconsistencies from manufacturing.

Does anybody else have similar tips for getting these strips to work? If I had the experience then that I do now, I could've saved a lot of time hunting down odd problems.

UPDATE 12/20/14:

After all of our neighbors started putting up their lights for Christmas, I wanted to do something special as well. I modified my code for Conway's Game of Life a bit so that each new cell was initialized to either green or red. I also made it reinitialize after 200 iterations, and wrote cron jobs to start and stop it each night.

I took a potato quality video of it running from my front porch. I apologize about the quality, but I can't do much better at the moment.