Introduction: 3D Printed Electronic Puzzle Box

About: I am a Software Engineer and a 3D printing hobbyist. I also enjoy video games, puzzles, and playing music. Visit my blog at to follow my projects.

Over the last few years, my family has been wrapping Christmas presents in more elaborate and difficult to open ways. Last year, I 3D printed a gift card inside a clear PLA box. This year I decided to step it up and make it a lot more difficult (and hopefully more fun).

This puzzle box has 3 compartments. The side compartments are large enough for gift cards or cash. The main compartment is as big as I could get it while still fitting on my Rostock Max v2 printer. It is large enough for small gifts.

Each compartment requires a 6 digit code in order to open. Additionally, the box has to be in a specific location for each compartment. This sends the recipient on a treasure hunt in order to get into all 3 compartments. The main compartment won't open without both key switches being turned, so you can hide the keys somewhere else or put them into the side compartments to be found along the way.

One of the challenges I wanted to tackle was fitting all of the electronics inside the lid so that the insides would not be seen even when the box is open. I think this gives it a more polished look overall.

This project requires a 3D printer, soldering skills, and basic knowledge of electronics.

Step 1: Tools and Materials

Step 2: 3D Printing the Box

There are five STL files to print. Two of them are quite large and need a fairly big printer. The main part of the box prints in one big piece with the doors on hinges. I used Simplify3D to put supports in under the doors before slicing the model. If you haven't tried Simplify3D, I highly recommend it. It is not cheap, but I really love it.

I've included the original 123D Design files in case you want to make modifications. Additionally, this version of the box has a "feature" where if you twist the lid, you can open the box without using the codes. I'm not going to lie, I've used this a few times because it was easy and I was with each person when they were solving the box. But if you want it to be more secure, I've made a fixed version that shouldn't let you twist it open. Beware that I haven't tested it yet, but you can give it a try. It is labeled "fixed untested" and only the Box Main file is changed.

The standoffs in the lid are set up for the components that I listed in Step 1. If you want to use something different, you can move the standoffs in the 123D Design file to accommodate the new hardware.

The symbols on the sides of the box are from Stargate. I added 6 of them to try to confuse my family into thinking that they were clues, but they weren't. I think they look cool, You can modify the 3D model to remove them or add your own symbols.

Step 3: Load the Arduino Software

I like to load the software before building the whole box. This lets you test each component as you plug it in.

I've attached a ZIP file here with all of the Arduino files. "ReverseGeocache_v1" contains the code to run the box. Put the other 3 folders (Keypad, LiquidCrystal_I2C, and TinyGPSPlus-0.94b) into your Arduino libraries.

All of the code you'll need to edit is right at the top of the ReverseGeocache_v1.ino file.


code1, code2, and code3 are the codes to open doors 1 (left door), 2 (right door), and 3 (main compartment). These should be 6 digits long and a mix of numbers and letters A through D. initCode is used to lock all doors and reset the memory of what doors were already opened. masterCode unlocks all of the doors. Set all 5 of these to whatever you'd like. codeEntered is an internal array, so leave it blank.


You can set 3 different locations for the box. Se the latitude and longitude in the LOCATION_1_LAT, LOCATION_1_LON variables (as well as 2 and 3). I've set all 3 to the Grand Canyon by default.

The margin variable defines how close the user must be to the exact location before the door will open. I allowed 0.1 miles, but you can make it more precise if you'd like by changing this value.

The rest of the header defines the other pin values for the components. Change these if you wire it up differently, otherwise leave it as is. I won't go over the rest of the methods here, but here is an explanation of the workflow:

The user enters a code. If it matches one of the codes, check if the door was opened previously. If it was, toggle the state of the door. If it was not opened previously, check the GPS location. If in the correct location, open the door. Otherwise show the distance to the correct location.

The only variation of this is for door 3, where we also check the state of both key switches and to make sure that doors 1 and 2 were actually opened before. The key switches use the same key, so this was a double check that the user isn't cheating.

Step 4: Wiring Diagram and Jumper Wires

This is what the wiring will look like. I wanted this to be as simple as possible, so I used female to female jumper wires on almost all connections. This lets us plug a prototype board into the Uno and just plug everything into there. Short of a few wires soldered to switches, everything can be easily removed.

In order to make everything fit, we're going to be cutting the plastic connectors off the ends of the jumper wires and putting heat shrink on instead to make the connectors shorter. I recently learned another trick to bend the ends of the jumper wires before putting the heat shrink on. This lets it take up even less space. I didn't do that when I put this together, but it is super easy to do. You can find info on how to do it on the Super Game Pi tutorial on Adafruit.

One other possible change would be to wire the key switches to A0 and A1 instead of 14 and 15. This would have fewer wires running all of the way across the board. If you decide to do that, you can easily change the pins in the Arduino code that we will get to later.

Step 5: Power Switch and Battery

The box is powered by a 9V battery that is placed inside a side compartment. This allows the user to replace the battery if it dies without being able to get at the internals of the box. The USB port on the Arduino is also accessible from inside the battery compartment so that you can easily program the box without taking it apart. A latching light-up power switch toggles power to the box. It only lights up when power is turned on.

To wire this, cut the red wire from the 9V battery connector. This will be rewires to connect one side to C1 and the other to NO1 on the switch. The + and - will be wired to 5V and GND on the Arduino. Solder these wires directly onto the connectors on the switch.

To splice the wires together, hook the wires around each other and put solder on the joint. Then cover it with heat shrink.

Depending on the length of the plastic relief piece on the power connector, you may have to trim it so that it fits inside the battery compartment.

Use #4-40 1/4" round head screws to attach the Arduino to the standoffs near the battery compartment. The first time you put them in, they will be a little tight.

Step 6: LCD Display

Plug the jumper wires for the LCD in before screwing it into place. I actually left the plastic connectors on for this one since it did fit, but the wires wouldn't be as stressed if you cut the ends off and replace it with shrink wrap, so that is up to you.

The SDA pin goes to A4 and SCL goes to A5. VCC goes to one of the 5V pins and Gnd to Gnd. Once that is all plugged in and screwed onto the standoffs, turn it on and make sure the screen turns on. You should see "Enter Code" on the LCD. If it is not visible, try adjusting the contrast using the screw on the back of the display (marked in the image).

Step 7: GPS

The GPS antenna fits into the square hole in the lid. I wanted to make sure that it was not blocked. I didn't actually test if it would work if completely enclosed, but I think it looks pretty cool this way. It is held in place by the GPS holder piece that you 3D printed.

Solder the headers onto the GPS so that they stick out the back. This makes sure that the right side of the antenna is facing out the lid. Use #4-40 1/4" round head screws on the GPS board and #4-40 1/2" round head screws on the GPS holder.

Connect Tx to pin 8 and Rx to pin 9. VCC goes to 5V and Gnd to Gnd.

Step 8: Keypad

The membrane keypad has a sticky back to it, so you can just peel the backing and put it right on the outside of the box. Slide the connector from the keypad through the slot from the front and stick it in place. You can use male to female wires for this one, or just stick some header pins inside the keypad connector to attach the jumper wires, then plug them into pins 0-7 as shown in the image.

Once they are plugged in, turn on the box. When you get to the Enter Code prompt, try typing the code in. If the wrong keys show up, you've probably got it wires backwards, so just flip them around.

At this point you can take the box outside and test the GPS as well.

Step 9: Servos and Key Switches

Almost done!

The doors are locked by 3 micro servos. The side door servos are mounted sideways so that the doors are prevented from falling open. When the door is opened, the servo moves out of the way and the door will drop open. This part can be opened if the user sticks something small inside the top of the door and pushes the servo out of the way, but hopefully they won't get crafty. The main compartment can't be opened this way.

Servo 1 goes under the 1 on the top of the lid. The orange wire goes to pin 10, brown to gnd, and red to 5v. Servo 2 goes on the opposite side and the orange wire goes to pin 11. Servo 3 goes in the middle slot and goes to pin 12. The mounts are set up to use the mounting screws that come with the servos.

See the images to view how the servos are mounted in place. Use the single arm attachment that is included with each servo. To make sure they are oriented correctly, turn the box on and enter the initialize code to move each servo into the locked position. Then put the arms on as they are shown in the pictures here.

The last item to wire up are the key switches. Solder 2 jumper wires to them like on the power switch. For the 1 side, plug one wire into gnd and the other into pin 14. On the 2 side, use pin 15. Screw them in place and you're all wired up!

Step 10: Close It All Up

Screw the lid cover in place using the #4-40 1/2" flat head screws. The screw holes in the cover are countersunk so that the lid will close flat. Make sure that the box is in the locked state when you do this so that servo 3 fits in easily.

The hinges I used fit perfectly in the slots so that the box closes flat. I got them from Lowes and they were pretty cheap. This also prevents the box from being opened by removing the hinges. Use the screws that come with the hinges here.

Close the box and enter the initialize code. You'll have to hold the side doors closed as you do this until the servos lock in place. Once you load the final version of the code onto the Arduino (if you haven't already), put the battery cover in place using #4-40 1/2" round head screws. You're all done!

Step 11: Gift Time!

Load up gifts into the box and run the initialize code to lock it all up. Now it is ready for a treasure hunt!

For my family, I simply hid the codes in a 6x6 grid of numbers and let them brute force finding it by going through each code one by one. A lot of you are more clever than I am and will think of better ways to hide the codes. Let me know how you do it!

3D Printing Contest 2016

Runner Up in the
3D Printing Contest 2016