Okay, so I have some bad news and some good news.
The bad news is that somewhere between LAX and SFO, the box containing the Blinkenlights prototype and the Glowbek mysteriously disappeared. Despite having my address clearly labelled on the package, it was not found or returned.
The good news is that this gives me all the more reason to step up my game. Glowbek 2.0 won’t be an Arduino and a prototyping board; it will be its own PCB. Blinkenlights 3.0 will be USB-programmable/chargeable and have its own battery. And in the meantime, I had to whip up something for another party, because being a darkwad just doesn’t appeal to me :)
I’ve based a lot of blinkies on the combination of an AVR micro and the tried-and-true WS2811 protocol, and wanted to try something new. I had read about the new(-ish) APA102 LEDs and wanted to see for myself how easy it was to interface with them. I also wanted to try my hand at running lights from something more powerful than the AVR, so I picked myself up a BeagleBone Black, a USB-to-serial adapter, and some APA102 strip from the AliExpress store I usually use.
Having some each of the WS2812 and APA102 strip, I first tried to get LEDscape to work with the WS2812. LEDscape is pretty neat in that it uses one of the BeagleBone’s PRUs to bitbang without the chance of interruption by the OS — the PRUs have DMA, so you can do things like double-buffering with virtually no effort. As it turns out, the hardware requires a decent bit of configuration to get this to work: the GPIO pins on the Beagle need to be configured to grant exclusive access to the PRU. On ARM Linux this is done using device tree overlays (Caution: deep rabbit hole), but for all my looking through the various forks/branches of the codebase, none of them seemed to load on my Beagle. It could have been the fact that mine is running Debian, the kernel version, or anything else; I as of yet have no idea — all I know is that to understand the problem, I’ll probably need to start from the ground up instead of trying to debug something I didn’t write.
I gave up on the WS2812 for the meantime and focused on the APA102, which effectively speak SPI. Well, not “speak”, strictly speaking, but they understand it just fine. The signal being clocked means that they can be driven at a range of speeds without the strict requirement of a realtime controller in a timed loop. This means that writing to them from Linux is as simple as opening the /dev/spidev0.0 “file” and sending it a message from userspace. I found I could clock the line as fast as 60MHz without causing problems (and as slow as 1500KHz without crashing the BeagleBone).
Once I’d laid down the groundwork to talk to the strip, I went to town using OOP, and all the wonderful things that you can do with C++11, and hardware divides, and the generous half-gigabyte of memory the Beagle has (which is to say that I could forget that there’s a limit and just “use lots”), which was a refreshing change from the constraints of C on the AVR. I integrated the “rainbow” HSV->RGB conversion code from FastLED (which is generously under the MIT licence) which made a stunning improvement to the colour generation of my code — more yellows, even colour distribution, brighter primary colours, it’s all there.
The end result looked suspiciously like this LED jacket:
The power source is one of two humongous 6S 2650mAh Li-po batteries which, if my stuff hadn’t evaporated, would have powered run a couple of laser projectors. While running the lasers from the battery for three hours drained them over halfway, the LED jacket used under a quarter of its charge running for four hours. Two differences: firstly, lasers are horrendously inefficient light sources, and secondly, this project used an R/C switching BEC instead of a blingy regulator I found on AliExpress (which I still maintain looks cooler, even if a battery monitor with a buzzer is a better idea).
Meanwhile, let’s hope whoever ended up with my box of tricks knows enough to enjoy its contents :/