Color Control


Overview

The idea for Color Control came from an online video where the creator flashed an LED light strip based on the sound of music. Apartment 401 decided to use an RGB LED light, Raspberry Pi, electronic parts, and a Google Home Mini to achieve a more broad purpose. We completed this project during Berkeley's Cal Hacks 5.0. Unfortunately, we did not submit because the project could not be transported to the judging location.

Goal

Apartment 401 wanted to control an LED light strip with plenty of options using a Flask web application and Google Home.

Solution

In order to control the LED lights, we decided to use a Raspberry Pi (Model 2 B+) for ease of programming. We used the RPi to create a web server, using Flask with Python for our server back-end. For controlling using Google Home, we used IFTTT's Webhooks service to generate GET requests for our website. Our website controller would to use AJAX POST requests upon the selection of buttons to create an interactive, 'clicky', website, which would allow for animation without refreshing the page. We started with a simple Flask server that would handle GET requests. A form that allowed 0-255 R, G, and B input respectively used a submit button to update the page to the same website but with additional HTML paths.

For example:
- /on/#R/#G/#B
- /off
These commands were processed using Flask, and correspondingly output pulse width modulation (PWM) to GPIO pins 23, 24, and 25 respectively for R, G, and B. Our back-end first used the GPIO.PWM module in order to output PWM to these pins. Our LED lights, like most, used a 12V pin and powered R, G, and B by grounding those pins. Our electrical schematic for controlling the lights was this: We also implemented colors instead of RGB values.
The HTML path would now be, for example:
- /on/green
However, the lights looked really off for colors such as orange, where the lights looked nearly white. We balanced the lights by tuning a multiplier for each of R, G, B, such that all colors's RGB values would be multiplied by the proper multiplier. We added the following colors: red, orange, yellow, green, blue, purple, white, aqua.

Our lights now could turn on any of the colors that we had specified. We could ask our Google Home Mini to "Turn the lights red", where 'turn the lights' represented a trigger for the following color keyword ('red'), which IFTTT would process into Our.IP:5000/on/red. We implemented port forwarding on our router, to the Raspberry Pi, in order to control our lights from the internet. The Raspberry Pi would process this GET request, and turn on the proper combination of R, G, and B multiplied by a value.

Our final goal was to implement more features, such as flashing, breathing, and alternating between multiple colors. In attempting to make the lights flash, we attempted to use different libraries in the hopes that they would have a built-in on-off function that used PWM when on. However, after scouring many libraries, it seemed that there was no such functionality that would also extend to breathing and alternating colors. We ended up using pigpio to control our lights. We had to run 'sudo pigpiod' each time we restarted the RPi, but we automated this by adding this command to the boot file for the RPi.

Unable to find a built in way to solve our problem, we tried a different method for flashing - running another Python program in parallel which would do the loop work: a while loop that output PWM and down time as specified. In the main Python script, we would find the process of the other program and kill it in order to break its while loop and regain control of the pins. This method worked! In order to find the side Python program's PID, we searched for a PPID of 1 and a program name of 'python3', which is the only possible program that the side program could be (as the side program would be started within the python3 program running as root). From there, it was straightforward to implement flashing, breathing (increasing and decreasing the brightness according to a sine wave or another waveform), and alternating the lights between different colors with the setting of flashing, breathing, and directly changing from one color to the next. We also gave the user control of high time and low time for all of these functions, where applicable. (Note: without killing the other program, we found, two conflicting commands to the lights seemed to occur simultaneously, which was not desired.)

One of the problems we ran into with keeping our Raspberry Pi on all the time as a server, is that the Raspberry Pi would become unresponsive to server requests after about a day. By replacing our WiFi dongle we were using with an Ethernet cable, this problem was resolved.

To come full circle to what inspired us to do the project in the first place, we wanted to implement sound mode. Currently, this mode responds to sound that the RPi picks up through a microphone, and outputs a corresponding brightness of white light according to volume. We are in the process of working with an electret microphone and high/low/band pass filters in order to separate the sound we hear into bass, treble/alto/soprano, and presence/sparkle signals. These signals would correspond to R, G, and B colors in sound mode. Note: We tested processing the signal from the electret microphone directly. We used Discrete Fourier Transform in order to identify frequencies in our sound. However, it seems that our Raspberry Pi cannot sample analog (using the SPI bus and an MCP3008) at a stable frequency in order to get reliable frequency identification. With physical filters, we can measure power of the signal instead, which only requires high sampling rate and not a stable one.