Introduction: Simple Arduino Maze Robot for Project Based Learning

Every summer since 2019 at Providence Classical Christian School I have been running a tech camp for elementary and middle school aged students. A few years ago I wanted to find a simple project to use project based learning to teach my tech campers how to write simple Arduino code. I went searching on Intructables and found this 3D Printed Maze Controlled by Your Android Device. I loved the look and the idea, but the coding was too advanced for my newbie tech campers (not to mention me) and it also required more expensive parts and Android phones to control. With this project as my inspiration, I went to Tinkercad and redesigned the entire robot from scratch. I decided that using a little video game controller joystick would be much easier for my students to code and also cheaper to build. Since I had zero Arduino coding experience, I went looking on YouTube for someone to teach me me how to write simple Arduino code for joysticks and servos. This is when I found Paul McWhorter. After watching a few of his videos (and drinking some iced coffee), I was able to come up with something simple enough to understand myself, and simple enough to teach a group of upper elementary aged students who would be writing code for the first time. At the end of tech camp week, each tech camper had built and coded their own maze robot. Now I am here sharing my successful project based learning experience with the Instructables community. I hope you enjoy it!

Instructables Maze Robot Model

Supplies

All links are to Amazon, but most of these parts can be purchased for much less on AliExpress or Temu. The screws and rivets are probably best found at your local hardware store.

Instructables Maze Robot 3d Printed Parts

Step 1: Teacher Prep Step 1 - Print 3D Printed Parts

Print 1 of each of the 3d printed parts for each student. I used neon yellow PLA Pro from ZIRO on my Ender 3 Pro. I recommend 0.2 mm layer height or smaller, with 20% infill using the gyroid infill pattern. Use 2 perimeter (wall) layers or you may find that the holes are too tight. I tried with 3 before and started having difficulty fitting all the parts. You should be able to print without supports on most printers.

If you'd like to extend this project further, take a look at step 14. In some cases, you may consider having your students customize their 3d printed parts before printing. However, consider how much time you have first. It took me almost 15 hours to print all the parts at 0.16 layer height on my Ender 3. If you have a more advanced printer you may be able to do so much faster.

Step 2: Teacher Prep Step 2 - Make the Power Wires

This step eliminates the need for a breadboard to power all the different parts. In the future I may redesign it to use an Arduino Nano and a breadboard, but the jumper wires were cheaper.

To make the power jumper wires, splice 1 male to male jumper wire with 1 male to female jumper wire. Cut them in half and solder them together so that one end is male and the other end is 1 female and 2 male ends. Use some electrical tape to insulate the connection between the wires.

Although the color is not essential, using the same colors will make your kits match the provided student guide.

Step 3: Teacher Prep Step 3 - Prepare Kits

I found it best to compile all the materials and put them together in a bag (gallon freezer bags work well) or a box for each student. I pre-screwed all of the M2 screws where they would be going to make it simpler for the students to assemble and to prevent them from getting lost. The students can then just remove them and put them back in when they are attaching the various parts. I have also provided a PDF student guide that can be printed and distributed to each student during your own class.


TIP: The little M2 black screws I used from Amazon were a nightmare. They stripped often and some of the heads broke off. You want to make sure your screws are screwing in smoothly before you put your kits together. If you find they are too tight, you may want to adjust the Tinkercad file for the holes, or heat up a small nail and melt the holes a little bigger. I made the mistake of printing with 3 walls instead of 2 and this made my holes especially small.

Step 4: Student Building Steps 1-6

Distribute the kits and guides and assist the students in building the first part of their maze robot. In these steps they will screw in the Arduino board, attach the base cover, and attach the joystick.

Step 5: Student Step 7 - Connect the Power

In this step the students will use the power jumper wires you made in step 2 to power the various components of the maze robot. The single male end of the black wire will go to the GND on the Arduino board. The single male end of the red wire will go to the 5V input on the Arduino board. The female end will go to the GND and 5V on the joystick. The male ends will match up with the servo connectors (red to red and black to brown).

Step 6: Student Step 8-10 - Maze Robot Programming Part 1

When I did this step with my students, I provided them with the same student guide I am providing you. I also projected the guide on a TV and explained what each part did as we went. The guide provides a detailed explanation for each step the students complete. The students had to type it in themselves using the Arduino IDE program and the guide they had sitting next to them. The last page of the guide provides the text of the completed program. As I was explaining it to the students, I had to keep reiterating the importance of syntax. "A computer only understands certain things and only does what you tell it to do," I would tell them. I explained to them that although we think of computers as being very smart, they are actually pretty dumb, they just follow a lot of instructions quickly.

From the student guide:

Step 8:

First you need to tell the Arduino how to use servos. You do this by adding the servo library and giving your servos names.

Type this:

#include <Servo.h>

Servo Xservo;
Servo Yservo;

Next you will tell the Arduino all of your variables. Arduino won’t know how to do anything unless you first do this.

They will look like this:

int var=#;

int = integer (a math word that means whole number)

var = variable (a data item that may take on more than one value during the runtime of a program)

Var can be anything you want, but it should make sense to you.

Our first 2 variables will tell our Arduino information about our joystick.

Type this:

int VRXpin=A0;
int VRYpin=A1;

VRX is the pin on our joystick and A0 is analog input 0 on the Arduino.

VRY is another pin on our joystick and A1 is analog input 1 on the Arduino.


Step 9:

void setup() is the section where we write the instructions that Arduino will do only once when we first plug it in.

We will first define our pins so the Arduino will know what we connected to it and what it should do with it.

pinMode(VRXpin, INPUT);
pinMode(VRYpin, INPUT);

VRXpin is the variable we set at the beginning that defines our VRX joystick being connected to A0 on our Arduino. We are now telling the Arduino that this is an input. This tells the Arduino to look for information from our joystick when we move it. Later we will also define outputs so it will know how to talk to our servos to move. VRYpin is for when we move the joystick the other direction.

X = move left to right

Y = move up and down


Step 10:

void loop () is where we write the instructions that will run over and over until we turn it off.

We will be telling the Arduino to move our servos (OUTPUT) a certain way when we move the joystick (INPUT).

Our first instruction will take a number from the joystick, plug it into a math equation and solve it. Then it will use the answer to that math equation to tell the servo where to move.

You will type:

Xval=analogRead(VRYpin);
WVx=(Xrange/1023.)*Xval*(-1)+Xrange+adjustX;
Yval=analogRead(VRXpin);
WVy=(Yrange/1023.)*Yval+adjustY;

***You might notice that our VRXpin and VRYpin are working with the opposite servo. This is because we are using the joystick backwards to fit into our robot.

Step 7: Student Step 11-13 - Maze Robot Programming Part 2

Remind the students that they must put a semicolon ; after each line of code or the program will not work.


From the student guide:


Step 11:

These are the rest of your variables.

int XServoPin=9; 
int YServoPin=10;

These variables tell the Arduino where you connected the servos.

int WVx; 
int Wy;

WV stands for "Write Value". Each of these define the variable used to tell the angle to which the servo will move. These numbers will be the answer to the math equation Arduino is solving using the number given from the joystick.

int Xval; 
int Yval;

These define the variables that will be the numbers coming from the joysticks

int dt=100;

dt stands for "delay time". This variable defines the wait time in the program.

int Xrange=10; 
int Yrange=20;

These define the range of how far the servos will move. Without these the servo would move so far that it would launch the ball.

int adjust×= 0; 
int adjustY=0;

These variables are used to adjust our servos so that they point straight up and balance the maze.


Step 12:

These are the rest of your setup instructions that your program will only run once.

pinMode(XServoPin, OUTPUT);
pinMode(YServoPin, OUTPUT);

These instructions tell the Arduino pins 9 and 10 are outputs going to the 2 servos.

Xservo.attach(XServoPin);
Yservo.attach(YServoPin);
}

These instructions attach our servos so that they can be controlled as a servo.

Be sure this sections ends with a bracket }


Step 13:

These are the rest of your instructions.

Xservo.write(WVx);
Yservo.write(WVy);

Remember WVx and WVy are the answers to the math equations solved by Arduino using the numbers inputed by the joystick. These instructions use WVx and WVy and write those values to the servos to make them move. Without these instructions, your servos wouldn’t do anything.

delay(dt);
}

This tells the Arduino to wait just a little bit before it repeats these instructions. Remember that everything in “void loop()” will repeat over and over until you turn it off.

Notice that the section ends with a }.

If you forget your ; and }, your robot won’t work.

Step 8: Student Step 14 - Wiring the Maze Robot

In this step the students will use the provided page from the guide to wire up the rest of their maze robot. This is where using the same color jumper wires is helpful. The green wire will go from VRy on the joystick to A1 on the Arduino. The blue wire will go from VRx on the joystick to A0 on the Arduino.

The yellow wire will connect to digital pin 9 and to the servo that will control the X axis.

The orange wire will connect to digital pin 10 and to the servo that will control the Y axis.

Step 9: Student Step 15-18 - Preparing the Servos

Step 15:

Label the servo arms with X and Y.


Step 16:

Plug in the USB cable to the maze robot and to the computer. You will have to go to "Tools" and "Board" to choose "Arduino Uno". Then go to "Tools" and "Port" and make sure that the USB for your computer is checked. This should allow the Arduino IDE software to communicate with the maze robot.

Once connected, click on the check button to make sure your code is written correctly. If you saw "Done compiling" on the green bar, then you are in good shape.

Next, click on the button with the arrow pointing to the right. This will upload the program to the maze robot.

Now you can move the joystick to see if anything happens. If the servos move, then you have done something right.

Move the joystick left and right to make sure you know which servo is the X servo. If it isn't the servo attached to pin 9, double check the wiring.


Step 17:

Move the joystick again, but this time up and down. This will help you identify the Y servo attached to pin 10.


Step 18:

Attach the X servo arm to the X servo and the Y servo arm to the Y servo.

Step 10: Student Step 19-21 - Adjust the X and Y

Step 19:

Move the joystick left and right and up and down. When the joystick is in the center, both servo arms should be pointing

straight up. If they aren’t you have to adjust the code in your program.

Go to the top section of your code and look for

int adjustX=0;
int adjustY=0;

Go up or down 1 number at a time. adjustX is probably between 20 and 25. adjustY is probably between 4 and 10.

Like this:

int adjustX=23;
int adjustY=7;

When you are finished, unplug the robot from the computer.

TIP: Using a level during this step proved very helpful for me. Negative numbers can also be used when making adjustments if necessary.


Step 20:

MAKE SURE YOU NEVER MOVE THE SERVO ARMS BY HAND. IT WILL BREAK THE SERVOS.

Remove the servo arms.


Step 21:

Attach the X and Y gimbal pieces using the two 4-40 x 1/2" machine screws and nuts. Line up the holes with the arrows and use these holes for the screws. You will notice that the X and Y gimbals are perpendicular.

IMPORTANT: Make sure that the gimbals are oriented exactly the same way as the picture. Failure to do so will result in the joystick moving the maze in the opposite direction of what is expected. I made this mistake at least once.

Step 11: Student Step 22-30 - Complete Robot Assembly

The students will use the guide to finish assembling the maze robot. Depending on your 3d printer, it may be helpful to pre-screw all of these holes to make sure it screws in smoothly. I did find that using precision screw drivers proved challenging for some students. Also, you want to stress to the students that they not move the robot by hand or it will damage the servos. This is especially important when the robot is powered.

Once assembled, the robots can be powered through the USB on the computer or Arduino compatible battery boxes may be used.

Here is a sample of a battery holder you might use.

Step 12: Student - Final Adjustments

You want to make sure your maze is balanced.

Go back to the top section of your code and look again for 

int adjustX=0;
int adjustY=0;

Go up or down 1 number at a time. adjustX may be between 20 and 25 and adjustY may be between 4 and 10.

Like this:

int adjustX=23;
int adjustY=7;


REMINDER: If you try out your maze robot and the joystick is moving the maze in the opposite direction, you have attached the gimbals backwards. See the picture to make sure you have aligned them properly.

TIP: A level is helpful during this step also.

Step 13: Sign Your Work

Sign the end of your code like this:

// Coded by John Doe


Your completed code should look something like this:

#include <Servo.h>

Servo Xservo;
Servo Yservo;

int VRXpin=A0;
int VRYpin=A1;

int XServoPin=9;
int YServoPin=10;

int WVx;
int WVy;

int Xval;
int Yval;

int dt=100;

int Xrange=10;
int Yrange=20;

int adjustX=0;
int adjustY=0;

void setup() {

pinMode(VRXpin, INPUT);
pinMode(VRYpin, INPUT);

pinMode(XServoPin, OUTPUT);
pinMode(YServoPin, OUTPUT);

Xservo.attach(XServoPin);
Yservo.attach(YServoPin);
}

void loop() {

Xval=analogRead(VRYpin);
WVx=(Xrange/1023.)*Xval*(-1)+Xrange+adjustX;
Yval=analogRead(VRXpin);
WVy=(Yrange/1023.)*Yval+adjustY;

Xservo.write(WVx);
Yservo.write(WVy);

delay(dt);
}

// Coded by John Doe

Step 14: Customize the Maze?

If you want to take this further with your students, you may want to consider letting them add their name or decorations to the 3d printed pieces in Tinkercad. You could also allow them to make their own maze to replace the provided maze. I made my maze by first using MazeGenerator.net and then downloading my generated maze as an SVG file. The SVG file can then be imported into Tinkercad and adjusted to fit the maze robot. I didn't have my students do this because I only had one week, a slow 3d printer, and 12 students. If you have your students make their own maze, have them make sure that the 1/4" ball will still fit and won't get stuck anywhere.


Future Feature: If I had to do it again, I'd probably redesign the maze so that it attached with magnets so that the mazes could be switched out and shared between students.


Have fun!!!

Project-Based Learning Contest

Third Prize in the
Project-Based Learning Contest