Friday, October 7, 2022

Arduino controlled maze

For an index to all my articles click this text

Usually we go to France for our Hollidays. And a few years ago we went to a region called Jura. In this region were a lot of shops that sold wooden toys. And one of these toys intrigued me. It was a maze game.



As you can see the maze is suspended in a frame and the knobs at the front and side make it possible to tilt the maze horizontally and vertically. By tilting the maze you can make the ball move and the object is ofcourse to direct the ball to the exit. It was not the maze that intrigued me but the mechanism to tilt it in both directions.

When I made my gesture controller I immediately thought that it would be a nice project to build this maze and control it with the gesture controller. And on a rainy saturday I build a prototype which I am going to show you here.

Maze generation.

The first step in building a maze is designing one. Luckily you do not have to do that yourself. I quick search with Google revealed a number of on-line maze generators. A real easy one can be found at: https://xefer.com/maze-generator



As you can see I generated a maze with a width of 10 columns and a height of 10 rows. As cell size I chose 30. A larger figure for the cell size will make the picture bigger. But that is not really important, as you can see later on.

You can find another maze creating program on this website:
http://www.mazegenerator.net/Default.aspx
This one is in fact more extensive as it can also make circular mazes etc. Just choose the one you are most comfortable with.

When I created a good looking maze I pressed Prt SCR (print screen) on my keyboard and made a screendump.
I then pasted the screendump in a drawing program and I cut out the maze and then imported the maze into Office.
In Office I scaled the picture to what I needed  and then printed the maze.



Scaling the maze is important. I bought some black beads on a market and they were 1 cm in diameter. So the corridors of my maze should be at last 1 cm wide. To make sure the beads would not get stuck I decided to make the corridors 1,5 cm wide. For the walls of the maze I used cardboard which was approximately 3 mm thick. So a cooridor would be 1,5 cm + 3 mm = 1.8 cm. I rounded that to 2 cm for convenience. As my maze had 10 corridors the total width and height would be around 20 cm x 20 cm.

When the maze was printed i lay it on a piece of cardboard and with a pen pressed the lines of the maze into the carton. Next I used a pen to trace the lines in the carton so they would be clearly visible.



Next step was to cut carton strips with a height of 2 cm. With these strips I made the walls of the maze and the walls of the corridors in the maze. I just cut the strips to length and glued them with hotglue.



I realised that you would get bored with playing with the same maze all the time. So I made a larger container to put the maze in. That way I could build several mazes and exchange them without having to rebuild the complete construction.

Next step was to have the container moving.

The electronics

The maze should be tilted horizontally and vertically. I was going to use two servo's for that purpose.

As this is a simple setup I used an Arduino pro micro for this project. You could use any Arduino which has at least 6 IO ports free. Just adjust the software to the port numbering. I used actually the same Arduino micro I used for the mouse simulation with the gesture controller I used in this project:

http://lucstechblog.blogspot.com/2019/11/sw520-mouse-gesture-controller-part-2.html

The gesture controller itself was described in detail in this story:

http://lucstechblog.blogspot.com/2019/11/an-easy-gesture-controller.html


The gesture controller is attached to the Arduino pins D6, D7, D8 and D9. It is important that the wires from the Gesture Controller are attached to the right Arduino pins otherwise the movement of the construction is unpredictable. Use the following wiring schematic:

D6  attached to UP
D7  attached to DOWN
D8  attached to LEFT
D9  attached to RIGHT

The first servo is attached to pin 4 and that controls the UP and DOWN movement. The second servo is attached to pin 5 and that controls the LEFT and RIGHT movement.

The Software

The software is actually quite simple. It looks at the position of the Gesture Controller and sends the state (UP, DOWN, LEFT, RIGHT, NEUTRAL) to some program lines that translate these to servo angles.

Here is the complete program:



/*SW520 servo control
  Luc Volders

Decides which way the servos will go by checking
which SW520 makes contact and which does not

using 4 SW520 put in a square form
top:    D6
Bottom: D7
Left:   D8
Right:   D9
*/

#include <Servo.h> 
 
Servo myservo;  // create servo object  

Servo myservo2; // for second servo

int dig1, dig2, dig3, dig4;
int pos = 0;    // store servo position

void setup()
{
  Serial.begin(115200);
  myservo.attach(4);
  delay(50);
  myservo2.attach(5);
  delay(50);
  for(int i=70; i<110; i++)
  {
    myservo.write(i);
    myservo2.write(i);
    delay(30);
  }
}

void loop() 
  { 
  dig1 = digitalRead(6);
  dig2 = digitalRead(7);
  dig3 = digitalRead(8);
  dig4 = digitalRead(9);

    if( (dig1 == 1) & (dig2 ==1) & (dig3 ==1) & (dig4 ==1))
      {
      myservo.write(90);  // neutral position
      myservo2.write(90); // neutral position
      }
    
    if (dig1 == 0)
      {
    //going up
    myservo.write(110);  // servo to 20 deg up
      }

    if (dig2 == 0)
    {
    //going down
    myservo.write(70); // servo to 20 deg down
    }

    if (dig3 == 0)
      {
      //going left
      myservo2.write(110);  // 20 deg left
      }

    if (dig4 == 0)
      {
      //going right
      myservo2.write(70);  // 20 deg right
      }
    
  delay(300);
}

As always I will show you how the program works step by step.

#include <Servo.h> 
 
Servo myservo;  // create servo object 

Servo myservo2; // for second servo

The servo library is loaded and connected to two servo instances: myservo and myservo2

  myservo.attach(4);
  delay(50);
  myservo2.attach(5);
  delay(50);

In the setup() the servo instances are coupled to the actual pins where the servo's are connected to. The first servo will be connected to pin 4 and the second to pin 5.

  for(int i=70; i<110; i++)
  {
    myservo.write(i);
    myservo2.write(i);
    delay(30);
  }

Assuming that both servo's are in the starting position (90 degrees) we move them slowly to a position where the board will be slightly tilted (110 degrees). This way we are sure they work as planned.

The loop is where the Gesture Sensor is read and the sensors put in the position the Gesture Sensor indicates.

  dig1 = digitalRead(6);
  dig2 = digitalRead(7);
  dig3 = digitalRead(8);
  dig4 = digitalRead(9);

The values of the Gesture Sensor are read and put in some some helper variables.

    if( (dig1 == 1) & (dig2 ==1) & (dig3 ==1) & (dig4 ==1))
      {
      myservo.write(90);
      myservo2.write(90);
      }

If all inputs from the Gesture Sensor are 1 (HIGH) then the sensor is in the neutral position and the servos will put the maze in the horizontal position.

    if (dig1 == 0)
      {
    //going up
    myservo.write(110);  // servo to 20 deg up
      }

If the Gesture Sensor points in a direction the servo will tilt the maze slightly. In this case the Gesture Sensor points upwards so the servo will tilt 20 dregrees UP which is enough to get the bead rolling.


    if (dig2 == 0)
    {
    //going down
    myservo.write(70);  // servo to 20 deg down
    }

This is the same as the previous piece of code but now the Gesture Sensor points DOWN and the servo will tilt slightly in the other direction.

The same is repeated for the LEFT and RIGHT positions.

That is all.

A first test



The video shows how this works. As you can see tilting the Gesture Sensor moves the servo arms.

The construction

The maze is build and put in a container as described above.
Now make an open frame slightly larger as the container. Attach the servo to the frame and glue it to the container. As you can see I attached the servo on the left side and made a suspension on the opposite side. In this prototype the suspension was just a small stick of plastic: actually some filament from my 3D printer.

Last step is to put this contraption in a frame.


Ok, OK laugh at my primitive drawing capabilities but it shows how the frame which has the container inside is suspended in a standing frame. One servo is attached to the standing frame on the right side (the blue blob) the other servo is at the back attached to the inner frame as the foto showed.

Real life.

And here is how it works.


It is all very primitive and not nicely finished. But hey it is a prototype and it works !!!

Future enhancements.

Well I have some ideas to finish this. First the suspension at the opposite side of the servo's could be made with 8mm rods and bearings. These are both available from your diy 3D printer shop or DIY hardware store.

The maze itself could be 3D printed.

The software works flawlessly.
A first extension would be to replace the Arduino Pro Micro with an ESP8266 or ESP32 and control the maze through a website. The second extension could put an IP-camera above it, made with a Raspberry or ESP32) and you could have your family and friends operate the maze from all over the world......

Have fun !!!!
Till next time

Luc Volders