fbpx

Maze Solver Robot

A Maze solving robot is one such clever Robot, it can perform tasks intelligently without any human assistance. A maze solving robot is quite similar to a line follower and a maze is a collection of paths through which the robot find a route to reach the destination from the start point.

The Robot solves a line maze in the following steps.

  1. First, the Robot travels through the entire maze and records the path it has taken to reach the end of the maze.
  2. Second Once the robot found a possible maze solution, using an algorithm the robot finds the “shortest path from start to finish”.

BLOCK DIAGRAM

WORKING

A-Line Maze is usually a black line on a white background and it could also be a white line on a black background. Each Line Maze has a Start point and finish point. The Robot is expected to follow the lines and find its way from start to finish.

Line Maze can be solved using any one of the rules.

Left-Hand rule – Always prefer a left turn over going straight ahead or taking a right turn and prefers going straight over going right.

Right-Hand rule – Always prefer a right turn over going straight ahead or taking a left turn and prefers going straight over going left.

We going to use five IR sensor as an eye of the robot to detect the path.

Looking at the picture, we can realize that the possible actions at intersections are:

  • At a “Cross” : Go to Left, or Go to Right, or Go Straight
  • At a “T” : Go to Left or Go to Right
  • At a “Right Only”: Go to Right
  • At a “Left Only”: Go to Left
  • At “Straight or Left”: Go to Left or Go Straight
  • At “Straight or Right”: Go to Right or Go Straight
  • At a “Dead End”: Go back (“U-turn”)
  • At “End of Maze”: Stop

We going to use “Left-Hand Rule”,so by applying that rule the actions will be reduced to one option each:

  • At a “Cross”: Go to Left
  • At a “T”: Go to Left
  • At a “Right Only”: Go to Right
  • At a “Left Only”: Go to Left
  • At a “Straight or Left”: Go to Left
  • At a “Straight or Right”: Go Straight
  • At a “Dead End”: Go back (“U-turn”)
  • At the “End of Maze”: Stop

SOLUTION AT INTERSECTION

The problem is when the robot finds a “LINE” it can either be a “Cross” (1) or a “T” (2). Also when it reaches a “LEFT or RIGHT TURN”, those can be a simple turn (options 3 or 4) or options to go straight (5 or 6). To discover exactly on what type of intersection the robot is, an additional step must be taken: the robot must run an “extra inch” and see what is next.

The possible actions are:

  1. At a “DEAD END”:
    • Go back (“U-turn”)
  2. At a “LINE”:
    • Run an extra inch
    • If there is a line: It is a “Cross” ==> Go to LEFT
    • If There is no line: it is a “T” ==> Go to LEFT
    • If there is another line: it is the “End of Maze” ==> STOP
  3. At a “RIGHT TURN”:
    • Run an extra inch
    • if there is a line: It is a Straight or Right ==> Go STRAIGHT
    • If there is no line: it is a Right Only ==> Go to RIGHT
  4. At a “LEFT TURN”:
    • Run an extra inch
    • if there is a line: It is a Straight or LEFT ==> Go to LEFT
    • If there is no line: it is a LEFT Only ==> Go to LEFT

Required Components

  1. Bread Board.
  2. Connecting wires.
  3. Castor wheel.
  4. Robot Wheel.
  5. Robot Chasis.
  6. Motor Driver l293d.
  7. DC Geared or BO motor
  8. Arduino
  9. Battery
  10. LM7805
  11. Switch
  12. Capacitors 470uf & 100uf.
  13. IR Sensor.

PinMapping

 Between Arduino and L293D

Between Motor and L293D

Between Arduino &  IR Sensors

CIRCUIT DIAGRAM

Software Requirements

1.Arduino IDE

FLOWCHART

PROGRAM

 /**** MAZE Sensor Array Pin Definition ******/
#define leftFarSensor 13
#define leftNearSensor 12
#define CenterSensor 11
#define rightNearSensor 7
#define rightFarSensor 6

/********* MAZE Sensor Array Value **********/
int leftNearReading;
int leftFarReading;
int CenterReading;
int rightNearReading;
int rightFarReading;

/********* DC Motor Pin Definition **********/
#define leftMotor1 2
#define leftMotor2 3
#define rightMotor1 4
#define rightMotor2 5

int leftNudge;
int replaystage;
int rightNudge;

#define leapTime 200

char path[30] = {};

int pathLength;
int readLength;

#define DEBUG 0
void setup()
{
/* initilize sensor pin */
pinMode(leftNearSensor, INPUT);
pinMode(leftFarSensor, INPUT);
pinMode(CenterSensor, INPUT);
pinMode(rightNearSensor,INPUT);
pinMode(rightFarSensor, INPUT);

/* initilize motor pin */
pinMode(leftMotor1, OUTPUT);
pinMode(leftMotor2, OUTPUT);
pinMode(rightMotor1, OUTPUT);
pinMode(rightMotor2, OUTPUT);
}

void loop()
{ 
readSensors(); 
if((leftFarReading == LOW) && (rightFarReading == LOW) && (CenterReading == HIGH || leftNearReading == HIGH))
{ 
straight(); 
}
else
{ 
leftHandWall(); 
}
}

void readSensors()
{
leftNearReading = digitalRead(leftNearSensor);
leftFarReading = digitalRead(leftFarSensor);
CenterReading = digitalRead(CenterSensor);
rightNearReading = digitalRead(rightNearSensor);
rightFarReading = digitalRead(rightFarSensor); 

#ifdef DEBUG
Serial.print("leftCenterReading: ");
Serial.println(leftCenterReading);
Serial.print("leftNearReading: ");
Serial.println(leftNearReading);
Serial.print("leftFarReading: ");
Serial.println(leftFarReading);
Serial.print("rightCenterReading: ");
Serial.println(rightCenterReading);
Serial.print("rightNearReading: ");
Serial.println(rightNearReading);
Serial.print("rightFarReading: ");
Serial.println(rightFarReading);
delay(200); 
#endif
}

void leftHandWall()
{ 
if(leftFarReading == HIGH && rightFarReading == HIGH)
{
digitalWrite(leftMotor1, HIGH);
digitalWrite(leftMotor2, LOW);
digitalWrite(rightMotor1, HIGH);
digitalWrite(rightMotor2, LOW);
delay(300);

readSensors();

if(leftFarReading == LOW && rightFarReading == LOW)
{
turnLeft();
}
else
{ 
done();
}
} 
if(leftFarReading == HIGH)
{ 
digitalWrite(leftMotor1, HIGH);
digitalWrite(leftMotor2, LOW);
digitalWrite(rightMotor1, HIGH);
digitalWrite(rightMotor2, LOW);
delay(300);

readSensors();
if(leftFarReading == LOW && rightFarReading == LOW)
{
turnLeft();
}
else
{
done();
}
}
if(rightFarReading == HIGH)
{
digitalWrite(leftMotor1, HIGH);
digitalWrite(leftMotor2, LOW);
digitalWrite(rightMotor1, HIGH);
digitalWrite(rightMotor2, LOW);
delay(300);

readSensors();
if(leftFarReading == HIGH)
{
delay(leapTime-30);
readSensors(); 
if(rightFarReading == HIGH && leftFarReading == HIGH)
{
done();
}
else if(rightFarReading == LOW && leftFarReading == LOW && CenterReading == LOW && rightNearReading == LOW)
{
turnRight();
}
else
{
straight();
return;
}
}
delay(leapTime-30);
readSensors();
if(leftFarReading == LOW && CenterReading == LOW && rightFarReading == LOW)
{
turnRight();
return;
}
path[pathLength]='S';
#ifdef DEBUG
Serial.println("s");
#endif
pathLength++;
#ifdef DEBUG
Serial.print("Path length: ");
Serial.println(pathLength);
#endif
if(path[pathLength-2]=='B')
{
#ifdef 
Serial.println("shortening path");
#endif 
shortPath();
}
straight();
}
readSensors();
if(leftFarReading == LOW && CenterReading == LOW && rightFarReading == LOW && leftNearReading == LOW && rightNearReading == LOW)
{
turnAround();
}
}

void done()
{
digitalWrite(leftMotor1, LOW);
digitalWrite(leftMotor2, LOW);
digitalWrite(rightMotor1, LOW);
digitalWrite(rightMotor2, LOW);
replaystage=1;
path[pathLength]='D';
pathLength++;
delay(1500);
replay();
}

void turnLeft()

{
while(digitalRead(leftNearSensor) == HIGH)
{
digitalWrite(leftMotor1, LOW);
digitalWrite(leftMotor2, LOW);
digitalWrite(rightMotor1, HIGH);
digitalWrite(rightMotor2, LOW);
delay(2);
digitalWrite(leftMotor1, LOW);
digitalWrite(leftMotor2, LOW);
digitalWrite(rightMotor1, LOW);
digitalWrite(rightMotor2, LOW);
delay(1);
}
while(digitalRead(leftNearSensor) == LOW)
{
digitalWrite(leftMotor1, LOW);
digitalWrite(leftMotor2, LOW);
digitalWrite(rightMotor1, HIGH);
digitalWrite(rightMotor2, LOW);
delay(2);
digitalWrite(leftMotor1, LOW);
digitalWrite(leftMotor2, LOW);
digitalWrite(rightMotor1, LOW);
digitalWrite(rightMotor2, LOW);
delay(1);
}
while(digitalRead(leftFarSensor) == HIGH && digitalRead(leftNearSensor) == HIGH)
{
digitalWrite(leftMotor1, LOW);
digitalWrite(leftMotor2, LOW);
digitalWrite(rightMotor1, HIGH);
digitalWrite(rightMotor2, LOW);
delay(2);
digitalWrite(leftMotor1, LOW);
digitalWrite(leftMotor2, LOW);
digitalWrite(rightMotor1, LOW);
digitalWrite(rightMotor2, LOW);
delay(1);
}

if(replaystage==0)
{
path[pathLength]='L';
#ifdef DEBUG
Serial.println("l");
#endif
pathLength++;
#ifdef DEBUG
Serial.print("Path length: ");
Serial.println(pathLength);
#endif
if(path[pathLength-2]=='B')
{
Serial.println("shortening path");
shortPath();
}
}
}

void turnRight()
{
while(digitalRead(rightNearSensor) == HIGH)
{
digitalWrite(leftMotor1, HIGH);
digitalWrite(leftMotor2, LOW);
digitalWrite(rightMotor1, LOW);
digitalWrite(rightMotor2, LOW);
delay(1);
digitalWrite(leftMotor1, LOW);
digitalWrite(leftMotor2, LOW);
digitalWrite(rightMotor1, LOW);
digitalWrite(rightMotor2, LOW);
delay(1);
}
while(digitalRead(rightNearSensor) == LOW)
{
digitalWrite(leftMotor1, HIGH);
digitalWrite(leftMotor2, LOW);
digitalWrite(rightMotor1, LOW);
digitalWrite(rightMotor2, LOW);
delay(1);
digitalWrite(leftMotor1, LOW);
digitalWrite(leftMotor2, LOW);
digitalWrite(rightMotor1, LOW);
digitalWrite(rightMotor2, LOW);
delay(1);
}
while(digitalRead(leftNearSensor) == LOW)
{
digitalWrite(leftMotor1, HIGH);
digitalWrite(leftMotor2, LOW);
digitalWrite(rightMotor1, LOW);
digitalWrite(rightMotor2, LOW);
delay(1);
digitalWrite(leftMotor1, LOW);
digitalWrite(leftMotor2, LOW);
digitalWrite(rightMotor1, LOW);
digitalWrite(rightMotor2, LOW);
delay(1);
}

if(replaystage==0)
{
path[pathLength]='R';
#ifdef DEBUG
Serial.println("r");
#endif
pathLength++;
#ifdef DEBUG
Serial.print("Path length: ");
Serial.println(pathLength);
#endif
if(path[pathLength-2]=='B')
{
Serial.println("shortening path");
shortPath();
}
}
}

void straight()
{
if( digitalRead(leftNearSensor) == LOW)
{
digitalWrite(leftMotor1, HIGH);
digitalWrite(leftMotor2, LOW);
digitalWrite(rightMotor1, HIGH);
digitalWrite(rightMotor2, LOW);
delay(1);
digitalWrite(leftMotor1, HIGH);
digitalWrite(leftMotor2, LOW);
digitalWrite(rightMotor1, LOW);
digitalWrite(rightMotor2, LOW);
delay(1);
return;
}
if(digitalRead(rightNearSensor) == LOW)
{
digitalWrite(leftMotor1, HIGH);
digitalWrite(leftMotor2, LOW);
digitalWrite(rightMotor1, HIGH);
digitalWrite(rightMotor2, LOW);
delay(1);
digitalWrite(leftMotor1, LOW);
digitalWrite(leftMotor2, LOW);
digitalWrite(rightMotor1, HIGH);
digitalWrite(rightMotor2, LOW);
delay(1);
return;
}
digitalWrite(leftMotor1, HIGH);
digitalWrite(leftMotor2, LOW);
digitalWrite(rightMotor1, HIGH);
digitalWrite(rightMotor2, LOW);
delay(1);
digitalWrite(leftMotor1, LOW);
digitalWrite(leftMotor2, LOW);
digitalWrite(rightMotor1, LOW);
digitalWrite(rightMotor2, LOW);
delay(1);
}

void turnAround()
{
digitalWrite(leftMotor1, HIGH);
digitalWrite(leftMotor2, LOW);
digitalWrite(rightMotor1, HIGH);
digitalWrite(rightMotor2, LOW);
delay(100);
while(digitalRead(leftNearSensor) == LOW || digitalRead(CenterSensor) == LOW)
{
digitalWrite(leftMotor1, LOW);
digitalWrite(leftMotor2, HIGH);
digitalWrite(rightMotor1, HIGH);
digitalWrite(rightMotor2, LOW);
delay(1);
digitalWrite(leftMotor1, LOW);
digitalWrite(leftMotor2, LOW);
digitalWrite(rightMotor1, LOW);
digitalWrite(rightMotor2, LOW);
delay(1);
}
path[pathLength]='B';
pathLength++;
straight();
#ifdef DEBUG 
Serial.println("b");
Serial.print("Path length: ");
Serial.println(pathLength); 
#endif
}

void shortPath()
{
int shortDone=0;
if(path[pathLength-3]=='L' && path[pathLength-1]=='R')
{
pathLength-=3;
path[pathLength]='B';
#ifdef DEBUG
Serial.println("test1");
#endif
shortDone=1;
}
if(path[pathLength-3]=='L' && path[pathLength-1]=='S' && shortDone==0)
{
pathLength-=3;
path[pathLength]='R';
#ifdef DEBUG 
Serial.println("test2");
#endif 
shortDone=1;
}
if(path[pathLength-3]=='R' && path[pathLength-1]=='L' && shortDone==0)
{
pathLength-=3;
path[pathLength]='B';
#ifdef DEBUG
Serial.println("test3");
#endif
shortDone=1;
}
if(path[pathLength-3]=='S' && path[pathLength-1]=='L' && shortDone==0)
{
pathLength-=3;
path[pathLength]='R';
#ifdef DEBUG 
Serial.println("test4");
#endif 
shortDone=1;

}
if(path[pathLength-3]=='S' && path[pathLength-1]=='S' && shortDone==0)
{
pathLength-=3;
path[pathLength]='B';
#ifdef DEBUG 
Serial.println("test5");
#endif 
shortDone=1;
}
if(path[pathLength-3]=='L' && path[pathLength-1]=='L' && shortDone==0)
{
pathLength-=3;
path[pathLength]='S';
#ifdef DEBUG 
Serial.println("test6");
#endif 
shortDone=1;
}

path[pathLength+1]='D';
path[pathLength+2]='D';
pathLength++;
#ifdef DEBUG 
Serial.print("Path length: ");
Serial.println(pathLength);
printPath();
#endif
}

void printPath()
{
Serial.println("----------------");
int x;
while(x<=pathLength)
{
Serial.println(path[x]);
x++;
}
Serial.println("-----------------");
}

void replay()
{
readSensors();
if(leftFarReading == LOW && rightFarReading == LOW)
{
straight();
}
else
{
if(path[readLength]=='D')
{
digitalWrite(leftMotor1, HIGH);
digitalWrite(leftMotor2, LOW);
digitalWrite(rightMotor1, HIGH);
digitalWrite(rightMotor2, LOW);
delay(100);
digitalWrite(leftMotor1, LOW);
digitalWrite(leftMotor2, LOW);
digitalWrite(rightMotor1, LOW);
digitalWrite(rightMotor2, LOW);
endMotion();
}
if(path[readLength]=='L')
{
digitalWrite(leftMotor1, HIGH);
digitalWrite(leftMotor2, LOW);
digitalWrite(rightMotor1, HIGH);
digitalWrite(rightMotor2, LOW);
delay(300);
turnRight();
}
if(path[readLength]=='L')
{
digitalWrite(leftMotor1, HIGH);
digitalWrite(leftMotor2, LOW);
digitalWrite(rightMotor1, HIGH);
digitalWrite(rightMotor2, LOW);
delay(300);
turnLeft();
}
if(path[readLength]=='S')
{
digitalWrite(leftMotor1, HIGH);
digitalWrite(leftMotor2, LOW);
digitalWrite(rightMotor1, HIGH);
digitalWrite(rightMotor2, LOW);
delay(300);
straight();
}
readLength++;
}
replay();
}

void endMotion()
{
endMotion();
}


 

Leave a Reply

Your email address will not be published. Required fields are marked *