Introduction: 3D Printed Maze Controlled by Your Android Device

This project started as a demonstration of the HC-05 bluetooth board for our Teen Imagineering Club . We wanted to show how we can use it to connect an Arduino to an Android device. We looked around the web for ideas and this project is the result. It turned out nice so we thought we would share.

The maze is controlled by tilting the Android device. The Android device orientation sensor data is transmitted through the bluetooth connection to the Arduino which controls the servos that tilt the maze. On the Android side the program is created with MIT App Inventor 2 and on the Arduino side we used the Arduino IDE . As with most projects we borrowed ideas and solutions from others and made them work for this project. Here is a partial group of links.

You have a choice if you take on this project. You can use our 3D files, Arduino code, and Android app and make a cool project. The better choice is to customize the project by learning about the maze generator and how it works in Blender and then dig into App Inventor 2 and learn to build your own custom apps. Either way I hope you have fun.

Step 1: Parts and Tools


The 3D print stl files are available on Thingiverse - thing:1451703

You will need:

  • 1x maze_generator08 (or make your own by following nimaid's work)
  • 1x maze_base_arduino
  • 1x gimbal_base_arduino
  • 2x gimbal_center
  • 1x gimbal_base
  • 2x servo_wire_keeper

In addition to the 3D prints you will need the following hardware. All of the electronics can be found at our favorite supplier, or from other web sources.


  • 3D printer - or have the parts made
  • 3D part cleaning tools
  • Hot glue gun
  • Screwdriver and pliers

Step 2: Our Maze or Design Your Own?

You can print our maze stl or you can learn how to make your own by following the directions on nimaids 3D maze generator Thingiverse page. The maze generator uses a Python script within Blender. We had never used Blender before but within an hour we were creating custom mazes so give it a try. For our project using a 1/4" ball these are the setting we used.

  • width = 15
  • length = 15
  • cellThickness = 7 mm
  • wallThickness = 0.8 mm (this number should be 2 times your printer nozzle diameter)
  • wallHeight = 7 mm
  • baseHeight = 1 mm
  • punchEntranceExit = False
  • dualExtrusion = False

FYI - The print time for the maze goes up an extraordinary amount if you choose a wall thickness greater than two times your nozzle diameter.

Step 3: Clean Your 3D Parts and Assemble the Maze - Part 1

To create the movements to work the maze we are building a 2-axis gimbal mount controlled by the 2 sg-90 servos. There are 4 pieces to the gimbal - top, bottom, and 2 center sections. The center sections will need to be cleaned to as per the drawing. We will use the single sided servo arm that came with the servo. Fit into slot and attach with one of the larger screws that came with the servo. The head of the screw will be on the inside of the upright and with the point fastening through one of the holes in the arm. After tightening you can clip the point with side cutters if you have them. Repeat for second center part. Attach the center halves (with the uprights rotated 90 degrees) with (2) 4-40 screws and nuts.

Step 4: Assemble Your Maze - Part 2

We like the extra pin groups on the RoboRed Arduino. It allows us to build this project without breadboards or soldering. If you use a regular Arduino you will have to modify the wiring to fit your need.

Test fit your Arduino into the base. Ours fit snug so I did not fasten the board in. The gimbal bottom is attached to the base with a little hot glue. The narrow arms should be on the single foot side as in photos.

Step 5: Assemble Your Maze - Part 3

Attach the gimbal top to the bottom of the maze. An easy way to get it centered is to draw an X from corner to corner as shown in the photo. You know the gimbal top is centered when its corners fall on the lines. We hot glued the gimbal top to the bottom of the maze.

Afterthought: With the ability to easily create different mazes a less permanent way to attach the maze may be better. Neodymium magnets might work well here.

The 2 servos are attached to the gimbal top and bottom with a little hot glue. Press the servos so that the glue layer is as thin as possible. They should be oriented as shown in the photo.

Before we connect the gimbal centers we are going to connect the servos to the Arduino (RoboRed) and run a centering sketch. We use the VarSpeedServo Arduino library to slow down the servos. If you don't already have the library you need to download the file below and unzip to your arduino/libraries folder.

Plug the bottom servo into the pin 6 group and the top servo into the pin 7 group of the RoboRed. Now download the file below and unzip to your Arduino directory. Open the sketch in the Arduino IDE. Connect the computer to the board and upload code. With the code running the servo shafts will stay centered while we attach the gimbal centers.

Attach the gimbal center section to the bottom servo. Lightly spread the forks to get them in place. I used 1/8x 5/16 rivets as a pivot but a short length of 1/8 rod will work as well. Use the small screw that came with the servo to fasten the servo arm to the servo shaft. Repeat for the top servo and you should have your maze looking like the finished photo above.

Because of the teeth on the servo shaft you are not likely to have a perfectly level maze when finished. You can adjust the pitchHm and rollHm variables in this section of code and reload the sketch until you are level,

const int svsp = 10;   //speed setting for VarSpeedServo SlowMove
const int pitchHm = 90;   //set so pitch direction is level
const int rollHm = 90;    //set so roll direction is level

Write these values down. You will enter them in the full code before you upload it,

Step 6: Adding the HC-05 (or HC-06) Bluetooth Module

I wanted to use the SoftwareSerial library to communicate with the Bluetooth so I would not have to unplug the Bluetooth when uploading programs. After trying it that way I found that SoftwareSerial and Servos don't play well together and cause the servos to jitter like crazy. I investigated and found it is a known issue and I could not find a good work around so we used the regular hardware serial connection.

We mounted the HC-05 bluetooth module with a dab of hot glue as shown in the photo. After the full sketch is up loaded .to the board use 4 strands of the female flat cable to connect the RoboRed serial data pins (see photo above) to the HC-06 as follows:

  • RX - TX
  • TX - RX
  • VCC - VCC
  • GND - GND

Step 7: Programming the Arduino

We created an Android App using App Inventor 2 that will capture the pitch and roll data from the android orientation sensor. It is then divided by 3 and rounded to the nearest whole number (this make the Android movements less sensitive). Then it is transmitted through the bluetooth connection to the Arduino with the following format pitch,roll/n with a comma separating the 2 integers and ending with a new line character (/n). We will show you how we made that code in the next step but first lets discuss the Arduino sketch.

For the Arduino code download the file below and unzip to your Arduino directory. Open the sketch in the Arduino IDE. Enter the pitchHm and rollHm numbers you found in step 5 to make your maze bed level. Make sure the bluetooth module is not connected then connect the computer to the board via the serial port and upload code.

Using the Read ASCII String Arduino tutorial as a guide we built a sketch loop that retrieves the pitch and roll data form the bluetooth connection. It then constrains the angles to +/- 15 degrees to keep things reasonable. The sketch then moves the servos to the pitch and roll angles.

FYI- Depending on the way you assembled your 2 gimbal center pieces you may need to change the - to a + on the code line indicated in the photo above.

Step 8: Programming the Android

Download the imagineering_maze.apk file below on your Android device and follow the instructions at the bottom of this link concerning installation of non-market applications. If you have no interest in learning how easy it was to create our maze control app or how you can create your own then you can skip the rest of this step.

This is our first experience with MIT App Inventor 2 ( AI2 ) but the learning curve was not bad. The code blocks work a lot like the ones in Scratch which we use a lot. AI2 is an online editor that lets you design your apps in your computer browser and test them out on your Android through a wifi connection without having to install each change. To look inside our code, get your AI2 account setup, then download the imagineering_maze.aia file to your computer. Remember .apk files are apps that run on your Android and .aia files are AI2 design files that work on your computer.

From your AI2 projects screen click Projects, select Import project (.aia) from my computer and navigate to the imagineering_maze.aia file (probably in downloads). You should now have our maze project on your computer. Lets take a look.

In the design tab (toggle between design and blocks using buttons in the upper right of the screen) you see we have just 2 visible components (ListPicker1 , Canvas1) and 3 non-visible components (OrientationSensor1 , BluetoothClient1 , Clock1). These are all we need as once we get the bluetooth paired we don't need to touch the screen again because the orientation controls the program.

Switch to the blocks tab and we will discuss the different groups of code blocks starting from the top.

The first group is there to handle a pesky error message that pops up saying "bluetooth not connected" even when it obviously is because you are controlling the maze. Others have mentioned this on the forums but no solutions are given so we just replace the message with a blank one.

The second group populates the listpicker with the available or past bluetooth connections when the listpicker is tapped.

The third group of blocks runs after you choose a connection from the list. It first disconnects any previous connection as a precaution. Then it attemps to connect with the connection you chose.

The fourth group is a timer that checks once a second to see if you are connected or not and displays the result in the listpicker text area.

The fifth group of blocks is where we look for orientation sensor changes and send the new positions over the bluetooth connection in the format the Arduino is expecting.

Try connecting your android device using the AI companion and see what the screen looks like. You can power up the Arduino (if you have the sketch loaded) and try the maze control.

We looked at many tutorials to get the pieces we needed to get our app working but in the end it is really simple to put it together. We hope you try your own app.

Step 9: Putting It All Together

We added a couple of finishing touches to the project. I had some 3/8" stick on non-slip pads that I had got at Home Depot. I added them to the feet to raise it up a little and give it a better grip. I also designed a servo wire keeper to tidy up the servo wires. Its available on Thingiverse. You may have to scale it up or down a bit to get the right fit depending on your 3D printer.

If you have followed the steps you should have your maze built, your Arduino (RoboRed) loaded with the maze_control_bt sketch, and your Android App ready to go ( either the .apk installed or the ,aia running on AI companion ). All that is left is to power the Arduino, tap the connect button and then solve the maze. If your front to back motion is wrong check the FYI at the bottom of step 7.

Let us know if you have any questions or comments and let us know if you build your own

Make it Move Contest 2016

Runner Up in the
Make it Move Contest 2016

Robotics Contest 2016

Second Prize in the
Robotics Contest 2016

Gaming Contest

Participated in the
Gaming Contest