The pop light project is an IoT light and controller that I’m building for my daughter’s bedroom.
It’s a … long term project apparently 😛
I started working on the project about a year ago (late 2019ish). I had been working with electronics, microcontrollers, and fabrication for a while at this point. Nowhere near an expert, but pretty comfortable and confident. That said, I knew that there was a skill that I really wanted to get under my belt; IoT communication.
I’ve built and worked with ReSTful APIs for years and over the previous couple of years I had been introduced and worked a lot with live connections via websockets. Seeing the instantaneous communication via websockets was pretty mind blowing and I wanted to be able to build electronic projects with a similar level of communication speed.
Also, as a solo dev on physical projects I knew that if I wanted to make “big” experiences I needed to figure out ways of giving the impression of large installations with a small footprint. I can’t build a giant interactive wall by myself, but I can build a bunch of smaller interactive items and mount them spread out along a wall to give the impression of a larger installation. To do that and coordinate the activity/communication to and between devices I needed to learn internet of things communication.
So, I did what I tend to do when I need to learn something new: I think of a project I could build to help me learn the new skills in a practical manner. The project idea that I came up with was for the pop lights. The pop light would be an RGB LED light fixture that could be mounted on a wall. I’d pair that with a touch based controller that my daughter could use to control the patterns.
So I sat down and started planning. I had recently started experimenting with the esp32 microcontroller via Adafruit’s huzzah 32 feather so the plan was to base the prototype off of it.
I’d used the huzzah to interface with ReST servers using long polling, but that’s hardly efficient or practical for real-time communication like I got via websockets. While talking through the idea with a friend I was told about the MqTT protocol. MqTT is super interesting, it allows for real time communication via a publish/subscribe pattern and has a tiny data footprint, perfect for (and geared towards) IoT devices.
Also, one of my favorite parts: there’s no custom server code (or very little at least). With websockets you have to manually write server code to orchestrate communication. This is great when you’re doing sophisticated coordination like organizing sockets/clients into specific groupings, intercepting messages at the server level and applying your business logic, determining what sockets/clients should get specific messages based on who they are, etc. But for a lot of microcontroller/microcomputer projects I’ve really just needed a simple relay on the server side to bridge the communication between clients. MqTT is great for this. You can install a broker on the server and have each of your clients subscribe to specific topics. Then clients can publish messages across topics and the broker automatically relays the messages to clients that have explicitly subscribed to those topics. No special coding on the server side. There are tradeoffs but sometimes it’s nice to not have to split your coding and business logic across client and server code.
From there the next step was to plan out and build a light. I wanted to physically emulate an old comic book “pop” illustration feel.
So I hopped in fusion 360, sketched out and extruded a large rough draft case.
Did some rough wiring, and started experimenting with diffusion approaches.
Silmutaniously I stared working through some code examples, identifying tools to help with development (MqTT Explorer is :chef-kiss: amazing), and starting to knit together a rough proof of concept with the code.
I also started to think through the controller I wanted to build for my daughter. I like the idea of physical touch driving electronic projects and I really love the idea of non-traditional buttons, so I decided to get a capactive touch breakout board and build a touch controller.
With the controller working and a rough case for the light together I decided to start refining the code. I had already roughed out a couple of light patterns and triggered them via MqTT from my laptop and now I could trigger them from the touch controller, but I I knew I had a big coding issue to resolve.
The original light pattern code was written based on the NeoPixel library demo code. It’s a great place to start, but it’s all written using blocking code, i.e. with delays. This means once the pattern starts running it will continue running until the pattern is finished, even if we get a message via MqTT to do a different pattern in the mean time. On top of that, there seemed to be message queueing happening while the patterns were running, so once a pattern finished if there were other pattern triggers waiting in the wings those too would fire before any new message triggers came down from the broker.
So the solution was to rewrite all of the light patterns to use state machines instead of blocking code. It was fun converting all of the functions, but my favorite had to be the conversion of the blocking version of the rainbow pattern to run without delay!
I also decided to merge in some ideas from my older sound box project and added touch tones to the controller.
At this point I had the magic bullet (plus some) through the entire process code and communication wise, but I was still not completely happy. The light was great, but it was big. I like the size, but if I want to make a bunch of these for my daughter’s wall a smaller footprint would be nice.
Another issue was getting the electronics mounted into the case without interfering with the LED strips. For the first light I just taped the solderless bread board to the back of the light itself (it’s a prototype, doesn’t need to be fancy), but I knew that needed to be fixed. I also decided to switch from CNC milling to 3D printing which I’m a bit stronger at design and planning wise.
So, I hopped back into Fusion and started ideating.
I still have a ways to go on the design and production, but this feels like a great start!