Rainbow Snake

This post is about a little side-project that I have been working on over the past few years. The project was adorned Rainbow Snake by someone else and we will not go into the details of its namesake today. Instead, let’s talk about the project that kept me awake for a few sleepless months in the hopes that it’d make a few people excited if I handed it to them.

What is it?

I got a little carried away in 2015 and built a large collection of light projects for a desert festival close to where I grew up in Reno, Nevada.

Sorry, not sorry for the (somewhat awful) sound mix, it was 2015 and I regret nothing.

Just about everything broke, although, remarkably, the LED panel at the end of the video, powered by scanlime’s solid-as-bleep fadecandy, returned unscathed. I had a “MacGuiver of a time” repairing things in the field that year. Each project was boutique and had all sorts of one-off hardware bugs. I felt the pangs of being a lazy developer when producing, maintaining, and updating each toy.

Sometimes when playing with one toy I wondered what it’d be like to use the software of another one. Pieces of DNA from the population of toys were cross-pollinated in a chaotic, dusty, copy-pasta on the $300 laptop I bought at Wal-Mart on the drive out because I forgot to pack the one I was supposed to bring that had all my software and curated DJ sets on it. When my friends and I wandered out in the dark, I dreamed of what would be possible if the toys could talk to and interact with each other, maybe even allowing for a means of interacting or communicating.

Inspired, I returned home determined to unify the software stack and build a mesh-networked generic yet flexible interactive device that was focused on light control. I would build interchangeable devices that could be plugged into toys that were just LEDs and optionally power separating that aspect of the design from the smarts. The controller would be the brains and would bring to life any object that participants could create from raw and easy-to-craft-with parts.

I’d recently started learning how to use Espressif MCUs with the Arduino wiring stack and their cheap cost cemented my dream for the project. Part of the dream was being able to signal to everybody around that you needed their attention or that it was time to meet up. Which leads me to the really aspirational part of my dream: I would build 100 of the devices by hand as well as buckets of the prototype building blocks so the parts could readily be incorporated into costumes or improvised toys and would give them away as gifts to let people be creative and interactive.

Building the thing

To accomplish the scale part of the problem, Rainbow Snake would use a 3D-printed enclosure that would exactly fit the ESP8266-based WeMos developer board, available from Alibaba with 3-types of header packages for less than $3. It would adopt the most basic imaginable interface, a single button, that could be sourced in a stackable form to mount atop the WeMos for less than $1.

The WeMos provides a 5v power supply that directly wires to USB with minimal protection making it an unexpectedly powerful source to drive LEDs. You can kinda cheat on power options (e.g. don’t have to build a lipo-charging circuit and power adapter) by using the lipstick batteries that can be found under $15 on Amazon. For the most part, I used the Anker model that consistently had great power and at the time I was able to source it cheaply.

Benchmarking the lipstick batteries

These batteries almost all come equipped with a powerful 18650 battery and a lipo charging circuit — alike the WeMos, some are less careful about regulating power making them a superior source for driving a LEDs. The “brain” would have a single cable coming out of it for connecting to LED strips based on the most common one that ships with APA102 packages sold online. Power would just be the micro-USB cable that comes with the battery and alternatively could come from any USB source. At a BOM cost of around $15, the brain of the snake is a modular design that can be assembled by my RSI-rattled hands in under 10 minutes, it’s just four stacking headers and four JST-wired connections— a competent electrician could do it in less time than I, with her eyes closed.

Believe cuz, everyting in the world is held together by hot glue and zip-ties

The 3D-printed parts for the enclosure can be output at a rate of about 4 per hour on the HIGH-speed setting of my trusty Lulzbot Mini. I operated the machine, later connected to an OctoPrint server (because who leaves their computer on and plugged into things) nearly constantly for the proceeding year. The initial design I adopted for looked something like this:

The bottom was just a box bottom and I hot-glued the two bits together. I later adopted a design that could be swooped together with a ziptie so that you could cut / replace it for repairs or replacing the button module and zip it right back up with a fresh tie that you trim, no glue, yo!

The bottom just meshed up with it:

Everything fit neatly inside and left a little wiggle for that button through the hole. If I was feeling especially paranoid, I could heat-wrap the entire part and add a layer of protection against dust and stuff. You get the gist, basic, easy to assemble, easy to disassemble, interchangeable parts, everything replaceable, everything the same, durable.

The following image shows one of the original prototypes next to the zip-tie model.

Hot snot is all over the place because I don’t like dust in my box

For some reason, the best results printing would happen when the parts were arranged like this:

LED strips could be tested right off the roll (for the most part, I tended to trim the length to avoid over-drain) and I just soldered 4-pin connectors at lengths of about 25 LEDs for the most basic configuration. At this point, I had my hardware prototype and quickly built some inter-device communication on the first few parts off the line:

What you’re seeing in the video is a command getting sent to neighboring devices using AP-AP mesh networking. You can tell it’s succeeding while all of the neighboring devices change to the bounce pattern from the bar LED pattern.

Fun with software

After building twenty or so of the devices, it was time to start experimenting with software and interactions on the device. This required the following things to be possible:

  • Sending commands and notifications to other devices
  • Adjusting the number of LEDs being controlled by the device
  • Controlling the current animation on the device
  • Interrupting or manipulating the current animation with the button for interaction and improvisation
  • ???

The following controls were adapted to allow all of these interactions from a single button:

  • Holding and releasing the button changes the pattern, this is probably the first thing peopled would be interested in while playing with the device and felt like the most discoverable way to implement it.
  • Tapping the button would trigger pattern interactions, e.g. I would add sparkles as done in Mark Kreigson’s FastLed glitter animation to a rainbow animation, would use the time between presses as a BPM trigger, or would seed new colors to other animations.

Although it’s not being triggered by the button press, you can see the sparkle animation interrupting the current animation in the following video:

For the more advanced controls, I added a menu. This menu is triggered by long-pressing the button. To discern between the long and short press, feedback is given to the user in an animation where the lights approach the middle of the LED strand. In the following video, I’m watching the animation for the signal that I’ve pressed the button long enough to trigger the menu.

Rainbow Snake also needed to add another interaction for “moving” through the menu. To do this, you tap the button quickly to “move up” the LED strip or tap slowly to “move down” the LED strip. For example, in the previous video, when I am making a selection in the mode menu, you can see the regions of the currently selected mode change on the strip. In the following demonstration, the same interaction is used to change the number of LEDs in the strip.

Please try and ignore the strange mumbling I’m doing here…

Now that Rainbow Snake had some interactions in place, I started going crazy and pulled in a nice variety of modes for the device including a POV mode borrowed from the 2015 Laser Nunchucks that would make images appear if you spin around the object you created:

Perfectly designed for an audience of one

I field-tested Rainbow Snake for the first time with some friends while camping (the name emerged this night). My friends loved the toys and interacted with them in ways that I had never imagined possible. Seeing other people play with the toy inspired new ideas for me. I felt pretty confident that it was ready for a larger audience.

By the second event I attended that summer, with about two months left in my project timeline (😟), I had built around 70–80 of the brains and 20 or so assorted light fixtures like disks, wands, swords, nunchucks, staffs, and most of all, snakes.

3D-printed enclosures were produced:

I also remixed toys that had nice diffusion:

I introduced the interactions to my friends and they all looked at me like I was from outer space. Nobody but me could wrap their heads around the controls. In particular, people kept getting stuck in the menu system and did not understand the feedback.

Slightly disillusioned, I shared the contraptions with strangers and at least one person was really interested in what I’d created and almost burst into tears when I told them they could keep it. I met another person at the event who was interested in Rainbow Snake and had been working on their own build that was based on Blynk. Blynk lets you use a mobile app that accesses an AP server running on various MCUs like the ESP8266 to adjust the settings on your device. They had an LED array cleanly attached to a top-hat.

After handing out all of the lights to event-goers, I noticed something else: people were shielding themselves from the raw LEDs in the dark environment of some stages. A newly made friend told me frankly, “the lights are tight, but you need a dimmer.”

Don’t worry, as soon as I got home, a dimmer was added to the menu system and the default brightness was brought way down.

How is it the coolest features have to be bolted on at the end?

On the drive home, I was struck again with the lightning of inspiration as I envied the clever iOS app that the top-hat person had crafted. If I was already sending TCP messages for AP-AP communication between devices, why couldn’t I also host a web server and serve a mobile app. With a little luck and GitHub-fu, and I stumbled upon ESP8266 FASTled web server (EFWS) and integrated it into the existing network code. EFWS is an excellently written Arduino app allows you to route HTTP messages to controls on the device. It is served as a single-page app (SPA) which is very clever because the ESP8266 web server is slow at serving lots of large files.

Having a web-based mobile UI opened up a whole lot of interesting possibilities.

First, the phone now can be used to do some of the interactions that required the device UI. For example, you could use the phone to lock the device to a mode freeing the button for click-specific interactions. The new modes added did things like:

  • Click the button to shoot a spray of lights
  • Click the button to add dashes of light
  • Click the button to “chomp” lights from both ends of the strip

Second, precise controls could be added for all of the device configuration:

  • Number of LEDs
  • Brightness of LEDs
  • Select BPM used in patterns
  • Tap BPM (added with help from friends)
  • Pattern selection
  • Color selection for patterns

Third, psst, your phone has hella sensors in it. Even from a mobile app, you can transmit sensor data such as GPS, device orientation, and compass! I added the following capabilities:

  • GPS navigation showing a “warmer” vs “colder” feedback for distance to a recorded GPS position
  • A compass showing, using the LED strip, cardinal directions
  • Tilt your phone to change the LED strip color

All of these interactions are enabled using the available web APIs for sensors and were served in client-side JavaScript in the SPA. Because it’s better on Android for GPS, a native Android app was also authored and published to the Play store.

Sensor data for compass / etc

I also added the ability to communicate over the mesh network using the mobile app. This way, without cell service, we could chat to each other!

The following video shows the mobile app with the “hot / cold” distance to a location:

You get the gist, the sensor bridge actually works!

Wrap it up, already, you talk too much, Gus.

Before running out of time, I made a last-minute call for requests and the only thing that came back was spinnable Poi. I designed some 3d-printable parts (really should have used Ninjaflex) and made some rather dangerous objects that were totally functional Poi — I also added the ability to manipulate the POV Poi patterns from the mobile app:

I also made the “stick-style” poi that would pretty accurately render images on both sides over POV for people daring enough to spin around what’s essentially a bomb attached to tubes of plastic:

I made the shoes you see above, I made tons of stuff.

By the time I ran out of time, I had produced around 150 of the Brains and two large storage buckets full of LEDs.

At the event, people loved Rainbow Snake even if they didn’t understand it. Although few people brought cell phones around with them, I was able to use the mesh network for discovering my group and making other people’s lights blink is a pretty fun party trick.

OK, back to work

I guess that’s all I want to say about Rainbow Snake for now. It’s been a fun project and building large-volumes of LED controllers was a real adventure. I’ve been working on a new version from time-to-time that is built around the ESP32 and that adds a lot more physical hardware controls to the device. It looks like this and I’ve been calling it the mk2:

Jeebus is that backlit arcade button fun to push!!!!

I have loads of ideas for ways that mk2 will be even more interactive and capable than the original; maybe once I am finally settled here in Seattle, things will take off again.

Thanks for reading!