MAZE ROBOT

Published Sep 17, 2022
 18 hours to build
 Beginner

This maze robot move on its own by by detecting gap in between the maze with human intervension

display image

Components Used

Arduino UNO
Arduino UNO
1
Ultrasonic Module HC-SR04
Ultrasonic module HC-SR04 is generally used for finding distance value and obstacle detection. It can operate in the range 2cm-400cm.
3
Metal Chasis for a Mini Robot Rover
Robotics Kits Anodized Aluminum Metal Chasis for a Mini Robot Rover
1
LED Mounting Hardware
LED Mounting Hardware LED Mount Self Ret 3mm Black .925 inch
1
9V Battery
Consumer Battery & Photo Battery 9V RECTANGLE
1
Male to Female Jumper Wire
Jumper Wires Mach pin jumper wires
26
Male to Male Jumper Wire
Jumper Wires Mach pin jumper wires
1
Female to Female Jumper Wire
Jumper Wires Mach pin jumper wires
1
USB Type A to B Cable
USB Cables / IEEE 1394 Cables USB A-B 28/26 BLACK 1.3 M
1
DC Gearbox Motor
Adafruit Accessories DC Gearbox Motor - TT Motor - 200RPM - 3 to 6VDC
2
Wheel for DC Gearbox Motors
Adafruit Accessories Skinny Wheel for TT DC Gearbox Motors
2
Description

The project maze robot is mini sized arduino based robot which automatically find its route between the gaps of the maze. This intelligence is provide to this robot by the programming the arduino with c/c++ code. The arduino in this maze will acts brain of this robot and the LM296 driver is a dual H-Bridge motor driver which allows speed and direction control of two DC motors at the same time. The wheels are attached to  the motor to activate the rotation by suppling the power from 12v battery. The battery and motors are connected  LM296 driver. The direction of the wheel controlled by LM296 driver through motor. 


PREREQUISITE KNOWLEDGE:

  • Basic knowledge in c/c++
  • `Basic of IoT

WORKING METHOD OF MAZE ROBOT

PROGRAMMING PLATFORM:

This Arduino code can be used to solve a simple maze.  The code will also need to adapt from maze to maze, and it usually involves a lot of trial and error to have the robot navigate successfully.

After assembling the robot, upload the Maze solver source codeto your Arduino from the IDE.

Arduino_Maze_Solver_JW_MP_image7.png

  • I have used the left side ultrasonic sensor as the supporting sensor to align the robot to the left sidewall. The robot always follows the left wall when solving the maze.
  • If the front sensor detects an obstacle, the robot has to change direction immediately.

The microcontroller using in developing this maze robot is Arduino. We can programme Arduino using Arduino ide an open source platform for coding. By using simple C or C++ language we can code in Arduino ide which dumped in Arduino after successful stimulation by using the code Arduino can controls the motion and designation of robot by passing the instruction.

  • SENSOR FUNCTION:   
void readLFSsensors()
{
 LFSensor[0] = digitalRead(lineFollowSensor0);
 LFSensor[1] = digitalRead(lineFollowSensor1);
 LFSensor[2] = digitalRead(lineFollowSensor2);
 LFSensor[3] = digitalRead(lineFollowSensor3);
 LFSensor[4] = digitalRead(lineFollowSensor4);
 
 farRightSensor = analogRead(farRightSensorPin);
 farLeftSensor = analogRead(farLeftSensorPin);
 
 if     ((LFSensor[0]== 1 )&&(LFSensor[1]== 1 )&&(LFSensor[2]== 1 )&&(LFSensor[3]== 1 )&&(LFSensor[4]== 1 ))  {mode = CONT_LINE; error = 0;}
 else if((LFSensor[0]== 0 )&&                                                   (farRightSensor < THRESHOLD)) {mode = RIGHT_TURN; error = 0;}
 else if ((farLeftSensor <  THRESHOLD)                                                  &&(LFSensor[4]== 0 )) {mode = LEFT_TURN; error = 0;}
 else if((LFSensor[0]== 0 )&&(LFSensor[1]== 0 )&&(LFSensor[2]== 0 )&&(LFSensor[3]== 0 )&&(LFSensor[4]== 0 ))  {mode = NO_LINE; error = 0;}
 else if((LFSensor[0]== 0 )&&(LFSensor[1]== 0 )&&(LFSensor[2]== 0 )&&(LFSensor[3]== 0 )&&(LFSensor[4]== 1 ))  {mode = FOLLOWING_LINE; error = 4;}
 else if((LFSensor[0]== 0 )&&(LFSensor[1]== 0 )&&(LFSensor[2]== 0 )&&(LFSensor[3]== 1 )&&(LFSensor[4]== 1 ))  {mode = FOLLOWING_LINE; error = 3;}
 else if((LFSensor[0]== 0 )&&(LFSensor[1]== 0 )&&(LFSensor[2]== 0 )&&(LFSensor[3]== 1 )&&(LFSensor[4]== 0 ))  {mode = FOLLOWING_LINE; error = 2;}
 else if((LFSensor[0]== 0 )&&(LFSensor[1]== 0 )&&(LFSensor[2]== 1 )&&(LFSensor[3]== 1 )&&(LFSensor[4]== 0 ))  {mode = FOLLOWING_LINE; error = 1;}
 else if((LFSensor[0]== 0 )&&(LFSensor[1]== 0 )&&(LFSensor[2]== 1 )&&(LFSensor[3]== 0 )&&(LFSensor[4]== 0 ))  {mode = FOLLOWING_LINE; error = 0;}
 else if((LFSensor[0]== 0 )&&(LFSensor[1]== 1 )&&(LFSensor[2]== 1 )&&(LFSensor[3]== 0 )&&(LFSensor[4]== 0 ))  {mode = FOLLOWING_LINE; error =- 1;}
 else if((LFSensor[0]== 0 )&&(LFSensor[1]== 1 )&&(LFSensor[2]== 0 )&&(LFSensor[3]== 0 )&&(LFSensor[4]== 0 ))  {mode = FOLLOWING_LINE; error = -2;}
 else if((LFSensor[0]== 1 )&&(LFSensor[1]== 1 )&&(LFSensor[2]== 0 )&&(LFSensor[3]== 0 )&&(LFSensor[4]== 0 ))  {mode = FOLLOWING_LINE; error = -3;}
 else if((LFSensor[0]== 1 )&&(LFSensor[1]== 0 )&&(LFSensor[2]== 0 )&&(LFSensor[3]== 0 )&&(LFSensor[4]== 0 ))  {mode = FOLLOWING_LINE; error = -4;}
 
 Serial.print (farLeftSensor);
 Serial.print (" <== LEFT  RIGH==> ");
 Serial.print (farRightSensor);
 Serial.print ("  mode: ");
 Serial.print (mode);
 Serial.print ("  error:");
 Serial.println (error);
   
}
void readLateralSensors(void)
{
 
}
  • MAZE FUNCTION: 
void mazeSolve(void)
{
   while (!status)
   {
       readLFSsensors();  
       switch (mode)
       {   
         case NO_LINE:  
           motorStop();
           goAndTurn (LEFT, 180);
           recIntersection('B');
           break;
         
         case CONT_LINE: 
           runExtraInch();
           readLFSsensors();
           if (mode != CONT_LINE) {goAndTurn (LEFT, 90); recIntersection('L');} // or it is a "T" or "Cross"). In both cases, goes to LEFT
           else mazeEnd(); 
           break;
           
        case RIGHT_TURN: 
           runExtraInch();
           readLFSsensors();
           if (mode == NO_LINE) {goAndTurn (RIGHT, 90); recIntersection('R');}
           else recIntersection('S');
           break;   
           
        case LEFT_TURN: 
           goAndTurn (LEFT, 90); 
           recIntersection('L');
           break;   
        
        case FOLLOWING_LINE: 
           followingLine();
           break;      
       
        }
   }
}
void recIntersection(char direction)
{
 path[pathLength] = direction; // Store the intersection in the path variable.
 pathLength ++;
 simplifyPath(); // Simplify the learned path.
}

void mazeEnd(void)
{
 motorStop();
 BT1.print("The End  ==> Path: ");
 for(int i=0;i<pathLength;i++)
   BT1.print(path[i]);
   //Serial.print(path[i]);
 BT1.println("");
 Serial.print("  pathLenght ==> ");
 Serial.println(pathLength);
 status = 1;
 mode = STOPPED;
}

void followingLine(void)
{

  calculatePID();
  motorPIDcontrol();   
}
void simplifyPath()
{
 if(pathLength < 3 || path[pathLength-2] != 'B')
   return;
 int totalAngle = 0;
 int i;
 for(i=1;i<=3;i++)
 {
   switch(path[pathLength-i])
   {
     case 'R':
       totalAngle += 90;
break;
     case 'L':
totalAngle += 270;
break;
     case 'B':
totalAngle += 180;
break;
   }
 }
 totalAngle = totalAngle % 360;
 switch(totalAngle)
 {
   case 0:
path[pathLength - 3] = 'S';
break;
   case 90:
path[pathLength - 3] = 'R';
break;
   case 180:
path[pathLength - 3] = 'B';
break;
   case 270:
path[pathLength - 3] = 'L';
break;
 }

 pathLength -= 2;
 
}
void mazeOptimization (void)
{
 while (!status)
 {
   readLFSsensors();  
   switch (mode)
   {
     case FOLLOWING_LINE:
       followingLine();
       break;    
     case CONT_LINE:
       if (pathIndex >= pathLength) mazeEnd (); 
       else {mazeTurn (path[pathIndex]); pathIndex++;}
       break;  
     case LEFT_TURN:
       if (pathIndex >= pathLength) mazeEnd (); 
       else {mazeTurn (path[pathIndex]); pathIndex++;}
       break;  
     case RIGHT_TURN:
       if (pathIndex >= pathLength) mazeEnd (); 
       else {mazeTurn (path[pathIndex]); pathIndex++;}
       break;   
   }    
  }  
}
void mazeTurn (char dir) 
{
 switch(dir)
 {
   case 'L': // Turn Left
      goAndTurn (LEFT, 90);      
      break;   
   
   case 'R': // Turn Right
      goAndTurn (RIGHT, 90);     
      break;   
      
   case 'B': // Turn Back
      goAndTurn (RIGHT, 800);     
      break;   
      
   case 'S': // Go Straight
      runExtraInch(); 
      break;
 }
}

 

SOURCE CODE FOR MAZE ROBOT:

int motor_lA = 9;
int motor_lB = 10;
int motor_enableA = 11;
int motor_rA = 3;
int motor_rB = 4;
int motor_enableB = 5;
int trigger_front = A0;
int echo_front = A1;
int trigger_left = A2;
int echo_left = A3;
int trigger_right = A4;
int echo_right = A5;

void setup() {
 // put your setup code here, to run once:
 pinMode(motor_lA,OUTPUT);   //left motors forward
 pinMode(motor_lB,OUTPUT);   //left motors reverse
 pinMode(motor_enableA, OUTPUT);
 pinMode(motor_rA,OUTPUT);   //right motors forward
 pinMode(motor_rB,OUTPUT);   //rignt motors reverse
 pinMode(motor_enableB, OUTPUT);
 pinMode(trigger_front,OUTPUT);
 pinMode(echo_front,INPUT);
 pinMode(trigger_left,OUTPUT);
 pinMode(echo_left,INPUT);
 pinMode(trigger_right,OUTPUT);
 pinMode(echo_right,INPUT);
 
 analogWrite(motor_enableA, 80);
 analogWrite(motor_enableB, 88);
}
void loop() {
 // put your main code here, to run repeatedly:
 Serial.begin(9600);
 long duration_front, distance_front, duration_left, distance_left, duration_right, distance_right;
   
 //Calculating distance
 
 digitalWrite(trigger_front, LOW);
 delayMicroseconds(2);
 digitalWrite(trigger_front, HIGH);
 delayMicroseconds(10);
 digitalWrite(trigger_front, LOW);
 duration_front = pulseIn(echo_front, HIGH);
 distance_front= duration_front*0.034/2;
 digitalWrite(trigger_left, LOW);
 delayMicroseconds(2);
 digitalWrite(trigger_left, HIGH);
 delayMicroseconds(10);
 digitalWrite(trigger_left, LOW);
 duration_left = pulseIn(echo_left, HIGH);
 distance_left= duration_left*0.034/2;
 digitalWrite(trigger_right, LOW);
 delayMicroseconds(2);
 digitalWrite(trigger_right, HIGH);
 delayMicroseconds(10);
 digitalWrite(trigger_right, LOW);
 duration_right = pulseIn(echo_right, HIGH);
 distance_right= duration_right*0.034/2;
 Serial.print("front = ");
 Serial.println(distance_front);
 Serial.print("Left = ");
 Serial.println(distance_left);
 Serial.print("Right = ");
 Serial.println(distance_right);  
 delay(50);

 if (distance_front >20){
   forward();
   
   if(distance_left > 10&& distance_left<20){
     forward();
   }
   if(distance_left >=20){
      left();
      delay(30);
      forward();
   }
   if(distance_left<10 && distance_left>0){
     right();
     delay(30);
     forward();
   }
} 
 
 if(distance_front<=20&& distance_right > 20){
   Stop();
   delay(1000);
   right();
   delay(400);
   
 }
 if(distance_front<=20 && distance_right<20){
   Stop();
   delay(1000);
   right();
   delay(800);
  
 }
 
 
}
void forward()
{
 digitalWrite(motor_lA,1);
 digitalWrite(motor_lB,0);
 digitalWrite(motor_rA,1);
 digitalWrite(motor_rB,0);
 delay(1000);
}

void right(){
 digitalWrite(motor_lA,1);
 digitalWrite(motor_lB,0);
 digitalWrite(motor_rA,0);
 digitalWrite(motor_rB,1);
delay(10);
}

void left(){
 digitalWrite(motor_lA,0);
 digitalWrite(motor_lB,1);
 digitalWrite(motor_rA,1);
 digitalWrite(motor_rB,0);
 delay(10);
}

void Stop(){
 digitalWrite(motor_lA,0);
 digitalWrite(motor_lB,0);
 digitalWrite(motor_rA,0);
 digitalWrite(motor_rB,0);
 delay(300);
}

After successful stimulation, dump the code in the Arduino. 

INSTRUCTION:

>Dump the code for maze robot in the Arduino using USB cable.

>Required components -   

HARDWARE 

  1. ARUDINO
  2. LM296 Driver
  3. Ultrasonic Distance sensor
  4. Motors
  5. 9 or 12V battery
  6. Breadboard       
  7. Jumper wires

SOFTWARE

  1. Arduino ide                                                           

>Make the connection with LM296 driver,ultrasonic distance sensor, motors, battery by using jumper wires and breadboard by refering circuit diagram.

>Before connecting the components make sure that the compnents are good enough.

  CIRCUIT DIAGRAM:

 

Interfacing Ultrasonic Sensors to Arduino

Wire the trigger pin and echo pin of the sensors to analog pins of the Arduino. To power up the sensors, connect all the ground pins to a common ground rail and all the 5V pins to a common 5V rail on the breadboard. 

Arduino_Maze_Solver_JW_MP_image9.png

Interfacing the Motor Driver to Arduino

The motor driver has seven screw terminals, which makes the interfacing easy. 

Arduino_Maze_Solver_JW_MP_image13.png

 

 

The L298N dual H-Bridge motor driver helps us to control the speed and direction of the two DC motors simultaneously. It acts as an interface between the motor and the Arduino. The motor driver has 4 input pins to control the rotational direction of the motor. ‘Enable A’ and ‘Enable B’ pins have the responsibility to enable and control the speed of the motors.

 LM296 driver:

The LM2596 regulator is monolithic integrated circuit ideally suited for easy and convenient design of a step−down switching regulator (buck converter). It is capable of driving a 3.0 A load with excellent line and load regulation. This device is available in adjustable output version and it is internally compensated to minimize the number of external components to simplify the power supply design. Since LM2596 converter is a switch−mode power supply, its efficiency is significantly higher in comparison with popular three−terminal linear regulators, especially with higher input voltages. The LM2596 operates at a switching frequency of 150 kHz thus allowing smaller sized filter components than what would be needed with lower frequency switching regulators.

Ultrasonic sensor:

An ultrasonic sensor is an electronic device that measures the distance of a target object by emitting ultrasonic sound waves, and converts the reflected sound into an electrical signal. Ultrasonic waves travel faster than the speed of audible sound (i.e. the sound that humans can hear). Ultrasonic sensors have two main components: the transmitter (which emits the sound using piezoelectric crystals) and the receiver (which encounters the sound after it has travelled to and from the target).

The formula for this calculation is D = ½ T x C (where D is the distance, T is the time, and C is the speed of sound ~ 343 meters/second).

This above diagram illustrate the circuit diagram  of the maze robot.

                                                                    FINAL WORKING MODEL

 

image                                 

This is the working model of the maze robot.

These types of autonomous mobile robots can be used in a wide variety of applications such as material handling, warehouse management, pipe inspection, and bomb disposal.

Codes

Downloads

MAZEROBOT Download
Comments
Ad