Power and output:
For the purposes of shiny toys, LEDs come in two kinds: bright ones and painfully bright ones. The painful ones draw 350 mAmps or more, need fancy constant-current power supplies for each LED and will melt without proper heatsinking. I went for the bright ones that draw 20 mAmps each and only need a resistor to protect them.
I chose the Piranha-style square LEDs, for the brightness and broad spread of the beams (like these ones from Sparkfun. I thought about going for smaller, surface-mountable ones, but chose the through-hole LEDs for shock resistance.
LEDs don’t like to get too hot. However, with four legs going through the circuit board, that ends up as eight different solder joints per LED. I ended up overheating a huge number and buggering up LED after LED. In the end, I resorted to pre-cooling the boards and LEDs in a big tank of dry ice, giving me condensation over the boards and a success rate of only about 80%. Hence there was much reworking of LEDs to get every LED on each light board to work. Sod that for a laugh.
LED drivers – PCA9532
Ooo, these chips are nice. You can use I2C to command sixteen LEDs off each driver, and eight drivers on the I2C bus, so 128 LEDs controlled from two outputs on the microcontroller. I went for forty RGB LEDs, so 120 total LEDS.
The drivers have only two flaws, the slow PWM and the limited number of colours. (Oh, and the I2C bus becoming unresponsive on a regular basis, but I don’t know if that is the LED drivers, the Picaxe, or my home-made circuit boards.)
LEDs are basically either on or off, so to dim them, you turn them on and off rapidly. These drivers switch 150 times per second, which is fast enough if you’re not moving the LEDs around. I am, hence dimmed LEDs just break up into the dotted lines you can see in the top picture.
The second problem is that each driver can handle 16 million colours, theoretically. In practice, each driver output can only be one of four states, on, off, one level of dimming, or a second level of dimming. Those dimming levels can be chosen from 1-254, but there’s only two of them. Hence when you’re running five RGB LEDs from the fifteen outputs on one driver chip, your first LED takes three brightness levels, red, green, and blue. Let’s say we want a random hue and we’re going to push the brightness up as much as we can, coz hey, that’s what we do around here. Let’s say the colour is hot pink, or #FF69B4 in hex. We set the red channel on full, so no PWM, then green at 105/255, and blue at 180/255. That takes up all the dimming levels and we’ve still got four more LEDS to go. For those, we can chose from on, off, 105, or 180 for each of red, green, and blue, giving a choice of sixty-four colours for each LED, but that’s still far from full colour. Fading one RGB LED up while fading another down isn’t going to happen.
(These problems are all solved in the next release of LED drivers from NXP, the PCA9635 has 97kHz PWM and separate dimming for each LED in an even smaller package, with over a hundred drivers on one I2C bus.)
Still, these driver chips are awesome. However, the awesomeness lead to…
Fitting in as many LEDs as I could, which was a mistake
I wanted this to be as fancy as possible. More LEDs equals more fancy, right? The PCA9532 drivers are limited to eight on an I2C bus, with sixteen outputs each. I spent some time trying to run more than one LED off each output (e.g. an LED on each side of the circuit board in series), but in the end, I couldn’t get the layout to work within the space constraints. Instead I went for four light boards, with five RGB LEDs and one driver on each side. Fitting it all into a 21 mm wide board and including all the end-to-end lines took some thought.
Unfortunately, in my quest to fit as much as I could into far too small a space, I didn’t realise that the outputs of the LED drivers were wonderfully designed for controlling four RGB LEDs, not five. This is not awesome.
Each driver has four four byte registers with an output for each byte. Had I gone for four RGB LEDs, then there would have been a direct mapping from LED to register and from colour to bits within that register. I’d have wasted four outputs, but saved myself heaps of code, because the mapping would look like:
Reg1.... Reg2.... Reg3.... Reg4 R1G1B2xx R2G2B2xx R3G3B3xx R4G4B4xx
Instead, I put five RGB LEDs on the sixteen outputs. Only one output wasted, but those five LEDs are spread across four registers like this:
Reg1.... Reg2.... Reg3.... Reg4 R1G1B1R2 G2B2R3G3 B3R4G4B4 R5G5B5XX
The LEDs don’t line up with the register bytes, and the code to detangle this and mapping them across took 70 lines, half the on-chip EEPROM and about 6 milliseconds. Yup, 6 milliseconds to go from “I want this LED to turn on in this colour and this brightness” actually having the instructions for the driver. When you’ve got 40 LEDs, then the worst case scenario is that updates take a quarter of a second. Not good enough for something that’s spinning three times a second.
So rather than remake all the light boards, I just wrote a spreadsheet to detangle everything in advance, then dumped the pre-processed data to the 32 kB EEPROM. Now displaying each frame of an animation just requires the Picaxe to get the bytes from the memory and chuck them straight to the drivers. This can happen faster than the drivers can cope with, so that’s good enough.
Hence patterns get drawn in Excel. There’s support for 8, 16, or 32 frames in each animation. This could be very much better, but isn’t that always the case?
All these LEDs give about 7 W of LEDs and, working from the datasheets, about 600 lumens of light output at full whack. That also pulls over two Amps, so how to power that?
Power and Voltage:
Batteries are a pain in the arse. There’s getting the voltage right, the capacity right, fitting them all in, and then looking after them.
Microcontrollers want 5 V, blue and green LEDs need 3.2 V plus dropout in the drivers and current-limiting resistors. Eight AAA batteries fit into the one-inch tube as two sets of four, but putting NiMH batteries in parallel is a bad, bad thing. So how to choose the system voltage? Much as I’d love to run all the eight cells in series, that would give 12V (or so), so I’d have to either run several LEDs in each string to get a suitable voltage drop, or lose most of the voltage (and the power) in the current-limiting resistors.
Or build constant-current drivers for each LED. I don’t know how I’d fit drivers for one hundred and twenty LEDs into a one-inch tube.
In the end, I plumped for a 5 V system, with the batteries in parallel. This munts the batteries. Turns out it’s also not good for the microcontroller either, but more on that later. They fit in, just. Four AAA cells will squeeze into a one-inch tube with just enough room remaining for: a) one layer of sellotape to hold them in place, b) wiring for the charging, programming, and microphone to squeeze past, and c) a square brass tube that I’ll talk about later. This squeezing does lead to abominations like this picture:
Eight NiMH AAA batteries, 900 mAh each, 8.6 Watt-hours. Given that the whole thing can pull 12 Watts or so, that’s not going to last long on full whack. However, most of the time, most of the LEDs are off. With an average of one colour on full time, the batteries should last over two hours.
After lots of pfaffing about, I’ve learnt an important lesson – LEDs don’t need regulated power, but microcontrollers do. Picaxe microcontrollers like a nice steady 5 Volts, LED driver chips can run down to 2.3 V. Turning on all the LEDs in the same millisecond can drop the battery voltage enough to crash the microcontroller, the same microcontroller that tells the drivers to turn off the LEDs. So many of the early versions had a failure mode that left the microcontroller crashed but LEDs turned on full-whack, until the batteries were shagged.
So, there’s a 5 V, 250 mA power regulator bodged in there, a MAX756. It only runs in step-up mode and when the battery voltage is above 5 V (it can go to 5.8 V under charge), it seems quite happy to sit there and not complain. When the voltage drops, it kicks in and keeps the microcontroller alive. This component is possibly the part that gets the hottest, hence the larger through-hole package for extra cooling, as opposed to a tiny surface-mount. It hasn’t had any heat-related problems, or rather with all the other problems this has, heat-related failures haven’t been noticed.
If I did this all again, I’d be tempted to spend much more time on battery management. For instance, actually having regulating charging and pack balancing would have stopped the batteries geting so munted. Then again, I’m not quite sure how I would fit that into the space that I’ve got.