Happy New Year! Like many of you I spent the Christmas period enjoying food, drink and the company of friends and family. I also indulged my geeky side and did some experimenting with a Raspberry Pi, an Arduino and an LED light strip. Read on for what I built…
Spoiler Alert, this is what I built:
That’s a 5m RGB LED strip flashing in time to music. The audio is picked up by a USB microphone plugged into a Raspberry Pi. That runs a Python script to perform a FFT on the incoming audio and choose colours, these are then sent over the serial link between the Pi and the Arduino. The Arduino has an “RGB Shield” which can drive the LEDs.
That’s quite a lot to take in. Let’s break it down.
Three weeks ago, I knew nothing about using an Arduino. I owe a debt to those who maintain the Arduino site, as well as dozens of different bloggers and enthusiasts who have shared their knowledge.
I ordered nearly all of this from Amazon (yay Prime!) except the RGB Shield which came from Velleman.
- 5 Meter RGB 60 LED Strip
- Raspberry Pi Model B+ Wifi Bundle
- Arduino Uno
- RGB Shield for Arduino (Kit / Assembled)
- Cheap USB Microphone
This is my third Raspberry Pi – they are fantastically versatile bits of kit. One of mine lives in the office and gives our resident Wookie a voice. (A blog post for another time!)
This is an Arduino Uno.
The banks of pins along each edge are for Power as well as manipulating analogue and digital signals.
The Arduino is pretty clever, but sometimes needs a bit of help to interface with the rest of the world. This is achieved with “Shields” which plug onto the top of the board and provide extra capabilities. In my case, I needed a shield to power and control my LED strip. This is it before being finally put together.
And final assembly – see how the shield pins slot into the main board, and have their own holes for stacking more shields.
The shield contains three LEDs – red, green and blue. These light up along with the signal being sent out of the shield. This is handy for debugging code without hooking up the entire strip since they’ll light just from the power provided over USB – whereas the LED strip needs a boost from a 12v adapter.
Using the Arduino IDE, I loaded this test.
That will blink Red, Green, Blue with a second delay in between, then loop. It’ll do this for as long as it has power. This proved that the Arduino was functioning and that the RGB shield was working. Horrah! I don’t have a shield that allows me to perform sound analysis on the Arduino, so I need a way to tell the Arduino what to do from an external device. This code reads from the Arduino serial port, then sets RGB based on the data it is sent, if it doesn’t receive a command in 30 seconds it’ll turn the LEDs off.
To test this, I knocked up a Powershell script to send the data via the serial port. First I needed to find out what port my USB/Arduino interface appeared as:
PS> System.IO.Ports.SerialPort]::GetPortNames() COM3
Mine is COM3, if yours is different you’ll need to change this line in the script:
$port = new-Object System.IO.Ports.SerialPort COM3,57600,None,8,one
Now you can call it: call it, full red:
PS> ./Write-LED ff0000
The script will understand HTML 3 character short codes, here’s full red, green and blue:
PS> ./Write-LED fff
The Arduino code, and this Powershell script, initialise the COM port at 57600 baud. Since we send 5 bytes to change a colour, we could, theoretically, change the colours 1440 times per second. Having proven the basics in Windows, let’s knock something together in Python on the Pi.
This doesn’t take any parameters, and will just set full red to test the comms work.
To perform audio analysis, we need to make sure the Pi has the ability to configure audio, as well as making sure we’ve got the bits Python needs:
sudo apt-get upgrade sudo apt-get update sudo apt-get install python-dev alsa-utils python-alsaaudio
This script assumes that there is a device capable of capturing audio for us to use in processing:
I had to use the alsamixer tool to fine tune the gain on the microphone, settling on a db gain of 20.00.
This is the first step. The lights currently behave like a crude VU meter, which means that red (mapped to the lowest frequencies) is nearly always on. I’d like to write some code that makes better use of the data to map better colours.
Also, the LEDs currently transition instantly from state to state, I’d like to add some intelligence to the Python code to fade between states depending on the intensity of the audio.