Optimizing a system to use the least necessary resources is a fun thing to do - and so it the complete opposite, trying to see how complex you can make a seemingly simple task. Like, controlling a few LEDs.

Well, here's Ledmacher: an ATmega328 with some WS2812B LEDs, using the V-USB library to have some basic USB functionality (check out RUDY for more on that), running a bootloader that can flash a new application firmware via USB itself.

On the other end of the USB connection is an Android phone running an app that allows you to configure what colors should be shown along with some additional parameters (how long the color is shown, how many LEDs should be used, and how smooth or fast a gradient transition between the colors should be - oh yeah, it got gradients).

While the app and microcontroller could just communicate via USB to do all that on the fly, it'd be a way too easy solution. Plus, there's still the Raspberry Pi. To be fair though, any Linux device will do here, as long as it can run Python and have an AVR toolchain, but for the sake of throwing extra devices into the equation, let's stick to a Raspberry Pi here.

AVR toolchain? That's right! After setting up the LED configuration via the Android app, it sends it to the Raspberry Pi that runs a simple Python backend to do the whole REST API JSON ladida shebang, triggering to build the actual firmware on the Pi itself. Once built, the app can request some build information and the firmware itself, which the Pi then sends to the Android device.

All that's left is to send the firmware data via USB to the microcontroller's bootloader, which then writes it as new application firmware to its memory, and tadaa, we got some LEDs shining!

Here's a video:

FAQ

Why?

Because why not?  ¯\_(ツ)_/¯

No seriously, why?!

Originally this was a project I implemented during an annual hackathon we had in the company I used to work at, where we gather for a weekend to do some fun nerd stuff. I've done the whole firmware flashing via USB before for my 4chord MIDI project (along with some customizable firmware experiments), and I thought doing so via an Android app would be an interesting option / alternative. Well, starting with the usual Hello World LED Blinking seemed like a nice useless way to play around and familiarize myself with the whole Android USB subject, so here we are.

What's Next?

There's certainly some room for "improvements". Like, the whole Raspberry Pi part could be packed inside a Docker container, or there could be database involved and having a user's history of all their firmwares. And there's definitely a lack of JavaScript to make this a complete full stack of over-engineering. I'll probably take those ideas to some other place where it makes a bit more sense though. Let's see.