Close

Firmware (finally) finalized. blinktronicator offically complete.

A project log for blinktronicator

Sixteen different LED colors on a teeny tiny board.

zakqwyzakqwy 06/12/2016 at 17:110 Comments

I took a ~6-month hiatus from this project, partially because #NeuroBytes has taken up all of my time but mostly because I have trouble getting excited about firmware development. This weekend I spent a day to finalize the firmware and run the boards through their paces, and I'm ready to change the "ongoing" tag to "completed". Yay!

First, a teaser picture designed to pander to our editorial overlords:

above: 1/8s, f/11.0, 35mm lens, iso200, swinging the camera around like a madman.

I also put together a < 3min video describing the four operating modes:

Mode Zero is pretty simple: the left and right buttons cause the selected LED to move back and forth, recycling at the end of the row. The buttons have a rollover function so you can hold 'em down to move between several elements. Everything is displayed at 25% brightness, which seems to be a good balance between blinding the user and not being useful. This is the default mode the blinktronicator reverts to whenever power is cycled.

Mode One is novelty mode, designed to look cool and demonstrate the fading capabilities of the firmware. I've implemented a 6-bit PWM fading routine, which breaks down nicely into a few discrete brightness levels separated by multiples of 4--enough to be obvious to the eye but also compact enough to leave a few LEDs off. This mode pretty much scrolls an array of brightness values, {1,4,16,64,16,4,1} (where 64 represents 100% brightness) through the sixteen elements at a rate controlled by the two buttons. Brightness values could be calculated on the fly using some simple bitwise math, but using a preset array means I can easily tweak individual brightness as needed.

Mode Two (which I confusingly called "Mode Three" in the video) is color mixing/design/utility mode. The right button works as it does in Mode Zero--pressing it once moves the 'cursor' one LED to the right, while holding it down rolls over. The left button allows the user to select four different brightness levels (1, 4, 16, or 64) along with "off" for each LED. This button also rolls over, which serves as a handy reminder of what the mode does as the user's first instinct is often to hold down buttons willy-nilly. I love this mode: you can project the LEDs onto a piece of diffusing paper to see how relative brightness LEDs mix, or just get a feel for how a selection of wavelengths look next to each other. Four discrete brightness levels helps compensate for the relative brightness differences of the elements; for example, the 527nm ("true green") LED is substantially brighter than the adjacent 560nm LED, to the point that comparing them side-to-side is best done with the 560nm LED at brightness level 64 and the 527nm LED at brightness level 4.

Mode Three is persistence-of-vision display mode. To make the refresh rate work right I had to dramatically speed up the program loop for this mode, so to avoid rolling over the mode change I added a separate delay function on the mode select statement to compensate (otherwise it was really hard to get the board to stay in this mode). POV mode just scans through a 2 byte wide array representing an "on" or "off" value for each LED, and sets them to full brightness as needed. Fading doesn't work here as the PWM code isn't nearly fast enough, but it works well enough to display simple images and text. I found experimentally that if I make the array longer than 48 bytes I start to run into memory overflow issues; too bad the 't85 doesn't come in a TSSOP package like the 't45. Now that I think about it, it might be worth redesigning the board to use the 't85 QFN, maybe with a big via on the bottom so you can still hit the ground pad with an iron. I like that blinktronicators are 100% hand-solderable without a reflow setup!

One interesting note: the POV display distortion is caused by the curvature of the LED array. I thought about fixing this in software (by pre-distorting the Jolly Wrencher in the opposite direction) but got lazy. Also, if you build one of these and want to use your own graphics, know that the resistor arrays aren't really spec'd for 100% duty cycle on all LEDs; they get a bit hot if you leave everything on. If nothing else, put a bunch of space between repeating graphics if possible.

Functions include a few designed to read button status using an implementation of Elliot Williams' clever debounce algorithm, along with a few speedy functions to update the various LEDs through the two shift registers. These could probably be rewritten to be more efficient (or at least readable), but I exited the never-ending optimization turnpike once this stuff was fast enough to work for the four modes above.

So that's about it--the blinktronicator is done, the repo is up-to-date (use 'runtime', the other two programs are earlier version that don't do as much), and I'm on to other projects. As I mentioned in the video, Mode Three bears some relevancy to an upcoming project, so .. stay tuned, I guess?

Discussions