Here’s details on my Kiwiburn project – a hat with 180 LEDs, all individually controlled… but to be honest, this was my project for Circulation, back in November. Getting it built was easy, getting it to work took quite some time, but I learnt a great deal. So here’s my design for a portable driver for the NeoPixel LED strips.
Why do this? Before making the next Mitochondrion, it was time to learn some new technologies.
The Mitochondrion Mark 4 (my glowstaff) is not too bad – 88 LEDs controlled by an Arduino Nano. However, it might be pretty but it isn’t responsive or interactive. It just splatters photons everywhere, generating randomly-chosen patterns.
I want more than just random brightly coloured lights. I want emotion, narrative depth, and engagement. That requires a far gruntier microcontroller than an 8-bit Arduino. Something like a Teensy 3.0 – ARM Cortex, 32 bit, about fifty times faster, lots more memory, and only 18 mm wide. And LED technology marches ever on, with Adafruit’s Neopixel strips being a big step up. And all of that is pushing me to use lithium batteries, even if they take more looking after than NiMH.
Thus it’s time to step up my technological game for the Mitochondrion Mark 5. The Hat seemed like a simple project that I could use for learning these new technologies – how to use them and what to use them for. Now that the Hat is working, I’m glad I took this step, because trying to get all this to work for the first time in the Mark 5 would be a bugger.
How far can I push existing technology? Quite a long way.
I’m not interested in just making it work. I always want to see how far it can go. If I’m going to put some LEDs on a hat, then how many will fit and how small and light can the whole rig be? Adafruit have their 60 LED per metre strip*. Five rows will comfortably sit as a band on my hat and my head is 36 LEDs around, give or take, so that’s 180 LEDs, three metres worth.
At full whack, 180 LEDs are going to pull 50 Watts, or ten Amps at five Volts. That leads to two design constraints. First, a driver that can supply that much power isn’t going to sit on the hat, so it goes in a box on my belt. Secondly, if the strips can be limited to much less than full whack, then that’s going to make the driver box much smaller.
Design and making a portable LED driver box:
The design for the driver was a constant trade-off between physical size, power capacity, and energy capacity. As ever, I wanted it tiny and bright and long-lasting. Oh, and reliable and safe and affordable and visually complex and controllable. What can I say? I am hard to please.
All of those requirements come down to a power system with a 2S Li-Po battery, XT60 connectors, a resettable fuse for safety, a power switch, a big UBEC to drop the 7.4 battery Volts to 5 Volts for the LEDs with a choke to reduce noise and a big cap for inrush protection, and a separate tiny regulator to supply 5 Volts for the electronics. The microcontroller would read the battery Voltage and cut off power before the battery ran too low. This was a bad idea, but we’ll get to that.
The control system had to be simple and bomb-proof as possible, so that I could operate it at night, by feel, at a festival where I might be, let’s say “tired and emotional“. So, physical power switch, a small and very expensive rotary switch with tactile clicks for selecting modes, and a Teensy 3.0 to generate patterns and run everything.
That all seemed to work well together, on a breadboard at least.
Much head-scratching, cardboard mock-ups, and looking at the Hobby King website followed, but eventually I got it all to fit into a reasonably sized but ugly box. That’s a 1.3 Amp-hour Li-Po, to give me about 10 Watt-hours of energy, a grunty UBEC to give 8 Amps sustained with peaks above that. That can cope with a peak power of all the LEDs running one colour at full brightness and stores enough energy to run the dim modes all night, the bright modes occasionally, and still be able to run the head-lamp mode to get me back to my tent at the end of the night.
The power and mode switches sit at one end, a socket for the cable to the hat go at the other. The end boards promptly broke, so replacements were drawn up in TinkerCAD to fit the switches and sockets then 3D printed by Patrick Herd.
The whole thing
The driver box fits in a leather pouch made by Wendy, which goes on a wide belt from the local army surplus.
Connecting the driver box to the strips on the hat turned out more complicated than expected. I wanted small locking connectors, a durable cable, and enough copper to carry a decent current without getting hot, as the cable generally sits under my clothes. I started with XLR connectors, but they’re huge. I thought about the Fisher or LEMO circular connectors, but they’re eye-wateringly expensive. Ultimately, I settled on mini-XLR. They’re about the size I was after and could cope with the current, just, but I couldn’t find any that could fit onto a decent size cable and clamped firmly onto the cable. So I went with the cheap ones.
The cable worked but after three days the connectors look like:
I doubt that’ll work for much longer. I’ll replace that with a smaller cable and mini-XLR connectors that grip, perhaps the REAN ones.
At the Hat end, the strips are sewn onto tapestry fabric – an open mesh that’s stiff enough to keep them in place but flexible enough to wrap around the hat. Some velcro to keep it round and two safety pins to keep it on the hat. Power and data connections to the strips go through two pieces of vero board, with the five strips running back and forth.
All up, it looks like:
Debugging Neopixel strips – white strips just work (mostly), black strips don’t (mostly):
Testing everything on breadboards showed that everything worked fine. So I built it, with able soldering assistance from Patrick and sewing help from Wendy. It all fitted together, just. And then I turned it on and the strips didn’t work. Or sometimes they did, with much flickering. At this point, in November just before the Circulation festival, there was quite a lot of swearing. So I put the hat to one side, took the Mitochondrion Mark 4 glowstaff and had a good time.
Getting back to it, poking away revealed that putting the cable too close to the big UBEC caused the strips to stop responding to the data from the Teensy, as did using a long cable, touching the cable, or using the 800 kHz mode in the Adafruit NeoPixel library. However, some strips (white ones) worked fine, mostly. The black strips worked barely, if at all The 400 kHz mode was better, mostly, but overall the reliability was terrible. Further poking and scoping revealed the first big problem – the Teensy runs at 3.3 Volts, the strips at 5. So data coming out of the Teensy was only just being recognised by the strips. A level shifter was needed.
Then followed lots of messing about with various different level shifters. I ended up squeezing in a 74HCT245 shifter to translate data from 3.3 to 5 Volts. I’ve also tested a TXS-0102 shifter with good results.
That didn’t fix everything though, so there was futher head-scratching until we finally worked out that (some of) white NeoPixel strips are WS2812, the black strips are WS2812B, and there are some subtle differences required in the timing of the data protocol. Thanks to help from Paul Stoffregen, maker of the Teensy, 1chicagodave, and the Adafruit support team, we got the white strips to be rock solid. If you’re wanting to control NeoPixel strips from a Teensy, then I recommend you read our discussions. The write-up from Hypnocube is also a source of much knowledge on how to use long lengths of these LED strips.
The HappyLEDs software
All of this runs the HappyLEDs library that I’ve been working on for a while. The goal for this library is a flexible framework for controlling interactive and responsive LED perforance tools. It’s getting there.
I spent so long getting the hardware to work that the behaviour and patterns are pretty simple: some simplex noise, some random twinkles, a few dim modes, a few at full brightness, a bright white circle at the front of the hat so it can be a head torch, a random strobe if I need to be as annoying at possible, and a rotating blue light in case I want to make jokes about being a policeman. All of this is controlled off the rotary switch, with priority modes for when the battery is flat or the Teensy gets too hot.
I’ll write up a description of the code when I get it to a state where I’m happy to share it. That’s a pretty high priority for me next, coz I think it’s useful code to run a variety of LED performance equipment.
Mistakes and how to do it better next time:
After all of this, what would I do differently? Four things: a more durable cable, less squeezing of bits, better battery protection, and some waterproofing.
Firstly, I’d use connectors with cable grips, coz whenever I move my head, there’s quite a load on the cable.
Secondly, the driver box is too packed. There isn’t even room for a charging socket, so the battery has to be removed for recharging. I can make more space through putting all the wiring onto a PCB, using a polyfuse instead of the automobile fuse, and using a smaller battery connector. The XT60 connectors are solid, but sized for about 60 Amps. I could get away with much smaller EC2 bullets.
Thirdly, I really should have done a better job of protecting the Li-Po from low Voltages. The plan was for the Teensy to read the battery Voltage (though a divider) and turn everything off when the battery ran down. That’s dumb, for three reasons. Firstly, it’s not reliable enough – currently the Teensy ADC isn’t reading a valid Voltage. I don’t know if that’s a hardware or software problem and it needs debugging, but a tried and tested hardware solution would be more trustworthy. Secondly, turning “everything” off really means only turning off the LEDs. The UBECs and Teensy are still running, so that’s enough of a load to damage a flat Li-Po. Thrdly, it’s bad user interface design. If the power switch is ON but the battery is flat enough that the Teensy isn’t running, then there are no lights and nothing indicating that the battery is still being discharged. Instead, I’ve learnt to put a protection circuit module in everything, even if that limits peak power.
Fourthly, water-proofing. It’s a hat and a light drizzle is enough to stop the NeoPixel data lines from working, if they are unprotected and exposed on my head. I had one night at Kiwiburn where it rained enough to cause flickering.
The social impact of wearing a thousand lumens on your head:
There’s very few pictures of the Hat at Kiwiburn. I could intellectualise this by saying that I prioritise immediate and uncapturable experiences, or I could just say that I was busy running around having fun and not stopping for pics, or I could point out that high contrast levels and rapidly changing brightness don’t make it easy for photographers. Feel free to choose whatever explanation you’re happiest with.
The Mitochondrion glow-staff starts lots of conversations with festival-goers. The Hat, not so much. It gets lots of attention, but it’s actually too bright. People can see it but they can’t see my face and that stops interactions. Hell, on the bright modes it’s too bright to even look at with dark-adapted eyes. Oops.
The dim modes are more bearable, but dropping the brightness to 16 (from the 255 brightness levels) makes it hard to do smooth patterns. One tweak might be to use Micah’s FadeCandy for the software dithering to get more brightness control; another might be to write some patterns that use the full brightness range but have most of the LEDs black to limit the total light output.
Still, it works when people wanted to find me across a dark field full of Kiwiburners, coz I’m the one with the ridiculously bright, colour-changing hat.
* Adafruit now have 144 LED per metre strip. I’ve tried it and hell yeah. With that density of LEDs, it’s starting to change from looking like a row of LEDs to looking like a solid bar of light. I want that. Of course, it also requires ludicrous amounts of power and lots of memory. Hmm…