Building a Christmas Music Light Show with a Raspberry Pi
A couple of months ago I really became interested in making a Christmas music light show using a Raspberry Pi. I've decided to put this post online to show you how to build the same show I built, and to talk about the challenges I had to overcome to get the show working. I'll also detail the hardware and software I used (links and downloads included) to make this show possible.
This particular project isn't as hard as you might think. Really, when you deconstruct how it works, the Raspberry Pi just plays a MIDI file and an MP3 file at the same time. Each of these audio files is playing the same song/melody in sequence. An application called Lightorgan, in a way, "listens" to the MIDI file as it is played and turns on the GPIO pins of your Raspberry Pi's in sequence with the song.
1 - Raspberry Pi (Model A or B)
1 - WiFi Dongle for the Raspberry Pi
1 - Small FM Transmitter
1 - 5 Volt, 8 Channel Relay Module Board
4 - Standard Wall Electrical Outlets
1 - Standard Spool of Stranded Electrical Wire
8 - 40 W Christmas Lights
To really make sure you can get this project off the ground, I'm going to walk you through each step of the software setup process. This doesn't take a lot of time to setup, but it does have quite a few details. For the purposes of this tutorial, I'm going to assume that your are using the Raspbian Linux distro.
Step 1: Install and Configure Timidity
You can install Timidity using the terminal command seen below. You'll also, after Timidity is installed, want to verify that you can hear audio back buy playing a MIDI file.
sudo apt-get install timidity
Once you have Timidity installed, you'll need to verify that it is listening on a midi port by using the
aconnect -o command. You should see output that looks similar to this:
client 14: 'Midi Through' [type=kernel] 0 'Midi Through Port-0' client 128: 'TiMidity' [type=user] 0 'TiMidity port 0 ' 1 'TiMidity port 1 ' 2 'TiMidity port 2 ' 3 'TiMidity port 3 '
Try playing a midi file using the
aplaymidi command. For example,
aplaymidi --port 14 yourmidifile.mid.
If you midi playback stinks, as pointed out in a post by Chivalry Timbers, the default Timidity settings may be too high for the Raspberry Pi. To fix this, edit the
/etc/timidity/timidity.cfg file and uncomment the following lines. Be sure to 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
Step 2: Install Gordon’s WiringPi Library
Download the latest software from the his repository, and follow the easy installation instructions for Gordon's WiringPi Library.
Step 3: Install Light Organ
At this point, you should download the source code for Chivalry Timbers' midi listening program, called Light Organ, at http://code.google.com/p/pi-lightorgan/source/browse/trunk/lightorgan.c. I've taken the liberty of cloning this over to GitHub where you can find the Light Organ Git repository. Download the code and configure it using this command.
sudo make && make install
Step 4: Run Light Organ
To "get your pins to listen to your midi file" you need to start Light Organ as root. You can do that using this command:
You'll need to make sure you start Light Organ as root every time you intent to run your light show because it is the software that makes your pins react to the midi sequence. After Light Organ and the Wiring Pi library have been installed and started, you will be able to play a midi using the
aplaymidi --port 14 yourMidiFile.mid command and see it hit your GPIO pins.
Connect the Relay Board to Your Raspberry Pi
To help you understand which pins should connect to the pins on the relay board, I've put together this simple pin diagram. For this project, I used WiringPi GPIO pins 0-7 (indicated with bright green in the diagram) . You can use a jumper cable to connect the pin to the relay. Be sure to ground the relay board by using the GND (ground) pins on the Raspberry Pi. Also, connect the relay board to power using one of the 5v pins. If you need more help connecting the GPIO pins to the relay board, use the terminal command
gpio readall to give yourself a pin print-out.
Essentially, this system will use a midi file as part of the light control system, but the person who views/listens to this show will hear mp3 audio. To hear the mp3 audio, you'll want terminal softare to play it. You can download mpg123 to play your mp3 files with the following command:
sudo apt-get install mpg123
Download the Music and Python Script
I've written a little python script to play the midi and the mp3 at the same time. I found a few usable mp3/midi files at http://www.mfiles.co.uk/christmas-music-and-carols.htm. These files worked well for my project because the midi and the mp3 files are perfectly synchronized. As you'll see from my Git repo, I've chosen to play a few of these files with my project. You can download the python I wrote to handle the audio playback from the xmas.py Git repo.
You'll find that the individual scripts I wrote to play a song are really simple. They really just synchronize the playing of an mp3 and a midi (the mp3 playback is started as a background process—notice the "&" at the end of the command) to be at the same time.
import os import time os.system("mpg123 -q carol-of-the-bells.mp3 &") time.sleep(0.55) os.system("aplaymidi --port 14 carol-of-the-bells.mid")
The FM Transmitter
The purpose of the FM transmitter is to broadcast your Christmas music to cars that might want to listen in on your light show. Just plug the transmitter into your Raspberry Pi's stereo jack, set the tuner to an unused FM frequency, and listen in.
The Final Result
Once you wire the relay board with power, connect your Raspberry Pi's GPIO pins to the relay board, and run the software provided in this blog post, you'll have your own working light show. Here's a video of what I would later turn into a 1500 light show!