This box was made with a button to press after a major achievement to boost your morale. It plays a song of your choice (or a random song) from a USB drive plugged into the side of the box. Personally, I prefer the Final Fantasy victory fanfares. With a little tweaking, you could easily make it stream over wifi or bluetooth.
The components used in this project are readily available. You should be able to build this machine in well under $100.
The main controller is a Raspberry Pi which is configured with the usbmount package. This will automatically mount USB drives under /media. I used a python script (run at boot time via /etc/rc.local – included at bottom of the post) that scans all the files ending in .mp3 in the /media directory and plays it when the GPIO goes high (i.e. an open circuit). I could have gotten an MP3 and DAC chip somewhere to output the audio and read music off an SD Card using a microcontroller but I couldn’t find a cheap solution.
The button was from a $10 emergency stop button I bought off eBay. Using an emergency stop button means I can stop the music any time by releasing the stop button. I took the button out of its enclosure and chucked it into my own. Be careful when you’re writing the software that the button is active high on the GPIO pull-up inputs (when the button is pressed, it is an open circuit – not a closed circuit unlike conventional buttons). I wired mine up to GPIO1 on the original Raspberry Pi B model since there’s a ground pin immediately to the left of it.
The PC speaker can be scavenged from any old computer and soldered to jumper wires to connect to an amplifier (or just a straight audio jack – see below).
Furthermore, I included an amplifier circuit to boost the audio. The is optional if you feel the power outputted by the Raspberry Pi is enough but it’s cheap enough to throw in even just as volume control. However, the amplifier did make the speaker more susceptible to noise, possibly from fluctuations in the power supply or electromagnetic interference from the cables – it even picked up blips from my wifi dongle. I chose an LM386 circuit since it’s small, easy to use and inexpensive (~$5-$10). Don’t bother wiring up your own circuit, eBay and websites like DealExtreme sell premade LM386 modules that take 5V nicely. For the amplifier, I also had to solder an old pair of earphone wires to jumper pins for easy connection.
I’ve included the design for the enclosure at the bottom of the post but be warned, the specs have changed slightly and I haven’t bothered to reflect the changes in the SCAD files.
Originally, I was going to 3D print the enclosure but felt it would look better made from wood. I was lucky enough to have a neighbour who had a CNC router in his garage and was nice enough to help me cut out the walls and build the enclosure (thanks Marco!).
The enclosure is designed to lock the Raspberry Pi in place via the SD card. Removing the SD Card lets the Raspberry Pi fall out nicely. Otherwise, it’s held in place by the USB connectors and SD Card. Nothing else was used to fix the board down.
The emergency stop button just needed screwing onto the top.
The speakers were fixed on with a plastic ring that came with the speaker. It was secured using nuts and bolts. I put a mesh on it too since it also came with the speaker.
The Raspberry Pi runs the default Raspbian Linux distro with a LOT of things cut out to reduce boot time. You may find minimal distros made for the Raspberry Pi that has a ~120MB footprint on the SD Card and fast boot times.
Next, I installed usbmount and pygame to automount USB drives as they are plugged in and for outputting sound in Python respectively.
Then, it’s just a matter of uploading the script that polls GPIO for changes and plays music at the right time. I have included the script I hacked up at the end of the post.
Don’t forget to add this script to your /etc/rc.local file along with code to export the GPIO interface and set it to input pull-up mode. You could use the horrible /dev/mem trick used in earlier tutorial Python code for the Raspberry Pi, but coming from a kernel developer background, I’d avoid messing directly with memory mapped I/O and just use the standard kernel interfaces for manipulating GPIO.
You may also want to configure your network interface to auto grab an address and install an SSH server so if you need to debug the box, you just have to plug in a wireless dongle instead of taking it all apart and hooking it up to a monitor.
Then, reboot your Pi and check everything works!