My Christmas Lights Display

January 1, 2022

I’ve always wanted to build a Christmas lights display that lit up to music - those were always the coolest houses to drive by every year; and I knew if I put something together like that, my kids (and probably neighbor kids) would love it. I wanted to document my journey building this, mostly for the sake of having some notes to reference at a later point, but maybe it’ll be helpful for someone else just getting started.

Disclaimer: Electricians: don’t @ me, I put this all together with google, youtube, and reddit.


Here’s the list of everything I used.

  • Raspberry Pi 4 (I went with the Vilros Starter Kit with 2GB RAM because it comes with a memory card, power supply, etc., all of which are required here)

  • 8-channel 5V Solid State Relay (I used this one)

  • Male-to-female jumper wires

  • Electrical outlets (5x) + a 4-gang box for mounting

  • Extension cords

  • 14-gauge wire (for the outlets -> relay)

  • FM Transmitter (I used this one)

  • 22-gauge wire (for the FM Transmitter’s antenna - I bought this)

  • Soldering iron (only needed for soldering the antenna wire to the FM Transmitter)

  • 3.5mm audio cable (male to male)

  • Terminal Block (I used this one)

Raspberry Pi setup

The first part is pretty routine with any Pi project. You need to set up your Pi with an OS (I used the official imager and installed the latest Raspberry Pi OS), and then set up your wifi/ethernet connection and enable ssh.

LightshowPi install

The next step is to install LightshowPi, instructions for which can be found on the Reddit Wiki. The install consists of updating packages, cloning a git repo, and running install scripts from therein. I did all this over ssh, which seems to be the easiest approach.

First Test

For the first test, I wanted to verify that I had everything install correctly. The relay comes with LED indicators, and LightShowPi comes with a test script you can run to flash the LEDs to ensure the wiring is correct:

Here’s how I tested:

  • Connect jumper wires from GPIO 0-7 -> channels 1-8 on the relay
  • Connect jumper wire from GND -> GND on the relay
  • Connect jumper wire from 5v -> VCC (power) on the relay
  • Ran sudo python ~/lightshowpi/py/hardware_controller.py --state=flash

Initial Wiring Test


I ran into a couple issues, both of which were thankfully already mentioned under the Wiki’s Common Issues. I specifically ran into both #2 and #3 in that list. In both cases, I was able to edit the files mentioned and try again.

Protip: Edit files on the Pi with sudo nano {file} works great if you have no other options. However, if you’ve got VS Code installed and are working over ssh anyway, the Visual Studio Code Remote Development Extension Pack makes this a lot easier. Using this extension, you can connect to your Pi and open up the git repo folder from there. Editing/saving files in VS code feels much more familiar and makes things like searching, find + replace, etc. much simpler.

Toolbox Time

I’m intentionally skipping over the wiring of my outlets to the relay. The reason is I’m not an electrician and what I’ve done here should not be copied if you do not know what you’re doing. It is very likely I’ve done something wrong, or it is not “up to code”, etc. but I’ll be iterating on and improving this each year.

My main goal was for this to be somewhat portable. On /r/LightshowPi, I’d seen a few people mention they packaged their wiring into a tote or tool box of some sort and it just so happened that I had a spare toolbox that wasn’t being used. I immediately go to work cutting out a spot for the 4-gang outlet box and another hole on the side. The idea is that when I put everything away, I can simply unplug the extension cords and pack the toolbox away.

[ pics coming soon ]

Helpful Commands

(For my future self)

Playing around with LSP for the first time this year, I used the following commands most often:

  • sudo crontab -e
    • to edit crontab (schedules)
  • sudo /etc/init.d/cron restart
    • restart the cron service (after any cron schedule change)
  • bin/start_music_and_lights --config=xmas.cfg
    • to start music and lights (where xmas.cfg is the name of my Christmas config overrides file)
  • bin/stop_music_and_lights
    • to stop music and lights

To update a playlist

I like to add new songs as I think of them. My process is as follows:

  1. Find a free “download mp3 from Youtube service” and copy/paste the links to songs I want to download.
  2. Update the filenames to remove spaces and make sure they are formatted {songTitle_artist.mp3} or something coherent.
    • There’s a command you can run to auto-remove spaces from files (from the wiki).
  3. Copy the files over to my playlist folder (xmas in this case)
  4. cd into /lightshowpi/tools
  5. Run python playlist_generator.py
  6. When prompted, enter the full path to the music/playlist folder: /home/pi/lightshowpi/music/xmas
  7. Once complete, the .playlist file in the folder is updated.

The cron schedule I use

# set var for path to LSP:
SYNCHRONIZED_LIGHTS_HOME = /home/pi/lightshowpi

# turn on lights at 4:45PM:
45 16 * * * python $SYNCHRONIZED_LIGHTS_HOME/py/hardware_controller.py --state=on >> $SYNCHRONIZED_LIGHTS_HOME/logs/music_and_lights.play 2>&1 &

# turn off lights at 5:14PM:
14 17 * * * python $SYNCHRONIZED_LIGHTS_HOME/py/hardware_controller.py --state=off >> $SYNCHRONIZED_LIGHTS_HOME/logs/music_and_lights.stop 2>&1 &

# start playlist with lightshow at 5:15PM:
15 17 * * * $SYNCHRONIZED_LIGHTS_HOME/bin/start_music_and_lights --config=xmas.cfg >> $SYNCHRONIZED_LIGHTS_HOME/logs/music_and_lights.play 2>&1 &

# turn off lightshow at 10PM:
0 22 * * * $SYNCHRONIZED_LIGHTS_HOME/bin/stop_music_and_lights >> $SYNCHRONIZED_LIGHTS_HOME/logs/music_and_lights.play 2>&1 & 

# turn on lights at 10:02PM:
02 22 * * * python $SYNCHRONIZED_LIGHTS_HOME/py/hardware_controller.py --state=on >> $SYNCHRONIZED_LIGHTS_HOME/logs/music_and_lights.play 2>&1 &

# turn off lights at 11:59PM:
59 23 * * * python $SYNCHRONIZED_LIGHTS_HOME/py/hardware_controller.py --state=off >> $SYNCHRONIZED_LIGHTS_HOME/logs/music_and_lights.stop 2>&1 &

(Note that you need to set your Raspberry Pi’s date/time/region settings to make sure you’re in the right timezone).

Additional Thoughts

  • Notice GPI0 0-7 above. I used 1-8 initially, which results in less-than-desired behavior. You can find the pinout for your Pi here.
© 2023 Lloyd Hanneman |