Holy moly, it's been a while since I've written! Well, it's time to fix that. I've done a lot of out-of-band development and side projects since I've last written, but nothing that I've published until now.
The Problem
For one of my side projects I'm using a Raspberry Pi 3B+ to drive some LEDs. For this particular project, I'm using the DotStar LEDs. They're connected to my Pi via SPI. I soldered some wires to a test strip and have those connected to the SPI0 pins via a JST connector that I've plugged in the Pi's header pins. Adafruit produces some pretty easy to use Python drivers, so programming these LEDs is easy enough. But I want to do more than just set individual LED values. I want to be able to produce and play animations.
I felt like I needed to develop a new library.
Requirements
I specifically wanted to be able to:
- Programmatically create animation sequences
- Serialize animation sequences
- Play animations, preferably on multiple boards, but primarily on the Pi
Easy-peasy. I need some data structures, an interface and/or classes for serialization, and an interface and/or classes for rendering.
Implementation
You can find my implementation on GitHub and find my documentation on Read The Docs. As of right now, it's built on top of Adafruit's Pixelbuf library. Presumably, this library should work with any of their drivers that are built on it. As of this writing, it has only been tested with the DotStar driver.
Examples
The project documentation already covers the specifics, so I figured I'd leave the rest of this blog post for fun examples and some examples of things I've done with this library so far. Here is a link to the Jupyter Notebooks used as of the time of this writing. While the contents of that link will never change, please keep in mind that the library may have evolved by time you see this article.
To run the example notebooks, make sure you have all the stuff you need for your particular LED setup, this library, and jupyter
. If you checkout or download the notebooks, you can cd
to the directory containing the notebooks and run jupyter notebook
in order to start a notebook server. From there, you can run, modify, or create new notebooks and experiments. I find this particularly convenient since my Pi is headless. It gives me an easy way to test and execute code on it.
To test all of this stuff, I've constructed the world's most sophisticated testing rig. It includes some 3d printed feet, a spare DIN rail, a piece of corrugated plastic, and some hot glue. As I'm sure you can tell from the photo, absolutely no mistakes were made and everything is perfectly square and level.
Runway Guard Lights
The full writeup of this one can be found in Programatic Generation of Animations.ipynb
. It mimics the lights that are found at the entrance of runways at larger airports. This isn't exactly what the one that I'm thinking of looks like, but it's close. All it's missing is a fade-in-and-out before wig-wagging.
The color is a bit washed out in the video, but here's my take on that:
Christmas Themed Lights
When putting some of these examples together, it was Thanksgiving weekend. With Chrimbus right around the corner, I thought I'd add my own Christmas animation. The way this works is that to start, it:
- Selects a random color from red, green, or white
- Selects a random brightness for that color
- Selects a random direction for that brightness (brighter or dimmer)
For each pixel, it will make it brighter or dimmer until it "dies" (is as bright or as dim as it can go). For that pixel, the random process repeats. This generates a random-looking animation that can be looped easily without an obvious-looking loop point. It also has an interesting "twinkle" effect.
Too Lazy to Write Something for the Rest
Without further commentary, I'll post the rest of the videos I produced. Each video contains a link back to the exact Jupyter Notebook that produced it, allowing you to do the same thing for fork()
it and do something else interesting. If you wanna talk about it, contact me here.
Happy hacking!
Comments
comments powered by Disqus