Raspberry Pi Lights: how to sync Christmas lights to midi audio

**UPDATE**

Check out Todd Gile’s project which uses the Raspberry Pi to sync mp3 audio by way of real time sampling! It’s really an awesome project, and if you want to use mp3 instead of midi, you should definitely check it out. https://bitbucket.org/togiles/lightshowpi

**UPDATE**

I’m recommending the use of the SAINSMART mechanical relays instead of the solid state ones I was originally using. There have been some reports that the PI does not have enough amperage to drive the solid state relays in some cases.

This post will show you the details of my Raspberry Pi powered synchronized Christmas lights project.  I really enjoyed working on this and I wanted to share it with anyone interested in this sort of thing.

It’s fun to begin at the end, so here is a video of the Pi Lights playing to Star Wars.

Also, the Peanuts theme song:

Theory of operation:

Untitled drawing

First, a Midi file is fed into Linux’s ALSA midi sequencer service, destined to be played on a particular port.  The sequencer then broadcasts accurately timed midi events to all programs subscribed to said port.  One of those programs is Timidity, which is a free midi synthesizer that will take care of playing the sound.  The other is a simple C program that I wrote to  control the GPIO pins based on midi events.  Each GPIO pin controls a solid state relay, which ultimately toggles the main electricity  going to each bank of  lights.

Materials required:

1 Raspberry Pi and case

612WbLY1UCL._SL1500_

SainSmart 8-Channel 5V Solid State Relay Module Board  (30$ on amazon.com)

Female to male jumpers

Cooper Wiring Devices 15-Amp White Duplex Electrical Outlet

6 Electrical outlets ( < $1 US  each)

CARLON 2-Gang Plastic Old Work Electrical Box 2-Gang Almond Standard Duplex Receptacle Plastic Wall Plate 2-Gang Light Almond Blank Nylon Wall Plate

3 Electrical boxes and cover plates  (prices vary)

 50' 14 AWG Non-Metallic Wire

50 feet of Electrical cable of appropriate gauge

IDEAL 50-Count 1/2-in Plastic Insulated Staples

A bag of electrical cable staples

Plytanium 15/32 x 4 x 8 Pine Sheathing Plywood

Enough Plywood to build a ~24″/12″/24″ box

Product Details

A small amplifier (~$20 amazon):

PYLE PLMR24 3.5-Inch 200 Watt 3-Way Weather Proof Mini Box Speaker System (White)

Outdoor speakers: (~$20 amazon )

Software needed:

Debian Rapsberry Pi distro  (http://www.raspberrypi.org/downloads)

Timidity (apt-get install timidity)

Alsa devel libraries (http://www.alsa-project.org/main/index.php/Main_Page)

Gordon’s wiringPi library (https://projects.drogon.net/raspberry-pi/wiringpi/)

About Midi Files:

Midi files are comprised of a sequence of events that richly describe how to play a song.  There are many different kinds of events, but the most interesting ones for my purposes are the NOTE ON and NOTE OFF events.

NOTE ON event {

Note value: { 0..127 }

Channel { 0..15 }

}

NOTE OFF event {

Channel { 0..15 }

}

Think of the note value part of the NOTE ON event as corresponding to key on an imaginary piano that has 128 keys.

Controlling the GPIO pins based on midi events:

I decided to control the pins based on the pitch of the notes.  There are 12 notes in an octave, so the pitch is obtained by taking modulus 12 on the note value.  From there, it’s again divided among the number of pins.  Using 6 pins, pin 0 corresponds to notes with pitch 0-2, pin 1 corresponds to 2-4, etc.

Getting Started – Software:

The first thing to do is download Timidity and make sure midi playback works properly.  After installing, configure it to run as a daemon.  Then use the ‘aconnect -o’ command to verify that it is listening on a midi port.  It should display something like this:

client 14: ‘Midi Through’ [type=kernel]
0 ‘Midi Through Port-0′

client 128: ‘TiMidity’ [type=user]
0 ‘TiMidity port 0 ‘

Try playing a midi file using the ‘aplaymidi’ command.  For example, ‘aplaymidi –port 128 yourMidiFile.mid’.

It’s probably the case that the default Timidity settings will be too aggressive for the Raspberry Pi to handle.  The midi playback may stutter and crackle.  To remedy this, modify the /etc/timidity/timidity.cfg file.  Uncomment these lines and restart Timidity.

opt EFresamp=d          #disable resampling
opt EFvlpf=d            #disable VLPF
opt EFreverb=d          #disable reverb
opt EFchorus=d          #disable chorus
opt EFdelay=d           #disable delay
opt anti-alias=d        #disable sample anti-aliasing
opt EWPVSETOZ           #disable all Midi Controls
opt p32a                #default to 32 voices with auto reduction
opt s32kHz              #default sample frequency to 32kHz

Once that’s all sorted out, it’s time to get started with the pin controller program.  You’ll need to download Gordon’s wiringPi library.  Download the latest software from the his repository, and follow the easy installation instructions (https://projects.drogon.net/raspberry-pi/wiringpi/).

The ALSA libraries should be installed by default on debian.  If you are using a different distro, go to http://www.alsa-project.org/main/index.php/Main_Page and get the latest development libraries.

You can then download the source code for my program here, called light organ.  http://code.google.com/p/pi-lightorgan/source/browse/trunk/lightorgan.c.  Check out the code to your pi using this command:

svn checkout http://pi-lightorgan.googlecode.com/svn/trunk/ pi-lightorgan-read-only

Compile the program by issuing the ‘make’ command.  Feel free to edit the code to suit whatever new ideas you come up with.

At this point, you should have a binary for the pin controlling program.  Run lightorgan as root.  Open another terminal and issue the command ‘aconnect -ol’ to list all of the active midi outputs.  You should see three entries: Timidity, lightorgan and the midi thru port.  The midi thru port needs to be configured to send it’s output both to lightorgan and Timidity.  Here is an exmaple of doing that:

aconnect -ol

client 14: ‘Midi Through’ [type=kernel]
0 ‘Midi Through Port-0′
client 128: ‘TiMidity’ [type=user]
0 ‘TiMidity port 0 ‘
client 129: ‘LightOrgan’ [type=user]
0 ‘listen:in       ‘

aconnect  14:0 128:0

aconnect 14:0 129:0

aconnect -ol

client 14: ‘Midi Through’ [type=kernel]
0 ‘Midi Through Port-0′
Connecting To: 128:0, 129:0
client 128: ‘TiMidity’ [type=user]
0 ‘TiMidity port 0 ‘
Connected From: 14:0
client 129: ‘LightOrgan’ [type=user]
0 ‘listen:in       ‘
Connected From: 14:0

At last, the ports are configured properly.  Now all midi traffic destined for port 14 (the through port) will be copied to ports 129 and 128 – Timidity and lightorgan.  You can use aplaymidi –port 14 midifile.mid to send to both Timidity and lightorgan.

If you’ve reached this point and everything is setup properly – you should be able to test the setup using a breadboard and some LEDs.  Here is an example with 4 LEDs:

In the file lightorgan.c, change MY_NUM_PINS to be the number of pins you plan on using.

Wire your pins to the LEDs using the chart at Gordon’s site: https://projects.drogon.net/raspberry-pi/wiringpi/pins/

Be sure to check out his tutorial on how to get started with GPIO on the Pi for more information.

Putting it all together:

I chose to build an enclosure using plywood to house the PI, the amplifier, outlets, relays, and connectors:

Photo: Construction has begun for my sound synchronized christmas light project. The photo shows six solid state relays and a half completed wooden enclosure. Also, a cat named dewey.

The junction box on the left is where the power comes in.  From there, individual runs of romex are run across to each relay, the ‘hot’ wire for each of these runs is separated by a solid state relay.  When voltage is run through the bottom terminals of a relay, the power is able to travel freely onto the outlet on the right side:

Photo: Oh what tangled webs we weave.

Shown above are 8 outlets (and also, my cat Dewey).  Two of the outlets are not connected to the relays, they are there to provide power for the Pi and the amp.  The connections on the left side are yet to be made.  Here is a view from another angle:

b

From here, the only thing left to do is complete the enclosure, add in the amp, add the Pi and wiring from the Pi.

a

This is the finished state of the box.  I probably should have cleaned it up a bit more, but I was too eager to see it in action. With everything being in an outdoor environment, I put a container of Damp-Rid in the box to try to mitigate the threat of condensation.

I hope this has been helpful.  If you have any questions, please comment.

-Chivalry Timbers

Posted in Uncategorized | 196 Comments