
From 2017 to 2023 I built a custom music-reactive smartphone-connected lighting setup for parties and DJing that costs around $50.
What started as a simple project evolved into a complex system:
- an Arduino microcontroller to control multiple RGB LED strips with hundreds of individually-addressable LEDs
- An implementation of the Fast Fourier Transform algorithm to analyse audio in realtime
- a smartphone interface to change colour modes (including a strobe)
- an OSC server and simple state machine to receive commands from the smartphone
- a multi-threaded Python server to run all of the above
This setup, while built hastily, has proved easily adaptable. I’ve probably hosted close to 50 parties across many different houses with some version of the setup and become very familiar with how it influences the dancefloor. Various modes make its versatile across a variety of moods, from mellow playlists with friends to 100 person ragers with decks and set times.
It also makes for great photography – while a number of shots aren’t lit correctly, the changing hues give plenty of variation when shooting in burst mode.
This post tells the story of how this system came to be. I’ve written this with a semi-technical audience in mind (basic Python and Arduino programming assumed), but feel free to skip architecture descriptions and enjoy the pretty photos!
The source code and instructions for setting it up is at github.com/2700kelvin/music-reactive-party-lights-v1 (open source, AGPL-v3). A warning – this is possibly the worst code I’ve ever written! It’s evolved haphazardly over 6 years, doesn’t have tests and never been refactored (except from the bare minimum to work with Python 3). I typically rushed to implement features in the hours before a party, and prioritised my time to other side projects and hobbies (DJing, for example!). The quality leaves a lot to be desired but perhaps it will help you build a similar setup!
I’ve since started prototyping a low cost Rekordbox Lighting DMX-based system which I also plan to write about sometime. Sign up to my mailing list if you’re interesting to hear more about this new setup (compatible with DDJ-FLX10 and RB-DMX1).
Subscribe to 2700kelvin mailing list
No spam, infrequent emails (only when I make a new blog post).
First prototype (2017)

In 2017 I found myself at Marquee Sydney (I haven’t been much since) and they were handing out these foam LED baton sticks. They’re very simple – 3 LEDs connected in parallel to a coin cell battery in a dancefloor resilient foam stick.

I convinced my mate to help me sneak a few home thinking perhaps I could hack it into some party lights. Ripping out the coin cell batteries I found they were easily controlled by an Arduino microcontroller.
I threw together some of the worst Python code I’ve ever written over a few beers to take sound from my laptop’s microphone and run a Fast Fourier Transform to output the intensity of various frequencies in realtime.
By sending this data over a virtual serial port (over USB) to the microcontroller, I could then instruct the mircrocontroller to control the LED baton based on the data, resulting in music-reactive lights!
Second prototype (2017)
One light was good, but I wanted multiple lights to react to different frequencies.
I quickly figured out these LED sticks went for almost a dollar each online, so I bought a bunch and got to work. Along with a good mate we gutted the coin cell batteries and soldered a number of header pins and some modular interconnecting cables.
By duct taping these LED strips around the walls and roof (the building was in such condition it has been demolished since!) and daisy chaining using our custom connectors we implemented a multi channel lighting setup with almost a dozen sticks.
I also found the microphone audio input took in a lot of “crowd” noise, so I created a virtual soundcard using Soundflower (and later Blackhole on Apple-silicon Macs) and read the audio off the virtual microphone. Setting up the correct audio routing from music programs, DJ software and correct input audio channels in Python was always usually a panicked process before a party!
Third prototype (2017)
I was feeling limited by the static colours of the hardwired LEDs in the foam sticks and looking for more creative control.
Inspired by the stunning Mรถbius strip-like Kepler Pendant by Milan-based Nemo Lighting I spotted at Mondoluce I set out to build a similar fixture. I bought a roll of craft metal wire, a WS2812-based 5 metre individually addressable RGB LED strip (around AU$25) and power supply – while I found it tricky keeping the desired orientation of the flat LED strip attached to the wire structure, I still managed to pull off a continuous and vertically separated concentric circle design!

Fashioning some U-shaped fasteners of the same wire I duct taped the apparatus to the roof (again, this building was in such a state it’s since been demolished!) and ran more power & data cables back to the microcontroller.
I implemented a new rainbow display that varied the hue “angle” as well as brightness intensity resulting in a beautiful effect.
The LED strip was very simple to control with the microcontroller using the Arduino libraries however a much higher baud rate was required to get the required data from the Python program to the microcontroller.
Fourth prototype (2017)
In a previous project I found TouchOSC was a brilliant modular interface builder for designing control interfaces on smartphones. OSC is an event based protocol similar to MIDI, and it can be used to communicate with microcontrollers over a network. I found there were some simple OSC libraries in Python which could easily receive this information.
To add multiple modes I implemented an OSC server which would listen to events from TouchOSC running on a smartphone on the same WiFi network.
I implemented a simple state-machine in Python and a smartphone interface to match. The TouchOSC interface builder is hugely flexible. Modes included static colours, rainbow, pulses of light and strobes!
The OSC server operated on an event-loop based model that updated a rudimentary state-machine while the FFT analysis & serial interface required a very tight loop running at a high frequency so the strobe didn’t flicker – some very average multi-threaded Python code resulted.
Fifth prototype (2018)
I found the strobe mode as a crowd favourite. In an experiment to boost the peak brightness I purchased a number of cheap fairy light strips. With tension applied using bench clips I could crisscross rooms with them (as well as the RGB strip) and some extra code enabled a “house lights” mode. I used a number of transistors on a breadboard to use an external 5V power supply. I only ran this setup at a couple of parties; I found the additional wiring and setup was usually more effort than it was worth (while RGB strips were extremely versatile).


Sixth prototype (2021)
Multiple RGB strips! This required more data, a higher serial baud rate to send this data to the microcontroller, and more bugs.
As I previously mentioned, I typically added features in the hours before a party and debugged a few beers in. By this point the code quality was so low and not bothering to do a rewrite, I wrote a “watchdog” timer that simply restarted the FFT / serial Python thread when it crashed. Problem solved!
Seventh prototype (2021-)
I made a friend who also happened to be building their own custom-programmed lighting control software but in more of a Nanoleaf-style form factor. With permission I grafted the code for his beautiful patterns in as another mode and mapped each Nanoleaf-style fixture in as a section of the LED strip. This resulted in a beautiful pattern which worked especially well after implementing a second 5 metre LED strip!
More photos
This setup has been a joy to experiment with. It’s always fun watching unsuspecting first timers when the lights drop in and abandon their static warm white glow!
I’ve since started prototyping a low cost Rekordbox Lighting DMX-based system which I also plan to write about sometime. Sign up to my mailing list if you’re interesting to hear more about this new setup (compatible with DDJ-FLX10 and RB-DMX1).

Subscribe to 2700kelvin mailing list
No spam, infrequent emails (only when I make a new blog post).