Introduction: The Pi Must Go On! Pi-powered RFID Musical Box.
An idea is born!
This Christmas, my wife and I entered a Hallmark store to let our 1 year old daughter look at the ornaments and trinkets. My wife and daughter were instantly drawn towards a glowing Disney princess castle. In the center of the castle was a platform, and as my wife took one of the five princesses from the front of the castle and placed her on the platform, lights started flashing and music started playing that corresponded with the selected princess. If Belle was placed on the platform, the castle played "Beauty and the Beast". Ariel sang "Part of your World" and so on.
Both my wife and daughter were enthralled by this castle! Finding out that these castles were sold out was a devastating blow. The closest castle was in a store hundreds of miles away. When we got home, my wife instantly searched online for sellers. The listed store price was a hefty $100 dollars or so, however, the online listings were upwards of $130-$160 as shown in these links:
I jokingly said, "I could probably make something like it for cheaper."
Knowing that I am a crafting novice and have the coding skills of a rock, she lovingly replied "I don't think so."
And the challenge was on!
DISCLAIMER: In the video there is a light buzzing sound. We apologize, that is our heater in the background and is NOT coming from the Pi or USB speaker.
A Long and Winding Road:
Skip to the next heading if you only care about a shopping list.
I'm going to give you a brief tour of my thought process.
"LeFou, I'm afraid I've been thinking" - Gaston (singing)
"A dangerous pastime" - LeFou
"I know" - Gaston
My wife and I grew up loving Disney. We had some Disney figurines laying around just waiting to let their voice be heard. This project really got its kick-start when I went down the rabbit hole on this very website to try and find similar projects. My goals were:
- Create or find a way to distinguish one character from another (without this step, the project is dead in the water.)
- Integrate whatever solution I found into a fairly durable physical "user interface".
- Make the project completely self-sustaining (As poor as my coding skills are, my one year old doesn't know the difference between a Secure Shell and Winnie the Pooh). Thus, I needed a simple on/off switch with a code that basically runs itself.
For the cost and computing power, you would be hard-pressed to find a better solution for a project like mine than a Raspberry Pi. I arrived at what I thought was the best solution to everything when I happened upon PyImageSearch. This Adrian guy is simply incredible, and his tutorials/projects seemed tailor-made for my application.
Picture what I had in my mind as the perfect solution:
My daughter holds up a figurine and the computer runs a facial recognition algorithm on the figure. After recognition, the correct song would play. This would require almost no hardware (just the Pi, a camera and a speaker).
After several attempts, I came to the realization that this just wasn't working right for me. I could get the Pi to distinguish my face from my wife's face, but the figurines were another story.
I then thought that I could train my own neural network using TensorFlow to recognize the princesses. This guy also does some amazing work in Computer Vision, and even uses TensorFlow Lite for the Raspberry Pi.
After some success, but mostly failure and "OOM" (Out of Memory) errors on my somewhat outdated laptop, I realized that I was back to the drawing board. While looking for hardware options, I happened upon the RC522 RFID reader and I knew I had found the final answer. Below, I will list the supplies with links of what I absolutely needed, and then I will list the materials that we used for the stage. Most of these links are to Amazon. I could have bought cheaper from elsewhere, but the free shipping and quick delivery was too good to pass up.
- Raspberry Pi 3 - I got this in a kit that came with a little case and power cable. I think a Pi Zero could handle this project easily. I got the Pi 3 when I thought I was going to do Object Detection/Neural Networks.
- Micro-SD Card - I got the 32 GB Sandisk Ultra Card, but something smaller/cheaper would have worked just fine.
- RFID RC522 Reader - Some people are getting these for less than $2 on Ebay. I chose to go with this one so I had a backup in case I messed something up.
- Momentary Push Button with LED - You could use any momentary button for this. I chose this one for the look and LED.
- MIFARE 1k tags - I was surprised at how affordable these are! Buy as many as you feel you need.
- USB Speaker - I got a new speaker because we don't have an extra one laying around. You could really use any speaker for this project.
- F-F Jumper Wires for GPIO Connections - If I wasn't a novice, I would probably have these laying around. You can also use M-F wires, and just solder to the RC522 leads. Your call.
- Soldering Iron
- Figurines - We chose Disney, but you could really use anything (i.e. Harry Potter, Mario, P.J. Masks, etc)
- Song/Sound List - We have a bunch of Disney CD's, and we bought the few extra songs we needed. Make sure and keep the project legal.
I ended up spending about as much on this as we would have if we'd ordered one of the castles from Ebay, but if I'd been smarter initially, I probably could have cut the cost to about $50-$60 total (using Pi Zero, RC522 from Ebay, cheap push button, less tags, and speaker that I had laying around.) For the same price as the Disney castle, we got more figures to sing as well as a sense of accomplishment!
- White box from local craft store
- Odds and ends pieces of balsa wood from local craft store
- Small piece of red velvet fabric
- Red thread
- Free Home Depot floor laminate samples (we got the ones with sticky bottoms)
- Hot glue gun
- Sewing machine
- White paint
- Permanent Markers
- X-Acto knife
This is all very optional. The beauty of a project like this is that you get to shape it to your vision. We chose a stage setting for the characters, but you could do anything with it. You could just use a Pi case and paint it at no extra cost to you.
A Word of Encouragement
This was my very first project on a Raspberry Pi. Take it from someone who had never coded in Python or even heard of a GPIO Pin, this is doable! The amount of resources and help online is tremendous. If you have a question, I guarantee it has already been asked and answered! In a matter of weeks I had the thing running with the card reader, LED push button, and speaker. Did I mention that my coding skills are sad to say the least? If this idea of a singing RFID Reader appeals to you, then dig in and have some fun!
Step 1: Set Up Your Raspberry Pi
If you are a beginner to the Raspberry Pi (like I was), then you should certainly give this section a glance. I would love to take the credit for getting my Pi set up just how I wanted, but the truth is that I relied heavily on the blogs/videos/Instructables of others.
The links I have included below is just the tip of the proverbial iceberg. If I included all of the helpful resources that I skimmed, this would cease to be an Instructable and quickly become an online library of sorts. Our PC has a Windows 10 OS, so I will include links that I found helpful for my particular case, but I imagine setting up the Pi with a Unix-based OS would actually be easier. So don't dismay if you have a Mac OS or Linux, as you will catch right back up on the following steps.
Setting up SSH for a "headless Pi" environment
Check out this tutorial for how to "flash" Raspbian Buster OS onto your Mini SD Card. I recommend performing what he says from the top all the way to Step #2 exactly how he explained it. It worked well for me! The OpenCV stuff isn't very applicable to this project, so once you've expanded your filesystem, the tutorial isn't as useful for this project. Before you can "expand your filesystem", you need to either connect a monitor/keyboard to the Pi or work through a SSH or VNC connection.
I only have a laptop at home. As such, I don't have keyboards and computer mice just laying around, so needless to say I was looking for a "headless (no extra monitor)" solution to talking to my Pi. I found that the program Putty was very user friendly.
This guy helped me figure out the basics of working "headless" in a Windows 10 environment, and this guy was also helpful in getting a Secure Shell (SSH) enabled on my RPi. Finding the RPi's IP Address proved more difficult than I initially suspected, but by using raspberrypi.local in Putty, I was able to get things going. I also had to switch my Network settings from "Private" to "Public". I recommend enabling X11 forwarding as shown in the image above.
Like I mentioned above, Adrian at Pyimagesearch.com has a ton of helpful tutorials. He doesn't "officially support Windows", but he'll throw the occasional bone that will help even a novice like me figure things out. This link especially taught me how to perform "remote development" on the Pi.
The blog will talk you through handy things like SCP (I use WinSCP as shown in the image above), Secure Shell File Transfer Protocol (SFTP) in Sublime Text or Pycharm, and many other useful things. I also used VNC Viewer to work on my Pi (see the snapshot above), and I highly recommend using a combination of all the available tools to make your life as simple as possible.
WinSCP made file transfer from my laptop to the Pi much easier, and SFTP made it so I could develop in a proper IDE like Sublime Text on my PC and have the scripts automatically update in the RPi folders. Super handy!!
I used Sublime Text to for this project since it is free to try out with the option of purchasing a license. After seeing how useful and user-friendly this IDE is, I am most likely going to dish out the money to buy the license.
I'm in.... Now what?
Just like everyone else, I recommend performing the appropriate updates and package installations you need to perform. After you see the magical green "pi@raspberrypi:~ $" as shown in the first image above, you are ready to go! Type the following lines into the command prompt and be patient while the Pi does its thing.
sudo apt-get update sudo apt-get upgrade
Step 2: Prepping the RC522 Reader
Take a quick screen break
If you are reading this, then I will assume it means that you are communicating with your Pi and that things went smoothly in the previous steps. Now it's time to give your eyes a break from the monitor and put your hardware hat on! Do some jumping jacks too, because things are about to get really exciting.
Note: At this point, you really could plow on with the rest of the software and coding steps and come back to this step later, so I'll let you decide how this plays out. Sometimes, when you get on a roll, it is hard to stop!
Setting up the RFID-RC522 Reader
By the time you are finished reading this Instructable, you should be fairly familiar with this blog post from "Pi My Life Up". This tutorial was perhaps the keystone to my project. I used the GitHub Repository source code associated with the blog post, and used the wiring diagrams with slight modifications (more on that later).
Most of the RC522 readers come without the header pins soldered on, and you will have the option to solder the the straight or bent pins into the "plated through-hole's (PTH's)". I chose to use the bent pins since they gave me the best profile for my project. You can use a breadboard to check connections, but since we will be using the F/F electronic jumper wires, you won't need to solder anything on the RC522 or the Pi after you have the header pins soldered in place.
I used 0.062" (1.6 mm) lead-free, silver bearing electrical solder with a rosin core. My soldering iron is a medium duty 40-watt Weller. You can take a look here. I have only soldered a little bit in my lifetime, and I am pretty poor at it, which is why I only included a tiny photo of the connections I made. I should just own it, but I guess you could say that I'm afraid of the soldering police. Once you have your header pins on, you are ready to start on your button.
Step 3: Getting the Button Ready
Button, button, who's got the button?
Like I mentioned, I needed this project to be completely self-contained. I needed to make it so that my children could use it without any knowledge of how to program, and so I decided that a simple Momentary On/Off button would suffice. Pulling the power to the Raspberry pi without executing:
sudo shutdown -h now
has the potential to ruin your SD Card. Don't do it! Therefore, I needed a button that could safely turn the Raspberry Pi on and off again. Once again, you will need to take out your soldering iron and use F/F jumper cables. On your wire, snip off an inch or two and strip back enough of the jumper wire to solder to the leads on the button. The button I used had a built in 12v LED that didn't require a resistor, so I soldered the jumper wires onto the correct leads for the button. It was a bit tricky for me to figure out exactly which button leads to use, so I recommend checking out 3:53 to about 5:12 of this video.
I don't have the helping hands with the little alligator clips, so I kindly asked my wife to use her "helping hands" by holding the wires in the correct position while I made the connection.
Later, I will discuss the software and scripts behind using the on/off button.
Step 4: Putting It All Together
Wiring it up
The first image above shows a Fritzing diagram of how to wire all of the components. The Fritzing diagram shows the button and LED as separate components. Mine was together, but the wiring is the same.
I only used a soldered connection on the button leads. The rest of the connections were purely mechanical connections made by the F/F jumper wires. The diagram is the same as the one on the "Pi My Life Up" blog post, except the GND pin that they placed on RPi GPIO Pin 6 was moved to Pin 30, since Pin 6 needed to be reserved for the button. I will give a quick summary of which header pin on the RC522 connects to the Pi:
- SDA goes to Pin 24
- SCK goes to Pin 23
- MOSI goes to Pin 19
- MISO goes to Pin 21
- GND goes to pin 30
- RST goes to Pin 22
- 3.3v goes to Pin 1
The image above that shows the GPIO Pin labels is from the Raspberry Pi website. I referred back to this image to help me know which pin is which. To attach the LED Button to the Pi, you will need to make the following connections:
- LED anode (+) goes to Pin 8
- LED cathode (-) goes any GND (I used Pin 39)
- Momentary Button lead 1 goes to Pin 5
- Momentary Button lead 2 goes to Pin 6
Note that the Button is simply closing a circuit, so it does not matter which lead goes to which pin. Just place one on pin 5 and one on pin 6, and you should be good to go. Your button won't be working yet, but you should see the LED light up once you plug your RPi in.
It's time we give some life to the project!
Step 5: Setting Up the Software - RC522
Back to the Computer
At this point, you should have the following things completed:
- Set up some method of talking with the Pi. I recommend VNC or SSH, but you can also use a monitor and keyboard.
- Solder RC522 header pins.
- Solder jumper leads to LED Button.
- Connect all of the F/F jumper wires to the RC522, button, and Pi according to the diagram in the previous step.
This section is really going to be the meat of this project, so hang on tight. Please note that the scripts we will be using for this section have been added above.
Getting the RFID Reader working
The RFID reader that I ordered came with a MIFARE 1k key fob and a card as well, so before I even ordered the extra fobs, I was ready to test it out. I also ordered some of the NTAG203 micro RFID Transponders from adafruit (as in the picture above), but we decided that for the same price, we could get a whole bunch more of the Classic MIFARE 1k tags. I am excited to try using the NTAG203 transponders on some other project though.
Like I mentioned before, this blog post is what I followed to get things set up on my Raspberry Pi. I will give you a rundown of his steps, but I recommend taking a look at his article and video as well in case I miss something.
In the Raspberry Pi terminal, configure your RPi to be able to use the Serial Peripheral Interface (SPI) by first running this command:
Using the arrow keys, select "5 Interfacing Options" and press Enter.
Then, arrow down to "P4 SPI" and hit Enter. When it asks "Would you like the SPI interface to be enabled?" select yes and hit enter. At this point reboot your Pi:
Install the packages you will need to interface with the RFID reader:
sudo apt-get install python3-dev python3-pip
In order to handle the signals from the RC522, we will need to use the spidev python library:
sudo pip3 install spidev
The MFRC522 library comes from a Github. This library is what we will use to read and write data to the RFID tags. To download the library, enter the following command:
sudo pip3 install mfrc522
Create a folder in your Pi directory where you will keep all of the scripts and music files for this project. I called it "pi-rfid" just like the blog we are following along with:
Now we are going to create a script that makes use of the MFRC522 library to write data to 13.56 MHz RFID tags. To get to our new folder, we will change directory and then create a Python script called "Write.py".
cd ~/pi-rfid sudo nano Write.py
Inside of the nano editor, enter the following code:
#!/usr/bin/env python import RPi.GPIO as GPIO from mfrc522 import SimpleMFRC522 reader = SimpleMFRC522() try: text = input('New data:') print("Now place your tag to write") reader.write(text) print("Written") finally: GPIO.cleanup()
The SimpleMFRC522() library is the way that we will talk with the reader. The try-finally block will handle exceptions and make sure that the last thing we do is cleanup the GPIO pins. To save the code in the nano editor, we will first press CTRL + X and then press Y and hit Enter.
Inside of the pi-rfid folder, run the Write.py script:
sudo python3 Write.py
Type the text you'd like to store in the RFID Tag, hit Enter, and place the tag on top of the RC522 reader. It should say "Written" if it was able to write correctly. As an example in the images above, I wrote Aladdin to the tag.
What good is an RFID reader though if it can only write? Let's create a Read.py file inside of the same /pi-rfid folder:
cd ~/pi-rfid sudo nano Read.py
If you want to check and make sure that your RC522 reader is working correctly, enter the following into the nano editor:
#!/usr/bin/env python import RPi.GPIO as GPIO from mfrc522 import SimpleMFRC522 reader = SimpleMFRC522() try: id, text = reader.read() print(id) print(text) finally: GPIO.cleanup()
Press CTRL + X, then press Y, and hit Enter to save the file. We will obviously need to modify this code to associate the text that has been written to the tag with a song, but for now let's run the script as is to make sure it is working. In the /pi-rfid folder, type:
sudo python3 Read.py
You will see that as you place your tag on the RC522 reader the text and id associated with the tag will be output. This is pretty amazing!
Getting the USB Speaker Ready
Using the USB Speaker is fairly straightforward. Even so, I had a few issues getting the RPi to default to the USB speaker. What I had to do is:
- Plug in the speaker.
- Make the Raspberry Pi look at "card #1" for the audio. In other words, change the default audio from the built-in jack and HDMI ports to the USB.
To make this happen, run:
sudo nano /usr/share/alsa/alsa.conf
Arrow down for a while, and then change
defaults.ctl.card 0 defaults.pcm.card 0
defaults.ctl.card 1 defaults.pcm.card 1
Hit CTRL + X, Press Y, and hit Enter. Now when you open up VNC Viewer, if you right click on the audio symbol in the upper right, you should see that the USB audio is selected by default as shown in the image above.
Creating the Playlist
For our song list, we only used songs that we had purchased on CD's. We made sure we were only using very small portions of each song. I tried to e-mail Disney about my specific project and whether it would be allowed or not, but I never got a response. Since this is not a commercial product and we are using songs that we purchased for our kid's enjoyment, we figured we were okay.
We used Audacity to snip the songs to the length we wanted and exported the songs as .wav files with the characters' names. For example, Jasmine's song clip was named Jasmine.wav and placed into the pi-rfid folder using WinSCP. This means that the filepath to this example file would be /home/pi/pi-rfid/Jasmine.wav. As soon as you have your list of songs and have written the correct text to all of the tags using the Write.py script, you only have one more step to go until your tags are singing!
Editing the Read.py Script
Before, the Read.py script could only recognize the tag. Now we are going to make it so that it recognizes the tag, loads the song associated with the tag, and plays it on the speaker.
I had some criteria that I used to design the code:
- I didn't want an exception to end the script, so I added some lines to skip misreads and only exit upon a "keyboard interrupt."
- I wanted the same character to be able to finish their song without endlessly restarting if my daughter chose to leave it on the reader.
- Any time a new character is placed on the reader, the song changes.
I'll walk you through the script line by line. At this point, I would love to also ask for advice. This is my first Instructable, first time ever coding in Python, first time setting up RFID tech, and first time using a Raspberry Pi. If any of you can think of a slicker way to do this, I would love the feedback as a comment. I'm new to the concept of try-except loops, so give me a holler if I am off my rocker with this code.
I would recommend using SFTP in Sublime Text to edit the script if you are comfortable with it.
First, open a Raspberry Pi terminal and type:
cd ~/pi-rfid sudo nano Read.py
If you are using SFTP, simply open up the Read.py file in the Raspberry Pi "server", and all changes you save in Sublime Text will automatically be made on the Pi.
Once you are in (either SFTP or nano editor in the terminal), type:
This helps the Pi know to read this file in Python.
Import all of the necessary packages:
import time from time import sleep import pygame import sys import RPi.GPIO as GPIO from mfrc522 import SimpleMFRC522 import re from subprocess import Popen
These libraries and functions will allow us to perform all the tasks required. Now type:
reader = SimpleMFRC522()
This is the same command as before. Now print some welcome messages:
print("Looking for cards") print("Press Ctrl-C to stop.")
Start a variable that you can use to check for repeat readings:
textloop = "Start"
The rest of the code will look like the following:
try: while True: print("Hold a tag near the reader") id, text = reader.read() print("ID: %s\nText: %s" % (id, text)) if text == textloop and pygame.mixer.music.get_busy() == True: pass else: character = " ".join(re.findall("[a-zA-Z]+", text)) filepath = ("/home/pi/pi-rfid/%s.wav"%character) # Just added the following three lines to prevent errors. # Code should skip the bad reading and continue to look # for tags if filepath == "/home/pi/pi-rfid/.wav": continue else: print("filepath is: %s"%filepath) pygame.mixer.init() pygame.mixer.music.load(filepath) # pygame.mixer.music.load("%s.wav"%(character)) pygame.mixer.music.set_volume(1.0) pygame.mixer.music.play() textloop = text sleep(2) except Exception: GPIO.cleanup() pass except KeyboardInterrupt: GPIO.cleanup() raise
The try-except loop is used to catch the exceptions and skip all of them except for a "keyboard interrupt". Inside of the try block, we are creating a while loop that is constantly reading. If a tag is read, the text is converted to a character name only (the text had a bunch of blanks after the name, so I took only the letters from the name).
This character name is loaded into pygame.mixer.music and the song is played. The textloop function is then updated to the current text, and the loop continues after sleeping for 2 seconds.
Note that the next time through, the program will essentially ignore the readings if two things are true: 1) text = textloop, and 2) there is a song playing. This makes sure that a song for the same character doesn't get read over and over and start the song repeatedly without letting it finish.
Also note that if there is a misread, and the text is blank, the code will skip over that case. This means that unless the program is interrupted with either the power putton or "keyboard interrupt", it will just keep on going.
There are multiple ways to do this task. I read one Instructable accomplishing a very similar task that was helpful, but this way made more sense to me. I have attached the Write.py and Read.py files I am using in this project, so feel free to download them and place them in your /home/pi/pi-rfid folder on your Raspberry Pi along with all of your songs.
One Last Quick Note
For whatever reason, I was having some trouble at one point with the MFRC522 code, and so I actually had to edit lines 140-143 of the MFRC522.py file you pip installed from:
if gpioMode is None: GPIO.setmode(pin_mode) else: pin_mode = gpioMode
I only had to do this after I started using the button though. Maybe it has something to do with the way that the pins are shared. This worked for me. To get to the MFRC522.py file, you need to sudo nano /usr/local/lib/python3.7/dist-packages/mfrc522/MFRC522.py. Or you can find this file and edit it through SFTP.
Step 6: Setting Up the LED Button
A Timely Word of Caution
Whenever you fiddle with scripts at boot, you need to be very careful. Best case, everything works out great. Worst case, you accidentally mess up a critical bootup protocol or add a script that will cripple your Pi. So to make sure you aren't headed back to Step 1 to flash Raspbian anew on your Micro SD, let's take a look at a safe on/off protocol you can use. I didn't have any issues using the process described below.
Check out these three videos that I watched to help me get started on the button:
- Video 1 - Adding a button
- Video 2 - Adding the LED to the button
- Video 3 - Mounting the button inside of a RPi case - I only watched this video because it shows the exact wiring for the same button I bought.
These videos and the text file he provides were critical to getting my button working right. Although we are not using RetroPie, all of the startup protocols and procedures will still work just fine with your Raspbian OS.
Since this step is more like a to-do list, just follow step-by-step, and everything should run smoothly for you.
"And at Last I See the Light"
To keep your LED glowing when the Pi is on, first, you need to make sure the serial can access the login shell. As best as I can tell (proficient Pi users correct me), this makes it so power is provided to the pin that your LED is attached to.
In a Raspberry Pi terminal, enter:
Once you are in, arrow to "5 Interfacing Options" and press Enter. Next, arrow to "P6 Serial" and once again hit Enter.Arrow to "Yes" and hit Enter one more time. Now reboot your Pi:
And when your Pi reboots, you should notice that your LED will light up and remain lit until it is once again shut off.
On Again Off Again
The text file that I followed is in the comments section of the first of the three YouTube Videos that I mentioned above. I will outline the procedure here as well.
First, even though we have some of the packages we need, let's just make sure everything was installed properly once again. If you already have the package installed, the Pi will just tell you. Open a terminal and type:
sudo apt-get install python-dev sudo apt-get install python3-dev sudo apt-get install gcc sudo apt-get install python-pip
Now, install the GPIO Package that you will need to use to get the button working correctly:
To extract all of the files within the .tar.gz package execute:
sudo tar -zxvf RPi.GPIO-0.5.11.tar.gz
These last few steps should have created a new folder titled "RPI.GPIO-0.5.11". Enter into this folder:
Install the scripts inside the folder:
sudo python setup.py install sudo python3 setup.py install
Make a directory called "scripts" in your Pi path to keep your shutdown script:
Use either SFTP or nano editor to create a new Python script called "shutdown.py" inside of the "/home/pi/scripts/" folder. Using nano in your terminal would look like this:
sudo nano /home/pi/scripts/shutdown.py
Paste the following scripts inside of the nano editor by copying and then right clicking inside of nano. The scripts has also been provided above, so feel free to snag it.
#!/usr/bin/python import RPi.GPIO as GPIO import time import subprocess # we will use the pin numbering to match the pins on the Pi, instead of the # GPIO pin outs (makes it easier to keep track of things) GPIO.setmode(GPIO.BOARD) # use the same pin that is used for the reset button (one button to rule them all!) GPIO.setup(5, GPIO.IN, pull_up_down = GPIO.PUD_UP) oldButtonState1 = True while True: #grab the current button state buttonState1 = GPIO.input(5) # check to see if button has been pushed if buttonState1 != oldButtonState1 and buttonState1 == False: subprocess.call("shutdown -h now", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) oldButtonState1 = buttonState1 time.sleep(.1)
Press CTRL + X and then Y to save this script. Connecting Pins 5 and 6 on the Pi enables the bootup, then this program watches and waits for a new button press on those same pins. Once connected, the "sudo shutdown -h now" command is executed, and a safe shutdown follows.
Reboot the Pi:
This last step will ensure that the shutdown.py script runs at startup and continues running until the button is pressed. We will use the edit the /etc/rc.local to ensure the script runs at bootup:
sudo nano /etc/rc.local
Use your arrow keys to go down to right before the end where it says "Exit 0". Add the following command right before "Exit 0" and make sure you don't miss the ampersand (&) at the end of the command. This "&" will make sure that even if the program ends up in some wicked, endless loop, the Pi will still continue its bootup protocols.
sudo python /home/pi/scripts/shutdown.py &
Press CTRL + X and then Y to save the file. Issue one last:
sudo shutdown -h now
As soon as your Pi is completely shutdown (the green light is done blinking), go ahead and try out your button.
Make sure everyone using the button understands that even though the Pi boots and turns off very quickly, it is still a computer, and takes some time to go from on to off. We usually wait 10 seconds or so between button pushes to let it do its thing.
You should be able to taste the victory at this point! One last tech step, and your child's dreams will come true!
Step 7: Enabling RC522 at Startup
The very last step we need to take is to make the RC522 "Read.py" script run on startup. I tried all sorts of different ways, but I finally had success using a Crontab. The simplest method of changing the rc.local file like we did in the last step just didn't work for me, and I'm not sure why.
Maybe some Python/Pi whiz out there can tell me what I did wrong, but Systemd, init.d tab, bashrc, and several other methods gave me some grief. Once I got it working with Crontab, I didn't dare go back to see if I could make the other methods work, but maybe on my next project, I will try them again.
I recommend reading this article, which describes the process of using a crontab to run a script at bootup.
We are going to need the Pi's id later, so let's find out what your id is now. In a terminal, type:
My username is Pi, so I typed the following as shown in the image above:
Your Pi's id is listed as uid. Mine was 1000, so I noted that down for later.
Next, you need to open crontab. In a terminal, execute:
sudo crontab -e
I wish that I had written down what I saw after issuing this command, but I want to say that I was presented with three options (one of them is default I believe). I just went with the default. If you aren't seeing those three options, then just arrow to the bottom of the file as shown in the image above.
For some reason, my USB audio had a bit of trouble running through a crontab, so I had to find a workaround. I'm not sure if this is the best way to get it working, but once again it worked great for me.
At the very bottom of the crontab file enter:
Replace "user_id" with your id. You can see my example in the images above.
Finally, enable your script in the Crontab by placing the following line at the very bottom of the file:
@reboot sudo python3 /home/pi/pi-rfid/Read.py > /home/pi/pi-rfid/log.txt
This will not only ensure that your file runs at bootup, but will also write all of the outputs to a .txt file inside of the "pi-rifd" folder. This is a great way to troubleshoot your program. Press CTRL + X and then Y to save the crontab, and you should be finished with all of the programming required for this project.
Use your button to turn off your Pi and then after waiting a sufficient amount of time, go ahead and hit the button one more time to turn it on. When you place the tag onto the reader, you should hear your saved sound files. If you get to this point and nothing happens Do Not Panic!! I ran into several errors while working on this project. I tried to include all of the workarounds that helped me get things going, but there is not way that I could catch every speaker/tag configuration that you could imagine. I have found that with a little patience and a lot of troubleshooting, miracles can happen.
One tool that I found helpful to see if my scripts were indeed running at startup was by opening a terminal and typing:
sudo ps -ax | grep python
This command searches for processes including "Python" in the name. You can look in the image above to see what scripts should show up. It also includes their Process id (pid), so you can end them using:
sudo kill <PID>
For example, if you wanted to end a process with a pid of 437, you would type:
sudo kill 437
I have found that the last process that includes "grep --color=auto python" is always running regardless of what we've done, so don't kill that process. Maybe someone could tell me what it is/does? The CTRL + C keyboard interrupt doesn't work on these background processes sent from the rc.local file or the crontab, so get familiar with killing the scripts in the terminal.
I found that the easiest way to troubleshoot was to kill the scripts and manually run the "Write.py" and "Read.py" scripts inside of the terminal. This allows you to use SFTP or nano to tweak the files and run them at a faster pace than switching the Pi on and off over and over again.
Regardless, if you do run into an issue or two, don't give up. The internet is a wonderful thing, and as I have said, if you have a question, it has probably already been asked.
I will also do my best to help with those of you interested in recreating a project like mine, so feel free to comment problems you run into, and I will do my best to help you figure out a solution.
We now have an RFID reader hooked up to a Pi along with an on/off button. We have written data to the tags and our handy-dandy "Read.py" script is constantly looking for those tags and playing the song corresponding to each tag as it is pressed on the RC522. Both the on/off button and the RFID reader scripts are running on startup, and as the on/off button is pressed, it shuts down and turns on the Pi.
As I mentioned, if you have tech questions or suggestions, please put them below. I am a complete beginner and appreciate criticism. I hope by the number of links that I dropped you can see that I needed about every website on the internet to figure this out. Don't hesitate to let me know what you would change or do differently. Since I received two RFID readers with my purchase, I will most likely try a variation of this project later. If you catch errors in any of the steps, let me know as well so I can correct them.
Passing the Baton:
I will now let my awesome wife explain the rest of this project. I was happy to make it this far, but my wife is amazing at decorating and embellishing. She will talk you through mounting the Pi, speaker, button, and RC522 reader in a safe location that is kid-friendly. Everything from here on out is optional for the functionality of the device, but we hope that by explaining our process, you might be able to replicate it should you so choose.
Step 8: Set the Stage!
For the stage, we found a white photo box at Michael's that worked perfectly. Whatever stage you decide, make sure it passes these qualifications:
- It's big enough to hold/cover/protect your equipment
- It's strong enough to be cut into and glued on
- It isn't too thick for the RFID tags to be read through it
We took the box with us to Home Depot and grabbed our favorite laminate stick-on tiles from their free samples. You can fit those squares to your stage, cut a circle a little bit larger than the RFID tags and call it good! My husband wanted it to look a bit more natural so we sliced the tiles into 1 inch wide sections and arranged the rows slightly different from each other, adding smaller squares in the gaps to get that "wood floor effect". Align them, but don't glue or stick anything permanently yet.
Step 9: Get Everything Into Frame...
Now you build the frame for your stage curtains.
We used some balsa wood dowels we found at Michael's. We used one small 24" square dowel, one small (smaller than the square ones) 24" round dowel and one thin 24" flat board.
- Cut the square dowel into two 12" rods
- Cut the round dowel into one 12" rod
- Drill one hole the size of the round dowel into both square dowels 1/2" down each rod
- Drill two holes into the stage floor on either side of the front of your stage for the square dowels to fit through- use an exact-o knife to cut the hole into a square shape
- Insert each end of the round dowel into the two square dowels
- Insert the square dowels into the holes in the stage floor and check to make sure all dowels are straight and fit properly into each hole
- Take the flat balsa board and cut it to your preferred size (we wanted it to cover the top of the curtains)
- Paint the dowels and board in your preferred color
- After the paint has dried, check for proper fitting, sand down any areas needed
- Insert your frame into the stage, glue it to the inside of the box lid, securely glue down the faux wood flooring, set the flat board to the side for later
Step 10: Draw the Curtains!
For the curtains, I found a half a yard of red velvet fabric at Walmart for $2 that was MORE THAN ENOUGH.
- Measure the width and length you want for your curtain panels and cut the fabric, adding an extra inch to your measurements (I had 7 x 9 in panels so I cut two 8 x 10 inch sections)
- Use a needle and thread or a sewing machine to hem up the two sides and bottom edge of each panel. The top edge should have AT LEAST a 1/2" hem with the sides left open or your round dowel won't fit and you will have done it all for naught...
- Cut two thinner pieces of fabric (about 1" by 4") and hem the sides to make ties to hold the curtains back
- Insert the curtain panels onto the rod, check to make sure it fits the way you want to, and glue the dowel into place
- Take the flat board and glue it to the two square dowels on either side, covering the dowel holding the curtains
Voila! You now have beautiful over-the-top curtains to fit your classy stage!
Step 11: Making the Cut
Now we're getting to installing the hardware inside the box. You'll need to cut out and reinforce (with glue) openings for these things:
- The speaker
- The Pi plug
- The LED on/off button
This depends highly on the shape/size of your stage so make sure to measure appropriate heights and spacing* needed to insert items.
*The Pi needs to be able to plug into the speaker, which needs to reach the outside of the box. The Pi also needs to stay connected to the on/off button, which needs to be part-way out of the box and reach the RFID tag reader, which needs to reach the bottom side of the center of the stage.
Then, it's still just a cardboard box with a weak structure so you've got to toughen it up a bit. We took our extra balsa wood pieces and cut them to reinforce certain areas:
- The LED button needs something to push against to work. Add a big clump of glue over the soldered connections. Place balsa wood directly behind it with a notch cut so the cords could get through. Finally, reinforce that piece of wood with two pieces of wood perpendicular to it
- The Pi needs wood behind it to be able to plug in without being pushed further into the box. Glue a piece of wood directly behind it, with reinforcing pieces perpendicular to that piece
The idea of reinforcing the box is to be sure that you won't completely destroy your stage trying to push the buttons or plug the Pi in. Do what you need to ensure that when you push, the button/plug are able to be pressed/plugged in and it's not bending the box to do so.
The RFID tag reader will remain loose until you have everything secure, then you can use a few dots of hot glue to stick it to the bottom side of your center stage circle.
Step 12: The Final Scene
Take the RFID's and attach them to the bottom your figurines (we used hot glue).
Add some LED lights, if desired (we just attached some $3 battery operated ones from Walmart).
Give those characters their moment in the spotlight and enjoy!
Our daughter has spent hours playing with this stage (she's 16 months old) and we have had friends from ages 2-26 also play with and enjoy it!
As beginners, we understand how much help and research was required to make this project possible. If you have any questions, leave a comment and we'll do our best to help you! We'd love to hear feedback about improving the project and success stories. Thanks for taking this journey with us!
THIS PROJECT WILL BRING JOY TO ANY AGE AT ANY STAGE!
Runner Up in the
Raspberry Pi Contest 2020