For Halloween 2019, I designed and built this Minecraft jack-o’-lantern equipped with a Raspberry Pi to play music, control an RGB LED block, and respond to proximity with flashing lights and sound effects.
This was a quick free-time project that involved 3D design and printing, electronics, and Python scripting. (Side-objective: promoting my young son’s interest in all of the above.)
A few weeks ago, I ran across this Minecraft Jack-O’-Lantern model and thought that I’d print one for my (older) son, who’s four years old and enjoys Halloween, Minecraft, and 3D-printed stuff.
It turned out pretty cute, but the empty space inside caught my attention. The Minecraft jack-o’-lantern glows yellow – maybe an RGB LED would make it more interesting?
I took some measurements and concluded that the interior was too small for anything like a Hue RGB bulb. I thought about scaling it up some more – I’ve printed some large models before, but how about (almost) an entire spool of filament? So I scaled up by 85%, requiring 400m / 1kg of 1.75mm PLA and printing for 36 hours on the fastest setting…
…now that’s more like it!
Now I have plenty of room inside. What else could I do with it? A Raspberry Pi should fit pretty easily. I could easily throw in some speakers and play music, like the Minecraft Halloween tracks. Could I also make it control the light? Maybe change color?
I had completed some classes this year in microprocessors and sensors, and some of the lab experiments involved the HC-SR04 range finder. A plan started to come together….
First, part selection and testing:
- RGB LED: I wanted a decent range of colors, integrated battery, just the right size, and a cubic shape that seemed appropriate. I chose this 4″ RGB LED cube, which is controllable by a standard infrared remote.
- Infrared LEDs and an infrared receiver: The RGB LED requires commands to be sent via infrared, so I’d need to record the infrared signals and then play them back using an infrared LED via GPIO. The recording could be done just once using the infrared receiver, and then the IR LEDs could be positioned near the sides of the cube to send commands. I chose this Gikfun kit (on hand).
- Range finder: Pretty simple – I chose the ELEGOO HC-SR04 (on hand). I initially chose the HC-SR04 from a different vendor, and then spent an hour trying to figure out why it kept becoming unresponsive – as it happens, some of these boards have a well-known problem with bad firmware. When the board receives a request for data, it sends the data and expects an acknowledgment echo on the same pin. Good boards, like the one from ELEGOO, use a timeout value in case the echo isn’t received… but cheaper boards don’t, and will hang until power-cycled.
- Microcontroller: I chose the Raspberry Pi 3B+ (on hand). I probably could have scaled down to a Raspberry Pi Zero W to reduce size and material cost, but I didn’t want to run into any problems while concurrently playing music, sampling the range finder, and sending IR commands.
- Speakers: I wanted speakers that were small and not terrible wattage, as the jack-o’-lantern would live outside. I wanted speakers with a dedicated power input, rather than using the Raspberry Pi TRRS jack for both power and signal. I chose these laptop speakers and removed the housings while keeping the lengthy cable with the USB power interface.
- Power source: I wanted a power bank that was compact, with decent power storage and two USB outputs (one for the speakers, one for the microcontroller). I chose this Adafruit USB Li-Ion power bank (ordered from Digi-Key since Adafruit was out of stock).
Here’s the schematic (generated with Fritzing):
Next was the software base:
- Operating system: Raspbian Buster Lite.
- Scripting language: Python 3.x.
- HC-SR04 interface: The RPi.GPIO library, using this tutorial from ThePiHut to communicate with the sensor.
- Infrared control: LIRC. For the record, LIRC is a powerful package that works well (when it works) – but it’s also very fragile and unreliable. Installing it (such as via this guide) is a difficult task full of hacks and workarounds, including building it from source twice, where the first time fails by design. I wish that the programming community would come together and either fix it or devise a more reliable replacement.
- Audio libraries: mpg123 for MP3s and aplay for WAVs, both invoked as shell commands and managed as subprocesses (which allows an MP3 to be paused).
- Media: An assortment of tracks from the C418 Minecraft Alpha soundtrack (purchased through Amazon) and selected sound effects from freesound.org.
For reference, here is my install guide. (I keep a file like this for each Raspberry Pi project that I undertake in order to document the configuration in a centralized and human-readable way. It’s helpful for debugging this project and as a reference for other projects.)
Part testing was improved by teaching my son what each of these parts can do. He’s still a little fuzzy on the details, but was excited to see each new piece of the puzzle.
The Python code to control the individual components was integrated into a script to run the process: playing music, periodically flickering the LED cube, and watching the input through the range finder. When the range finder indicates a nearby object, the script pauses the music, plays a random sound effect, flashes the LED cube red until the sound effect ends, and then resumes the music and returns to normal. Quite simple. Here is the script.
I wired up the microcontroller to the components by making a molex cable. Not the neatest cable, but it did the job.
The physical integration mainly a 3D-printing design task:
- The lid had to be printed and attached. Initially, I had planned on gluing it on, but in the middle of the design process, my
sonwife suggested hanging the jack-o’-lantern from a hanging-planter hook near the front steps of our house. It was a fine idea, but it meant affixing the lid in a way that would support the full hanging weight of the device. I added some bolt holes to the lid and printed a square bracket that fits tightly under the ledge at the top of the pumpkin.
- Most of the components sit in a vertical stack: the speakers (facing downward), the battery, and the Raspberry Pi, with enough headroom for the molex connector and a bit more to avoid bending the wires too much.
- The Raspberry Pi mounts to a platform that sits over the battery. Both the battery bracket and the platform required a cutout to expose the battery power button. (My initial bracket for the battery was so snug that it depressed the power button and shut off the battery.)
- The LED cube sits in a set of posts flanked by two cylindrical pillars for the IR LEDs.
- The range finger slides into the holes in the front, and there’s a small ramp-shaped bracket that holds it securely in place. (It’s only 0.7mm, yet it holds quite securely.)
- The main jack-o-lantern body has a hole at the rear. I designed a plug that bolts into a nut held by the rear post of the platform. As a result, the base is bolted to (and hangs from) the body with a single bolt – it’s both secure and easy to disassemble.
The base required a few drafts to fit everything together without crowding…
…but the results were nice. The height of the bottom compartment is 50mm – more than I’d planned, and not quite as unobtrusive as I’d hoped – but when printed in brown, it looks fine.
Now for component integration. I used some wire nuts for the IR LEDs just so that I could uncouple them if necessary.
Making a note here: Huge success! We hung it outside and it glowed, flickered, and made spooky noises throughout the trick-or-treating period. (It was also connected to our WiFi, and I found it amusing to ssh into our Minecraft jack-o-lantern to adjust the ranges.)
At the end of the evening, my son looked up and me and said, “Thank you for printing my pumpkin.” I’ll take that as a win.
A few concluding notes:
- The design requires the base to be unbolted from the body to turn the battery and LED cube on and off, and to remove and recharge each component. Not ideal, but the components really aren’t meant to be built into a bigger project.
- The HC-SR04 is a pretty low-spec component. It was OK at detecting ranges in my office, but when hung outside, it couldn’t detect anything more than a few centimeters away. Also, it generated a bunch of false positives, so it would just randomly trigger. Probably better to use a PIR motion sensor for these types of projects in the future.