Introduction: Turned My Bedroom Into a Light Show
I turned my bedroom into a light show / club / meditation room, all with the help of Arduino, WS2812B LEDs, microphone MAX9814, and potentiometer.
This Instructables is organized into four sections:
- What the "light show" does
- Technical summary
- Design process
- Key considerations
Note: The purpose of the last section is to summarize & explain all the technical hurdles I faced, so that other WS2812B hobbyists don't have to face the same issues I did. I recommend skipping to this section if you're just looking for technical tips when debugging issues.
Step 1: The "Light Show"
The main goal of this project is to set the ambiance of my bedroom through lighting. There are three main lighting modes for setting the ambiance:
- Music-reactive mode - for when I BLAST music and want a light show to accompany the vibes. (see videos)
- Normal mode - for when I just want normal yet dope lighting to create a comfortable atmosphere. (see pictures)
- Off mode - for when I want to turn it off. (duh)
Step 2: Technical Summary
- Arduino Uno microcontroller - control all lighting, microphone, and potentiometer signals.
- WS2812B LED strips (5V) - lighting, LED strips are placed all over my room.
- Electret microphone MAX9814 - detect audio & relay signal into Arduino Uno for music-reactive mode.
- 100 kOhm potentiometer - select lighting modes.
- 5V 30A power supply - supply power to everything.
- WS2812B 3-pin connectors - easily connect strips to circuit board.
Software libraries used:
- FastLED library - control lighting & create light patterns.
- Fix_FFT library - split audio signal into frequency bins for music-reactive mode.
See attached files for full EAGLE schematic and code.
Note 1: POOM is my code-name for this project. From a design standpoint, "poom" sounds like "boom" as in when the bass kicks in. This reflects the audio aspect of this project. But the pronunciation "b" sounds too aggressive. The pronunciation "p" sounds more light-hearted, more meditative to reflect the meditative atmosphere this project can create in normal lighting mode. And so we have "poom" :)
Note 2: I know the circuit board & connections are not the cleanest. I actually made a much cleaner circuit board with Arduino Nano and HC-05 Bluetooth module (check the Extras section for picture). Unfortunately, the Nano didn't work, and Bluetooth did not work with FastLED anyways (check Key Considerations section for why that is). For the sake of time, I stuck with what is shown here.
Step 3: Design Process
My design process in making this "light show" work consisted of the following steps:
- Design circuit & draw out schematic.
- Plan LED placement & buy/cut/solder LED strips & wires.
- Calculate power supply requirements & buy power supply.
- Solder circuit & connections.
1. Design circuit & draw out schematic. - I used EAGLE to draw out the circuit, as attached in the POOM_circuit.sch file. The Arduino Uno/Nano, WS2812B LEDs, and potentiometer are supplied with 5V from a 5V power supply. A power switch is placed in the 5V line between the LEDs and the 5V supply to the Arduino to prevent the Arduino from accidentally supplying power to the LEDs and burning up. This is because the Arduino has output current limitations, preventing it from supplying power to >8 WS2812B LEDs. The microphone is supplied by 3.3V from the Arduino. The microphone output is connected to A5 analog input pin on the Arduino. The potentiometer output is to the A1 analog input pin on the Arduino. There are 3 data line signals for the WS2812B LEDs, which are connected to D2, D3, and D6 digital I/O pins on the Arduino. Three data line signals are used instead of one because the digital I/O pin has power limitations, as adding too many parallel connections to one data line can corrupt the data signal (in my experience).
2.Plan LED placement & buy/cut/solder LED strips & wires. - I began this project with two rolls of WS2812B LED strips, rated for 5V. I planned out possible LED placements to create an ambiance for my room. I made rough sketches of my room to plan LED strip placement and wire lengths required (see picture for example of sketch). To test how things looked, I placed the LED strips in multiple spots in my room, with the strips powered by the RF controller & 6A power supply that came with one of the rolls. Several things I took into account when planning placement: 1) I didn't want to see the LED strips directly, so reflecting off the white walls in my room or diffusing the lights with paper looks nice. 2) I didn't want dark corners, so lighting up all/most sides of my room is essential. 3) I needed to minimize the amount of wire length needed.
After planning, I cut and soldered LED strips, wires, and WS2812B 3-pin connectors (see picture). I also created & soldered "connection hubs" that contained a bunch of female WS2812B 3-pin connectors to minimize wiring and keep organized. I had three connections hubs: 1) the main hub for data line 1 power & connections and output connections for data lines 2 and 3 to secondary & third hubs (see picture); 2) secondary hub for data line 2 power & connections and output connections for data line 3 to third hub; 3) third hub for data line 3 power & connections.
3. Calculate power supply requirements & buy power supply. - After cutting LED strips, I counted the number of LEDs and calculate power supply requirements based on the simple formula: Number of LEDs * 0.05 Amps = Total Current in Amps. I used a total of ~300 LEDs, therefore requiring a power supply with >15A. To be safe, I bought a 30A power supply and soldered the necessary connections, as shown in this video.
4. Solder circuit & connections. - Now that I had all the materials, LED strips cut & wired, and connection hubs soldered, I soldered the circuit board containing microphone, potentiometer, and power switch. I used the multimeter to ensure nothing was improperly shorted.
5. Code. - I began by testing each individual function: reading potentiometer output, converting audio signal to lighting effect, and creating lighting effects. Then, I combined everything under a master code. In the next two paragraphs, I'll explain 1) how I organized my final code. 2) the thought/testing process in converting audio signal into lighting effects.
My final code is organized as follows:
- In the initial setup, I define moving average filter values for audio signal processing, pattern lists that lists out all the lighting patterns and modes, FFT frequency bin parameters, and lighting pattern parameters.
- In the main loop, I
- 1) read potentiometer values to select lighting mode to run
- 2) update the hue, which constantly changes over time
- 3) run the lighting mode selected
- 4) relay the lighting data determined by the lighting mode selected to the data lines of the WS2812B LEDs.
- 1) record 256 analogReads of audio signal output
- 2) compute magnitude of frequency bins by performing FFT on the audio signal
- 3) condense 256 frequency bins into 3 frequency bins of low, mid, and high, based on FFT frequency bin parameters.
- 4) perform moving average filtering on low, mid, and high bins.
- 5) trigger corresponding lighting patterns for mid and high bins.
The thought/testing process for converting audio signals into lighting effects is a BIG one. First of all, I needed to understand what I wanted for lighting effects. I decided I wanted big brightness changes for kicks/bass (mid bins) and glittering patterns for higher frequency melodies (high bins). On TOP of that, I decided that, if there's only higher frequency melodies present for a couple seconds, a more meditative, less glittering lighting pattern should accompany the higher frequency melodies (see flowchart picture). In ADDITION, I rotated lighting patterns for mids and highs every 10-16 seconds. To accomplish this, I had to make several technical decisions. As examples, I used a moving average filter to filter out random noise spikes, but I chose smaller windows for low and mid frequency bins to avoid lag between the lighting effect and the kick/bass in the audio signal. I condensed 256 bins into low, mid, and high bins to simplify audio analysis. I only used mid and high frequency bins because it was difficult to create lighting triggers from the audio captured at low bins. Note that all of these stem from MULTIPLE trials and error.
6. Test. - I performed SO MUCH TESTING to determine optimal parameters so that I get the lighting effects I desired.
Step 4: Key Considerations
Here is a summary of technical considerations/hurdles:
- LEDs require large amounts of current/power - This is a common issue within the LED strip world, where not enough power is supplied to the LEDs. A symptom of this is LEDs flashing rapidly on and off. You need a power supply with 1) correct voltage and 2) enough amps. I chose a 5V power supply because the WS2812B LEDs I bought are rated for 5V. I chose a 30A power supply because it supplied enough current for all LEDs. The total current can be calculated as follows: Number of LEDs * 0.05 Amps = Total Current in Amps. This is because each LED draws a maximum of 0.05A. For my setup, I used a total of ~300 LEDs, therefore requiring a power supply with >15A. (Please let me know if my calculations are wrong!!!)
- Voltage drops when too many LEDs in series - This is also a common issue within the LED strip world. Voltage drops can be problematic when too many LEDs are connected in series. A symptom of this is LEDs at the end of the strip turning yellow or dimming when all LEDs are programmed to show white at a constant brightness. If many LEDs in series are needed, inject power in the middle of the strip. Sometimes, turning up the voltage from 5 to ~5.1 V on your power supply (if capable) can help with this. In my experience, having >100 WS2812B LEDs in series can cause this issue. I also turned up the voltage on my power supply from 5 to 5.19 V.
- Data line signal gets corrupted when too many parallel LED strips - Although the data line of WS2812B LEDs does not require significant current, adding multiple parallel connections with too many LEDs can cause the data line to mess up. A symptom of this is LEDs flickering and changing colors randomly and rapidly. In my experience, 1 data line connection from a digital I/O pin on the Arduino can supply at most 3 LED strips in parallel, with each strip having >20 LEDs in series. Disclaimer: I'm just giving my best guess on the cause of this issue because I don't have the proper multimeter to test this, so having someone's input in the comments would be nice!
- FastLED does not work with Bluetooth on Arduino Uno - I really wanted to implement Bluetooth to control lighting and I even made my initial circuit with an HC-05 Bluetooth module. However, deep into the project, I realized the FastLED library removes interrupts, and this corrupts any message received by the Bluetooth module, as SoftwareSerial library requires interrupts. This website provides a TON of info on this issue. In my case, I used a potentiometer as a "Plan B" solution.
- Wire gauge requirements for large currents - Choosing the correct wire gauge is necessary and required by electrical standards to safely handle large currents. Check this table for wire gauge requirements. Note that the lower the gauge number, the thicker the wire and the more current it can handle. Typical wire gauges for WS2812B are 16-18 AWG. If you only have thin wires (say 22 AWG), connecting the wires in parallel also works (in my experience & according to online sources).
- Arduino Uno ADC effect on sampling rate - The fix_fft library allows an audio signal to be divided into a maximum of 256 frequency bins. The bandwidth of each frequency bin is calculated as follows: Arduino ADC sampling rate / 256 bins. In my case, the default Arduino ADC sampling rate was too low, and thus the frequency bins were too wide. To change the ADC sampling rate, I had to change the ADC prescale factor from 128 to 32 to get a sampling rate of ~38 kHz, which resulted in a frequency bin width of ~144 Hz. This factor is accounted in the following formula: Arduino ADC sampling rate = (ADC clock speed of 16MHz / ADC prescale factor) / 13 conversions. The exact change I made is commented in the setup() function of the attached code.
Step 5: Conclusion
The goal of this project was to create an ambiance for my bedroom, and I can tell you from personal experience, it ABSOLUTELY achieved that goal.
The motivation for this project stems from a lot of places, from Youtube videos of people's PC setups, to a night with my friends where we cracked and threw 40 glow sticks in a bedroom and enjoyed the view, to imagining how cool it would be to see lighting respond to the music I produce in real time.
For a future project, I've been thinking about making an LED sleeve that lights up according to your heart beat, detected using PPG. I think this would be a cool (though probably useless) combination of this project and my career interest in medical wearable devices. Would love to hear feedback in the comments!