Start Your Christmas Light Show With a Button

145

2

About: I'm a student of Electrical Engineering at Clemson. I've tinkered with hobby electronics since early high school (2012). I'm a photographer with Clemson's athletic department, along with being an active me...

When running a Christmas light show synced to music you might want to start the show by pressing a button. This tutorial is only applicable for a show that is controlled through Falcon Pi Player (FPP) running on a Raspberry Pi. If you're running FPP then you're probably using Falcon controllers and using xLights or LightORama to sequence your show. If none of those words mean anything to you, this tutorial is probably a little bit over your head for now and you should start by reading this wiki https://auschristmaslighting.com/wiki/ and joining a Facebook group like below

Step 1: Parts List

You'll need the following items:

  • A button. I used this one with an LED ring light around it: [Amazon]
  • A resistor. Preferably 200Ω or greater (2 of these if you're using the LED button) Standard 1/4W or 1/8W is fine
  • Connector wire. The gauge you should use depends on how far the button will be from your Pi. I used 18awg wire for about 10 feet from my Pi and it worked flawlessly
  • A way to connect a wire to the Pi's GPIO pins. You can use a ribbon cable with the breakout breadboard, or you can just use some female connectors like I did. We only need 3 wires - Ground, 5V, and data for button. [Amazon]
  • (Optional) A waterproof connector on each end for easy maintenance. I use 3-pin marine grade connectors: [Amazon]
  • (Optional) Heat shrink butt connectors [Amazon]

Step 2: Wiring Diagram

The pictures show a wiring diagram for a button without an included LED, and a button with an LED. The way I set up the wiring diagram allows you to run a button and a light (continuously on) with just 3 wires.

For the GPIO pin, pick any of the GPIO pins on the pi. Use the +5V and Gnd pins as well. You could probably get away with using the 3.3V pin, but the voltage drop across several feet of wire might make the signal unreliable or not be enough to light up the LED.

NOTE: The 3-pin connector will not fit through the hole you need to drill for a button with the LED ring light. So attach the connector after putting the button in your faceplate.

Step 3: Falcon Pi Player Basic Setup

NOTE - FPP is constantly being updated, and it's totally possible that they'll improve their scripting support or that they'll include "push button to start" as a default feature that requires less programming.

I followed the above video for initially getting everything set up.

I find videos boring and slow, so here's a summary of it:

  • Import your sequence to fpp using the file manager
  • Create a playlist with the sequence in it. For the next steps the playlist will be called "playme"
  • Open a blank notepad file and type the following:
    • #!/bin/sh
    • fpp -P playme
  • Save it as a .sh file on your computer
  • Go to the file manager in FPP and upload your script file. Go to the "Scripts" tab and make sure it is there
  • Under Status/Control go to Events
  • Create a new event. Event ID 1/1, Event name whatever, Effect Sequence NONE, Event Script
  • Go under Input/Output Setup and click GPIO triggers
  • Toggle the pin your button is attached to. If it will go low when you press the button then put the event on the Falling option, if it is active high then put the event on Rising.
  • Click the Reboot button by the warning it pops up after you make all the changes

After doing all this, you should be able to press the button to get your show to start. Woohoo!

However, this method has some limitations. If you press the button again while the playlist is going, it either 1) won't do anything or 2) will crash FPP and refuse to do anything with your button until you reboot it. So if you're just using a button as a dramatic way play your show on command, the above method will be all you need.

If you need something more, continue to the next step

Step 4: A More Robust Script

Below is the script that I eventually arrived at. You can view the script on Github here: [Gist.Github]

  • If someone presses the button during “night” hours it will play Tiger Rag (my Song1) and then go to the standby sequence which loops infinitely.
  • If the button is pressed while Tiger Rag is playing then it starts my second song, Hallelujah, and then will go to the standby sequence indefinitely.
  • But if someone presses the button during daytime or very late at night it will play Tiger Rag once and then turn all the lights off.

This allows the button to work at any time of day but the lights don’t have to be on all the time. It also allows for multiple songs to be played from 1 button by identifying which song is currently playing, ending that song, and playing the "next" song.

You can find more resources for scripting in FPP here: https://github.com/FalconChristmas/fpp-scripts
For more complicated logic just google “bash script ____” where underscore is what you’re trying to do. You can test your scripts using the FPP Shell (username fpp password falcon) The basic commands are as follows.

Pay attention to capitalization!!

  • Capital -P will play a playlist once, lowercase -p will repeat it.
  • fpp -v 66 Set volume to 66%
  • fpp -c stop Stop the show immediately
  • fpp -C stop This might be stop show gracefully
  • fpp -p thisPlaylistName Plays thisPlaylistName on repeat (so the intro song plays once, then the Main stuff will be repeated indefinitely.
  • fpp -P thisPlaylistName Plays thisPlaylistName once
  • eventScript "${MEDIADIR}/scripts/${thisScriptVariable}" Runs a script. In the case on the left it works for if you have your script name saved into a variable somewhere above, like thisScriptVariable=”PlayTheSong.sh”

ButtonSuperScript.sh

#!/bin/sh
###########################################################
#To be run if the button is pressed.
#You should have two playlists for each song - one with
# just the song as the "First play" and nothing in main,
# and another with the song as first play and your standby
# sequence as the "Main" sequence. (At least if you want
# to do the exact thing that I'm doing)
#
#For example, if your song is Tiger Rag, you should have
# playlists "TigerRag", "TigerRagStandby", and "Standby"
#
###########################################################
# Playlists to run if it is between 6 and 11
NightSong1="TigerRagStandby"
NightSong2="HallelujahStandby"
NightStandby="Standby"
# Playlists to run during the day or after 11
DaySong1="TigerRag"
DaySong2="Hallelujah"
DayStandby="Standby"
#On and off times in 24-hour time. If you want minutes, good luck
OnHour=17
OffHour=23
###########################################################
# Guts of the script. #
###########################################################
# Get our current status (IDLE=0, PLAYING=1, Stopping Gracefully=2)
STATUS=$(fpp -s | cut -d',' -f2)
#Get the running playlist and trim to 7 letters
PLAYLIST=$(fpp -s | cut -d',' -f4 | cut -c1-7)
#This will be "both" if it's playing a song, and "sequence" if it is standby
#used to determine if Standby sequence is running
STANDBYSTRING=$(fpp -s | cut -d',' -f5)
#First 7 letters of names of playlists for comparison
#Just 7 letters so that "Song1Standby" and "Song1" are identical
#Okay so actually it should be first x letters and x should be the shortest song name you have
StandbyPlaylist=$(echo $NightStandby| cut -c1-7)
Song1Playlist=$(echo $NightSong1| cut -c1-7)
Song2Playlist=$(echo $NightSong2| cut -c1-7)
STARTITEM=""
#Get the current hour in military time
CurrentHour=$(date +"%H")
#Print the status of some things - "echo" is like "print" in most languages
#Useful for testing if various things trimmed or calculated correctly
echo CurrentHour is $CurrentHour
echo Running playlist is: $PLAYLIST
echo Song2Playlist is: $Song2Playlist
echo Status is: $STATUS
#Set the volume to 80% at night, 100% otherwise
#So that if I'm sleeping it isn't as loud
#if [ $CurrentHour -lt $OffHour -a $CurrentHour -ge 11 ]; then
# fpp -v 100
#else
# fpp -v 80
#fi
# Check that we got something meaningful
if [ -z"${STATUS}" ];then
echo"Error with status value">&2
exit 1
fi
# Act on the current status
case${STATUS}in
# IDLE
0)
#Night time - play Song1 with standby
if [ $CurrentHour-lt$OffHour-a$CurrentHour-ge$OnHour ];then
echo Playing NightSong1
fpp -c stop
fpp -p "${NightSong1}"${STARTITEM}
#Day time or really late - play song 1 once then turn off lights
else
echo Playing DaySong1
fpp -c stop
fpp -P "${DaySong1}"${STARTITEM}
fi
;;
# PLAYING or STOPPING GRACEFULLY (graceful happens if button pressed when a scheduled playlist is ending)
1 | 2)
#Standby is running - this works because standby is my only non-media sequence
if [ "$STANDBYSTRING"=="sequence" ];then
#Night time - play Song1 with standby
if [ $CurrentHour-lt$OffHour-a$CurrentHour-ge$OnHour ];then
echo Playing NightSong1 for night time
fpp -c stop
fpp -p "${NightSong1}"
#Day time or really late - play tiger rag once then turn off lights
else
echo PlayingDaySong1 from playing
fpp -c stop
fpp -P "${DaySong1}"
fi
#To support more songs, copy this section and change "Song2Playlist" in last section to Song#Playlist
#Song1 is running
elif [ "$PLAYLIST"=="$Song1Playlist" ];then
#Night time - play Hallelujah with standby
if [ $CurrentHour-lt$OffHour-a$CurrentHour-ge$OnHour ];then
echo Playing HallelujahStandby from Tiger Rag is running
fpp -c stop
fpp -p "${NightSong2}"
#Day time or really late - play Song2 once then turn off lights
else
echo Playing Hallelujah once from Tiger Rag is running
fpp -c stop
fpp -P "${DaySong2}"
fi
#LAST SONG IS RUNNING - PLAY STANDBY
elif [ "$PLAYLIST"=="$Song2Playlist" ];then
#Night time - play standby on loop
if [ $CurrentHour-lt$OffHour-a$CurrentHour-ge$OnHour ];then
echo Playing standby on repeat
fpp -c stop
fpp -p "${NightStandby}"
#Day time or really late - play standby once
else
echo Playing Standby Once
fpp -c stop
fpp -P "${DayStandby}"
fi
else
echo For some reason the last elsecase executed.
fpp -c stop
fpp -P "${DaySong1}"
fi
;;
esac

Step 5: (Optional) Faceplate for the Button

I have access to a laser cutter at Clemson through the Makerspace, so I quickly sketched up a design to cut+etch. There's a hole in the middle for my button, the words say "Push Me" in a Christmas font, and a snowflake around the button. I spray painted some wood white and then covered it in masking tape (so that the laser cutter doesn't scorch parts I don't want etched). The file I used is attached.

Share

    Recommendations

    • Trash to Treasure

      Trash to Treasure
    • Arduino Contest 2019

      Arduino Contest 2019
    • Tape Contest

      Tape Contest

    2 Discussions

    0
    None
    jakabo27jessyratfink

    Reply 2 months ago

    Thank you! This year I'm going to use an edge-lit acrylic piece as the background, I'm still working on designing it all though. I'll probably update the pictures when it's done