The Mitochondrion 3.5 – An Excessive Glowstaff (4 of 8)

Power and output:


Photo by Loki Gash for Filament Magazine

LEDs

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.

Never again.

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:

Power budget

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.

Regulated power

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.

7 thoughts on “The Mitochondrion 3.5 – An Excessive Glowstaff (4 of 8)”

  1. Why is mounting NiMh in parallel a bad thing? Other than “it munts the batteries”.

    And, yes, 6ms to do a couple of barrel rotates and an add or two is sh!te. Next time the doctor prescribes C and a big cup of HTFU.

    1. Coz the weakest battery takes all the load, so rapidly gets over-discharged. Then it takes all the charge, so rapidly gets over-charged, while the rest just sit there looking bored.

      Next time around, it’ll be one bit string of batteries all in series, so they all have to behave. This does mean squeezing in a big DC-DC “lots of Volts” => five Volts converter, and I do mean squeezing.

      And C, glorious C, so that computation can happen in less than a week. No HTFU thou, not enough room left after that DC-DC converter.

  2. Dot, dot, dash, dash

    I really like the “headline” picture on this post. If you hadn’t told us that the “dotted” lines were an artefact of “too slow” PWM, then I’d have assumed that it was being done deliberately to generate beautiful photographic trails (the eyes blur things together too much for it to really work there, but cameras can help make it more visible). Accidental discoveries, and all.

    FWIW, pre-rendering data for microprocessors is not only not “cheating”, it’s pretty much the only sane way to do a whole bunch of things. You call it, eg, “compiling” or “pre-rendering”, and if you’re particularly Computer Science(tm)-y about it, you invent a custom language and compiler tool for it. But it’s definitely a very traditional time/space tradeoff. Given enough ROM space it occurs to me that you could pre-render larger runs of patterns, and output it a lot faster with a(n off-CPU) shift register driving part of the ROM address — and treat the microprocessor solely as “system supervisor”. This too is a long standing trick. Famously Woz used a variation on this trick in the Apple II design, for video output. (And most of the “character generators” in early terminals, microcomputers, etc, used the same trick.) It’s just that now you really can have a couple of MB of ROM and go all the way to the “space” end of the time/space tradeoff. (Pre-rendering has also long been used for audio output, particularly where it doesn’t need to be real time adjustable.)

    Ewen

  3. Looking at the boards, coupled with your comments about power issues, it looks like there’s not a lot of power supply decoupling going on. One of the lessons I learnt on the NTP server was the importance of power decoupling caps to smooth out peaks in demand without needing to worry so much about full-on regulation.

    The rule of thumb I use is 100nF cap close to every VCC pin, and ensure it’s directly routed to it. 100nF is not the perfect solution in every case, but it it does seem very important to ensure *every* VCC pin has such a decoupling cap.

    The other thing to consider is how to fail-safe the MCU if it doesn’t have brown-out detection. A reset-supervisor is probably the ticket here, they’ll force the MCU into reset by driving !RESET low .. can also wire those into any other chips with useful !RESET lines. A reset supervisor isn’t huge either, you can get them down to SOT-23 packages.

    1. I’m going for full-on power regulation in the next version, with separate DC-DC converters for the LED strips and the microcontroller. There’s nothing more grunty/noisy than some 20 mA LEDs on the microcontroller side of things, so I’m hoping that the power should be fairly stable. But if not, how do I go about working out what size caps I need and where to put them?

      I’m planning to do the imminent brown-out detection in software, with the Arduino directly reading the battery voltage via a voltage divider. Obviously, this only works if it hasn’t browned-out yet.

      1. Even with fully regulated supplies it’s still mandatory to have decoupling caps. The problems I had were with LDO regulators (which are actually *less* noisy than anything switch-mode, at the cost of efficiency). Anything digital will expect it’s supply to be very very stable.

        For size of caps, I have no answers. 100nF at least for every VCC pin is what I see crop up in a multitude of datasheets. I figure if they expect more they’d say so, was the case with the GPS chips I used which suggested more and how to arrange it. Placement should generally be as close to each VCC pin on an IC as physically possible and directly connected.

        If you’re going to use an Arduino then you get brown-out detection for free – the AVR MEGA implements it internally and (once you set the BOD fuses) will ensure it’s hard reset if the power drops below the configured threshold and come out into a sane state on return. (You can also detect this case – there is a register you can check for what caused us to go into reset.)

        Means that you should have only very brief periods where the LED drivers are stuck, assuming you don’t have some other !RESET control on them.

Leave a Reply

Your email address will not be published. Required fields are marked *