A couple years ago I got into making electronic conferences badges by building a device for DEFCON 25 shaped like a dragonfly. Like all badges the most important design factor was quite literally how flashy it was, and two years ago I delivered on that with ten RGB LEDs. At the time I planned to hand-assemble each and every of the 105 badges at my kitchen table. Given those constraints, and a desire for electrical and programmatic simplicity, I landed on using APA102s (DotStar’s in Adafruit parlance) in the common 5050 sized package. They were easy to place, easy to design with electrically, simple to control, and friendly to a human pick-n-place machine. Though by the end of the production run I had discovered a few problems, the APA102s were a success.
This year I made a new and improved version of the dragonfly, but applying my lessons learned led me to choose a very different LED architecture than 2017. I swapped out the smart LEDs for dumb ones.
When starting a new project I find it’s helpful to to clearly articulate a goal. In the first year the goal was “learn about building more than one of something”, a skill that can be quite a struggle! This year’s goal was “learn how to do things as if I was building a product for real.” Fortunately it turns out I’m not the only one around here who’s interested in that process and I had a lot to learn. To meet that goal the plan was to build 500 badges and get them manufactured and assembled by a real overseas production facility, a process which warranted new design considerations.
Let’s do some quick math. In 2017 each APA102 cost me $0.13 (purchased on eBay) and each unit had 10 of them, so that’s $1.30 in LEDs per badge. Not bad! The LEDs were pretty much the headline feature of the device and it was worth some money to do it right. But this year I obviously needed more LEDs. Last time I was bound by the practical reality of hand placing every LED which put a hard limit on the number of parts per board I was willing to use, but for 2018 I had already decided this wouldn’t be the case. So how many LEDs should I use?
Obviously I should aim for a couple hundred! Well…as you can see in the image on the right a hundred LEDs won’t fit. How many will? After some non-scientific playing with a printed mockup of the design it seemed like with some adjustments maybe around 50 would. There would be plenty of time to tune the number as I went so it was more important to begin estimating than it was to be exactly right at the start. If I used the same of APA102s at the same price (remember, this is a rough estimate) I was looking at about 50 * $0.13 = $6.50 of LEDs per board. Again, for the headline feature, not too bad. But maybe I could do better. Now that adding LEDs was basically free in terms of assembly time I wanted as many as I could get.
What about “dumb” LEDs without controllers? That should be an easy way to save money. A quick skim of DigiKey suggested that while I could get dumb RGB LEDs in a wide variety of packages they weren’t actually inexpensive. The cheapest were about $0.17 a piece in full reels. So I turned to my favorite site on all the internet and began researching. And researching. Even a cursory search showed significantly lower prices and I amassed an extensive table of pinouts, prices, packages and options. As you can see from the highlighted row in the table the part I chose was an astonishing $0.006 each. That’s 0.6 cents per RGB LED. Now we were down to a comical $0.30 of LEDs per board if I could get 50 on there. For the price of three APA102s I could populate an entire badge! But a microcontroller that will directly drive 50 RGB LEDs (or 150 channels) wasn’t going to be practical so I needed to figure out how to control them.
There are lots of ways to drive LEDs. In the past I’ve used a particular 36 channel constant-current LED driver, the IS31FL3236, that I really liked though it was a little expensive at $2.24 in single quantity on DigiKey. That was significantly more than I spent on LEDs alone last year so definitely a no go. Plus it was QFN. But this year with higher quantity and professional assembly things are different. On DigiKey there was a price break conveniently at 500 pieces. (Can you guess why I decided to make that many badges?) This brought the price down to about $1.26 each. Plus, if a machine was doing the solder paste stenciling and part placement I didn’t care that it was QFN – in fact the small size would probably make my design easier! So how do I use a 36 channel driver to drive 150 channels?
First I decided to knock two off my arbitrary RGB LED quantity and aim for 48 LEDs to make a convenient multiple of 12 (as in 12 x 3 channel RGB LEDs). The controllers weren’t too expensive at quantity so the simplest option was to add four controllers to each badge. Using DigiKey prices, that bumps us past a couple more price breaks so each controller would cost a mere $0.95. With this architecture the LED cost per board looked like (48 * $0.006) + (4 * $0.95) = $4.09, a pretty decent savings over the cost with APA102’s! But it seemed wasteful to use so many LED controllers given the plethora of options for LED control. Could it be even better?
It’s a pretty common trick to use persistence of vision to scan a grid of LEDs and trick the human eye into seeing it as all on all at once. Alone a single IS31FL3236 drove each of its pins all the time (it didn’t timeshare) but maybe these two techniques could be mixed together. Each LED was common anode, meaning the high side of each R, G, and B diode was shared giving a convenient way to switch each entire LED on or off at once. I decided to go ahead and make a test board to see if this could work.
I divvied up the LEDs into four groups of 12 LEDs and connected each pin on the LED controller to a single leg of four LEDs (one in each bank). Instead of connecting the anode of each LED directly to a power rail they ran through a PFET. Each bank had a FET so they could be individually switched on and off by the microcontroller. After bodging around my backwards FETs and playing with the timing I got the test board to work, giving me a 12 x 4 RGB matrix driven by a single IS31FL3236 controller and four FETs.
This was the architecture I ended up using for the final product. The only comment of note was how painful the final board layout ended up being. The combination of my naive routing strategy and bank switching topology meant that I had to route each trace to all four corners of my board. This pushed me up to six layers which became another case of a design decision made possible by higher volume — the jump to six layers from four only cost $0.60 per board.
So what was the final cost for LEDs and drivers per board? (48 * $0.006) + $1.26 + (4 * $0.054) = $1.764. A $0.50 premium, and a lot of code complexity, on the original 10 LED design yielded 48 RGB LEDs. After multiple iterations of the LED control state machine I was able to get the buttery smooth fades I was looking for and the final performance was very satisfying. Blinkenlights perfection.