I'm hoping this will be my last post about the Daft Punk helmets that I made for Halloween. While they were an incredibly fun project to design, build, and program, it has been a fairly draining process. I'm ready to move on to a new project, but first I'd like to wrap this one up.
Before I get into how I controlled the numerous lights embedded in each helmet, I should take a moment to discuss the power requirements. This is one area that I was uncertain about coming from a background of knowing absolutely nothing about electronics. The first problem was what the power source would be. I listed by options and their pros/cons:
After much deliberation I settled on using some LiPo batteries I had sitting around from another project. I had two 3-cell (11.1V nominal) 4500mAh rechargeable batteries and two helmets to power. A perfect match. Unfortunately, all of the LED drivers needed 5V to operate. Since connecting them to the batteries as-is would most definitely end painfully, I needed a way of dropping the voltage from 11.1V to 5V. The beginner electrical engineer in me immediately thought of using the ubiquitous LM7805, a linear voltage regulator set up to drop an input voltage to a steady 5V on output. A quick check with the datasheet for the pinout and I was ready to go.
What does this mean? The datasheet for any electrical component typically provides a large amount of information on how to operate the component, what the standard operating characteristics are, and what the limits of operation are. Above, I've highlighted in appropriately fire-orange the thermal resistance of the component. The units for this are degrees Celsius per Watt, and the quantity describes how much the device will heat up when dissipating some amount of power. Why is this of any concern to me? Well, linear voltage regulators drop the input voltage down to the output voltage while maintaining some amount of current by dissipating the excess power as heat. If you don't understand that last sentence, either I'm explaining it poorly or you should read up on basic electronics (V=IR, P=IV). I prefer to believe the latter.
So how much power will I need to dissipate? I know the voltage drop (6.1V), but what is the current draw? Let's consider the pseudo-worst case where every LED in each helmet is on full brightness, but the LED drivers and other components don't require any power. For the red LED panels, that makes 320 LEDs using 20mA of current each, or 6.4 Amps total. For the RGB LEDs, there are 96 LEDs with three sub-components each drawing 20mA resulting in 5.8 Amps. So in dropping 6.1V while powering every LED, we need to dissipate up to 40 Watts of power (~45% efficiency). Our handy datasheet tells us that the regulator will set up a temperature differential relative to the ambient air temperature of 65 degrees Celsius for every Watt we dissipate. This leaves us with... 2600 degrees. That's hot enough to melt iron. It's also hot enough to completely destroy the regulator, so using a linear voltage regulator is not an option. There is the option to use a heatsink to help dissipate the waste heat more efficiently, and the datasheet helpfully tells us that in that case, we only heat up by 5 degrees C per Watt. This gets us to a toasty 200 degrees C, still too hot to handle. We need another option.
Enter the DC-DC switched-mode regulator. I'm not enough of an expert on these circuits to give an intuitive explanation for how they work, but the end result is a drop in voltage with high efficiency (75-95%). The higher efficiency means we won't be dissipating nearly as much energy as heat compared to the linear regulator. I grabbed a couple cheap step-down converters (a switched-mode regulator that can only step voltages down) from eBay and made two battery packs. Each converter had a small dial for picking the output voltage, so I tuned that to output 5V and glued it in place.
Top: finished battery pack. Bottom: Just the switching regulator.
The rest of the circuitry for each helmet was fairly simple. I used an Arduino Pro Mini 5V in each helmet to control the lights and hooked up a tiny push button to each to provide some basic user input. The LED drivers for the red LED panels needed three data lines connected to the Arduino, and the RGB strips just needed one per strip. With all of this hooked up, the helmets were ready to be programmed.
Before I get into the details of the code, the whole thing can be viewed on my github.
There are a couple steps to thinking about the code for each helmet. I think it's easiest to work out the code from the lowest level to the highest. The first step is figuring out how to talk to the LED drivers. Luckily I had fairly complete drivers in each helmet that handled power, PWM, and had an internal data buffer. The first bit of code I wrote just interfaced with the different drivers. The second step is figuring out how to do an internal data/pixel buffer in each Arduino so that you don't have to compute which LEDs to turn on while attempting to talk to the LED drivers. This causes significant lag, and for the RGB LED drivers, is impossible (more on that later). The third step is deciding how to fill the internal pixel buffers. This is where I get to decide what patterns will show on each helmet, how quickly they update, etc. The code will basically 'draw' an image in the pixel buffer and expect it to be sent out to the LED drivers by whatever code was written for step two. The fourth and final step is writing the overall flow of the code. This is what handles which drawing mode is running, how the push button is dealt with, and how often the pixel buffers and LED drivers should be updated.
While the overall theme of both codes roughly follow these steps, there were differences in implementation for each helmet. I'll go through a few of the key points for each step.
The Silver Helmet (Thomas)
Step 1: The drivers were essentially acting as shift registers with 16 bits of space in each. The first 8 bits were an address and the second 8 bits were the data payload. The addresses 0x01 to 0x08 pointed to the 8 different columns of pixels attached to each driver. Sending a data payload of 0x24 (binary 00100100) with an address of 0x02 would set the third and sixth pixels of the second column on.
Step 2: Since each pixel is either on or off, only a single bit is needed for each pixel. The display was conveniently 8 pixels high, so a single byte for each of the 40 columns was used as the internal buffer.
Step 3: There ended up being 6 possible modes for this helmet. Some displayed text by copying individual characters from memory onto the pixel buffer, while others manipulated each pixel to create a unique effect. Below I have a gif of each mode except the 'blank' mode, which you may guess is not very interesting.
Step 4: The button was coded up as an internal interrupt in the Arduino, so at any point, pressing the button would increment the mode counter. Every few milliseconds, the main loop would allow the code pertaining to the current mode to take a 'step' in modifying the pixel buffer, then the main loop would go ahead and push the pixel buffer out to the LED drivers.
The red pixel near the bottom of the display is not a stuck pixel. It's actually the on-board LED for the Arduino shining through from the backside of the helmet. A few notes on the modes. The Robot/Human mode would actually choose which of those two words to display at random after the previous one had finished scrolling by. The random bytes was done through bit-shifting, byte-swapping, and random bit-flipping. The starfield was boring so I never left it on. The game of Pong actually kept score with itself on the edges and the ball would get faster as the game progressed.
The Gold Helmet (Guy)
Step 1: The LED drivers found on each RGB LED require precise timing in order for them to accept data. Luckily, there is a wonderful library put out by the lovely folks at adafruit that handles this timing. Their library uses hand-tunes Assembly code to ensure the timing is accurate and that the Arduino plays nice with the drivers.
Step 2: The NeoPixel library sets up a pixel buffer on its own, but I decided to also keep one outside the library. Each pixel requires 8 bits of data per color channel and I was using 8 strips of 6 LEDs on each side of the helmet. This is 96 LEDs (288 individual color channels), but I was only interested in having a single color for each strip of 6 LEDs. This limits the number of color values that need to be held in memory to 48. I kept a single array for each color and side (right-red, right-green, ..., left-red, ...), each 8 bytes long.
Step 3: There were only four modes (including a blank one) that I came up with. The gifs are below.
Step 4: Again, the push button acted as an interrupt for the Arduino to switch modes. The main loop stepped forward the appropriate mode and copied my own pixel buffers to the NeoPixel buffers so the data could be sent out.
The Classic Blocks mode was created based on some videos I had seen of other similar helmets in action. I felt it had a nice 90s feel to it. The Cycling Colors mode was copied directly from my Music Box project, but sped up by a few times. The Slow Beat mode used the colors from the Classic mode, but kept them mostly steady with a slow pulsation of the brightness.
With that, the code to drive both helmets had been finished. The LED drivers had been wired to the LEDs; the LEDs had been soldered together; the visors had been tinted and melted into place; the helmets had been painted and glossed, sanded and molded, reinforced with fiberglass and resin; and some pieces of paper had been folded into the shape of two helmets. It had been a hectic but incredibly fun project for the eight weeks it took to get to completion. Not everything went as planned and some of the edges were rougher than intended, but I personally think the end result was well worth the effort. I hope these few posts covering the build progress have been interesting or even useful to you. To wrap this up, here are a few snapshots of the helmets being worn for Halloween 2013: