Ever wondered how you could sync light effects wirelessly across multiple devices to generate a moving, flexible light show? ‘Sounds pretty neat…’ is what I thought, so I built it! Here’s the report for this flashy distributed systems project.
(Github repo can be found here)
This project is a light installation my good friend Marc Zeman and I built together. Go check out some of his awesome artwork over at zemanseinladen.de)! We participated in a bicycle riders event to raise awareness for bicycle riders and the issue of a lack of bicycle paths in Berlin. Bicycle rider safety is a big issue there. The motto of the event was ‘Lichterfahrt’, which translates to something along the lines of ‘trail of lights’. Every participant was invited to decorate their bicycle with luminating gizmos. We came up with the idea to create something special. A coordinated effect, that would allow us to sync light effect patterns across multiple bikes wirelessly, while driving. I was convinced it could be done, and Marc was immediately sold on the concept.
It was a joint venture that worked out nicely. We split up the work, I was responsible for the design of the control system and for developing the software components for the project. Marc provided the bicycles and LED strips and attached these in pleasing geometric patterns to the frames of the bikes. After some initial research, I laid out how the technical side could work, based on a bunch of Raspberry Pi Zeros. Marc took care of the design of the lights that the system would control and started to equip the bikes with the led strips.
I quickly ordered some Raspberry Pi Zeros to get started on a proof of concept. Development started with a small test rig I designed on my prototype board. Just three LEDs there, enough to test effects and network operation of the Pi Zeros, hooked up with current limiting resistors directly to the Raspberry Pi Zero’s GPIO pins. Apparently Raspberry Pi Zeros were already in high demand, so I had to order at two different shops to get my hands on 4 units.
I also sourced some power MOSFET to take care of switching duties. My plan was to control the MOSFETs using PWM signals on the Raspberry PI GPIOs via the Raspbbery PI Remote GPIO functionality. Activating remote GPIO on a Raspberry Pi basically allows control of its GPIO pin signals via network.
I set up a test rig to design the system and, in particular, get an idea of which effects would look good with three bikes. I kept it simple: 3 LEDs to simulate the actual LED installation (Which Marc was taking care of). All other parts were hooked up as they would be in the actual real bike installation, including the power MOSFETs for switching heavier loads than just three single LEDs.
I had initially planned to use just 3 Raspberry Pi Zeros, with one of them acting as the server/host and two clients. However, that did not work well, and it took me some time until I figured out that the workload for running a flask app and at the sime time controlling the PWM GPIOs via remote GPIO and the GPIO pins of the server itself was too much for the raspberry Pi. I was gettin a lot of stutter and asynchronouse behaviour in the effects.
I therefore decided to use one Raspberry Pi Zero as a dedicated server/host, acting as the Wireless LAN access point and running the Flask application, distributing the signals to three Raspberry Pi Zero clients. Upon booting, the server will start the Flask application, which at startup pings the configured IP addresses of the clients. The light effects are then initialized based on the available number of clients.
The Raspberry Pi zero does not require much current while idling, so a small power bank was enough to power each one of these. A larger power bank was installed in one bicycle to ensure that sufficient capacity was available to power two units in one of the bicycles (server/host + client).
Since we use PWM to control the LEDs, the LEDs aren’t actually on for extended periods of time. This cuts power considerably, depending on the selected effect. My tests showed that small 3000 mAh power banks were sufficient to keep the setup running for a couple of hours.
I designed the system software to work with any number of clients, which I think is pretty cool. You can see that during testing, I hooked up two bicycles when we had the LED installation ready. This is the ‘glimmer overlap’ base-effect on a pretty slow setting. No change of configuration necessary for using just two clients… On startup, the application tries to initialize the configured remote GPIO clients, but if one of the configured IP addresses is not found in the network, then only the available clients are used. All effects are engineered to work with any arbitrary number of clients. We only had three bicycles, but in theory this system could control way more than that. Imagine ten bikes equipped with this installation, lighting up in a quick sequential pattern, random pattern, glimmer…you name it, I programmed a lot of different effects.
I designed a GUI using some jquery elements in the front-end with some sci-fi looking controls. The front-end hooks up to the REST-API of the flask app. I designed this GUI to be optimized for viewing on a smartphone with touch controls!
You can pick a base effect and then control all the parameters (max intensity, attack, decay, width, spacing, …) to customize it to your choosing. There’s some wicked combinations, the possibilities are almost endless as each combination of parameters produces a unique flavor depending on the base-effect. Slow, fast, bright, dull, completely dark, barely on, super bright, synced, sequentially, overlapping….. I also programmed some random modes which produce interesting effects as well. I’m a bit disappointed that we didn’t take the time to capture more video material of some of the different settings.
The front-end GUI features a stop button to stop any running effects, and a bunch of slider controls. You can configure any of the base-effects to your liking, and at any point in time reset the values to the standard settings of the base-effect. This feature ensures that if you’ve drifted off into configuration territory that just doesn’t look pleasing, you can always go back to something pretty at a single click.
Here you can see the bikes in action! We’re being filmed by the third bicycle rider, so you can’t see number three. Theres a hard strobe effect activated, if I recall correctly this is the random strobe effect with a hard cutoff.
In the last clip, you can see the bikes parked next to the river with a glimmering synchronized effect activated. Notice that the on/off interval changes a bit, this is due to the fact that I’m changing the configuration via the GUI on my smartphone while this clip was recorded. There were hundreds of cyclists in the event, but only once did our connection break which meant I had to reboot the server Pi. After about 30 seconds of darkness, we were back online!
I hope you enjoyed this article, that’s it for now - thanks for stopping by!