Introduction: MAZE SOLVING ROBOT
It is a line following robot designed to control its movement at specific junctions.
This robot was made to participate in NERC 2023, which had two distinct tracks, so I created two distinct codes. Delays in the code are used to fill in gaps between the black lines on the track.
Supplies
TT Gear Motors x 2
L298N Motor Driver x 1
Arduino UNO x 1
IR sensors x 5
Jumper wires
Bread-Board
Acrylic car kit
Step 1: Circuit Construction
Motor Driver pins:
IN-1 = 7
IN-2 = 8
IN-3 = 9
IN-4 = 10
EN-A = 6
EN-B = 5
IR Sensors:
Right most = 11
Right = 12
Middle = 2
Left = 3
Left most = 4
Wall = 13
Step 2: Sensor Alignment
Align as only the middle sensor must be on the black line and the right and left sensors just beyond the black line. Right and left most sensors must be far away so if the robot deviates during a gap it may catch the black line.
Step 3: Tracks
These are the two tracks, one involves only left turns and one involves only right turns.
When the ir sensor for the wall detects a wall the robot takes a quarter circle turn and returns back to the black line.
Attachments
Step 4: Code-1
TRACK WITH ONLY LEFT TURNS:
//only for left turns
#define IR1 11 //right most sensor
#define IR2 12 //right sensor
#define IR3 2 //middle sensor
#define IR4 3 //left sensor
#define IR5 4 //left most sensor
#define IR6 13
#define MOTOR_SPEED 164
//Right motor
int enableRightMotor=6;
int rightMotorPin1=7;
int rightMotorPin2=8;
//Left motor
int enableLeftMotor=5;
int leftMotorPin1=9;
int leftMotorPin2=10;
int walls =0;
void setup()
{
//This sets frequecny as 7812.5 hz.
TCCR0B = TCCR0B & B11111000 | B00000010 ;
// put your setup code here, to run once:
pinMode(enableRightMotor, OUTPUT);
pinMode(rightMotorPin1, OUTPUT);
pinMode(rightMotorPin2, OUTPUT);
pinMode(enableLeftMotor, OUTPUT);
pinMode(leftMotorPin1, OUTPUT);
pinMode(leftMotorPin2, OUTPUT);
pinMode(IR1, INPUT);
pinMode(IR2, INPUT);
pinMode(IR3, INPUT);
pinMode(IR4, INPUT);
pinMode(IR5, INPUT);
pinMode(IR6, INPUT);
rotateMotor(0,0);
}
void loop()
{
int ir1 = digitalRead(IR1);
int ir2 = digitalRead(IR2);
int ir3 = digitalRead(IR3);
int ir4 = digitalRead(IR4);
int ir5 = digitalRead(IR5);
int ir6 = digitalRead(IR6);
//If none of the sensors detects black line, then go straight
if (ir1 == LOW && ir2 == LOW && ir3 == HIGH && ir4 == LOW && ir5 == LOW)
{
rotateMotor(MOTOR_SPEED, MOTOR_SPEED);
}
//If right sensor detects black line, then turn right
else if (ir1 == LOW && ir2 == HIGH && ir3 == HIGH && ir4 == LOW && ir5 == LOW)
{
rotateMotor(MOTOR_SPEED/4.8, MOTOR_SPEED);
}
//If right sensor detects black line, then turn right
else if (ir1 == LOW && ir2 == HIGH && ir3 == LOW && ir4 == LOW && ir5 == LOW)
{
rotateMotor(MOTOR_SPEED/4.8, MOTOR_SPEED);
}
//If left sensor detects black line, then turn left
else if (ir1 == LOW && ir2 == LOW && ir3 == HIGH && ir4 == HIGH && ir5 == LOW)
{
rotateMotor(MOTOR_SPEED, MOTOR_SPEED/4.8);
}
//If left sensor detects black line, then turn left
else if (ir1 == LOW && ir2 == LOW && ir3 == LOW && ir4 == HIGH && ir5 == LOW)
{
rotateMotor(MOTOR_SPEED, MOTOR_SPEED/4.8);
}
//If left sensor detects black line, then turn left
else if (ir1 == LOW && ir2 == LOW && ir3 == HIGH && ir4 == HIGH && ir5 == HIGH)
{
rotateMotor(MOTOR_SPEED, -MOTOR_SPEED);
}
//If left sensor detects black line, then turn left
else if (ir1 == LOW && ir2 == LOW && ir3 == LOW && ir4 == LOW && ir5 == HIGH)
{
rotateMotor(MOTOR_SPEED, -MOTOR_SPEED);
}
//If left sensor detects black line, then turn left
else if (ir1 == LOW && ir2 == HIGH && ir3 == HIGH && ir4 == HIGH && ir5 == HIGH)
{
rotateMotor(MOTOR_SPEED, -MOTOR_SPEED);
}
//If left sensor detects black line, then turn left
else if (ir1 == LOW && ir2 == HIGH && ir3 == HIGH && ir4 == HIGH && ir5 == LOW)
{
rotateMotor(MOTOR_SPEED, -MOTOR_SPEED);
}
//If left sensor detects black line, then turn left
else if (ir1 == LOW && ir2 == LOW && ir3 == LOW && ir4 == HIGH && ir5 == HIGH)
{
rotateMotor(MOTOR_SPEED, -MOTOR_SPEED);
}
//If left sensor detects black line, then turn right
else if (ir1 == HIGH && ir2 == LOW && ir3 == LOW && ir4 == LOW && ir5 == LOW)
{
rotateMotor(-MOTOR_SPEED, MOTOR_SPEED);
}
//If left sensor detects black line, then turn right
else if (ir1 == HIGH && ir2 == HIGH && ir3 == LOW && ir4 == LOW && ir5 == LOW)
{
rotateMotor(-MOTOR_SPEED, MOTOR_SPEED);
}
//If left sensor detects black line, then turn right
else if (ir1 == HIGH && ir2 == HIGH && ir3 == HIGH && ir4 == LOW && ir5 == LOW)
{
rotateMotor(-MOTOR_SPEED, MOTOR_SPEED);
}
//If all the sensors detects black line, then go left
if (ir1 == HIGH && ir2 == HIGH && ir3 == HIGH && ir4 == HIGH && ir5 == HIGH)
{
rotateMotor(MOTOR_SPEED, -MOTOR_SPEED);
}
else if (ir6 == LOW)
{
rotateMotor(MOTOR_SPEED/1.2, MOTOR_SPEED*1.2);
delay(3000);
}
//If all sensors are on white
else if (ir1 == LOW && ir2 == LOW && ir3 == LOW && ir4 == LOW && ir5 == LOW && ir6 == LOW)
{
rotateMotor(MOTOR_SPEED, MOTOR_SPEED);
delay(2200);
}
}
void rotateMotor(int rightMotorSpeed, int leftMotorSpeed)
{
if (rightMotorSpeed < 0)
{
digitalWrite(rightMotorPin1,LOW);
digitalWrite(rightMotorPin2,HIGH);
}
else if (rightMotorSpeed > 0)
{
digitalWrite(rightMotorPin1,HIGH);
digitalWrite(rightMotorPin2,LOW);
}
else
{
digitalWrite(rightMotorPin1,LOW);
digitalWrite(rightMotorPin2,LOW);
}
if (leftMotorSpeed < 0)
{
digitalWrite(leftMotorPin1,LOW);
digitalWrite(leftMotorPin2,HIGH);
}
else if (leftMotorSpeed > 0)
{
digitalWrite(leftMotorPin1,HIGH);
digitalWrite(leftMotorPin2,LOW);
}
else
{
digitalWrite(leftMotorPin1,LOW);
digitalWrite(leftMotorPin2,LOW);
}
analogWrite(enableRightMotor, abs(rightMotorSpeed));
analogWrite(enableLeftMotor, abs(leftMotorSpeed));
}
Step 5: Code-2
TRACK WITH ONLY RIGHT TURNS:
//only for right turns
#define IR1 11 //right most sensor
#define IR2 12 //right sensor
#define IR3 2 //middle sensor
#define IR4 3 //left sensor
#define IR5 4 //left most sensor
#define IR6 13
#define MOTOR_SPEED 166.5
//Right motor
int enableRightMotor=6;
int rightMotorPin1=7;
int rightMotorPin2=8;
//Left motor
int enableLeftMotor=5;
int leftMotorPin1=9;
int leftMotorPin2=10;
int walls =0;
void setup()
{
//This sets frequecny as 7812.5 hz.
TCCR0B = TCCR0B & B11111000 | B00000010 ;
// put your setup code here, to run once:
pinMode(enableRightMotor, OUTPUT);
pinMode(rightMotorPin1, OUTPUT);
pinMode(rightMotorPin2, OUTPUT);
pinMode(enableLeftMotor, OUTPUT);
pinMode(leftMotorPin1, OUTPUT);
pinMode(leftMotorPin2, OUTPUT);
pinMode(IR1, INPUT);
pinMode(IR2, INPUT);
pinMode(IR3, INPUT);
pinMode(IR4, INPUT);
pinMode(IR5, INPUT);
pinMode(IR6, INPUT);
rotateMotor(0,0);
}
void loop()
{
int ir1 = digitalRead(IR1);
int ir2 = digitalRead(IR2);
int ir3 = digitalRead(IR3);
int ir4 = digitalRead(IR4);
int ir5 = digitalRead(IR5);
int ir6 = digitalRead(IR6);
//If none of the sensors detects black line, then go straight
if (ir1 == LOW && ir2 == LOW && ir3 == HIGH && ir4 == LOW && ir5 == LOW)
{
rotateMotor(MOTOR_SPEED, MOTOR_SPEED);
}
//If right sensor detects black line, then turn right
else if (ir1 == LOW && ir2 == HIGH && ir3 == HIGH && ir4 == LOW && ir5 == LOW)
{
rotateMotor(MOTOR_SPEED/4.5, MOTOR_SPEED);
}
//If right sensor detects black line, then turn right
else if (ir1 == LOW && ir2 == HIGH && ir3 == LOW && ir4 == LOW && ir5 == LOW)
{
rotateMotor(MOTOR_SPEED/4.5, MOTOR_SPEED);
}
//If left sensor detects black line, then turn left
else if (ir1 == LOW && ir2 == LOW && ir3 == HIGH && ir4 == HIGH && ir5 == LOW)
{
rotateMotor(MOTOR_SPEED, MOTOR_SPEED/4.5);
}
//If left sensor detects black line, then turn left
else if (ir1 == LOW && ir2 == LOW && ir3 == LOW && ir4 == HIGH && ir5 == LOW)
{
rotateMotor(MOTOR_SPEED, MOTOR_SPEED/4.5);
}
//If left sensor detects black line, then turn right
else if (ir1 == HIGH && ir2 == HIGH && ir3 == HIGH && ir4 == LOW && ir5 == LOW)
{
rotateMotor(-MOTOR_SPEED, MOTOR_SPEED);
}
//If left sensor detects black line, then turn right
else if (ir1 == HIGH && ir2 == HIGH && ir3 == HIGH && ir4 == HIGH && ir5 == LOW)
{
rotateMotor(-MOTOR_SPEED, MOTOR_SPEED);
}
//If left sensor detects black line, then turn right
else if (ir1 == LOW && ir2 == HIGH && ir3 == HIGH && ir4 == HIGH && ir5 == LOW)
{
rotateMotor(-MOTOR_SPEED, MOTOR_SPEED);
}
//If left sensor detects black line, then turn right
else if (ir1 == HIGH && ir2 == HIGH && ir3 == LOW && ir4 == LOW && ir5 == LOW)
{
rotateMotor(-MOTOR_SPEED, MOTOR_SPEED);
}
//If left sensor detects black line, then turn right
else if (ir1 == HIGH && ir2 == LOW && ir3 == LOW && ir4 == LOW && ir5 == LOW)
{
rotateMotor(-MOTOR_SPEED, MOTOR_SPEED);
}
//If left sensor detects black line, then turn left
else if (ir1 == LOW && ir2 == LOW && ir3 == LOW && ir4 == LOW && ir5 == HIGH)
{
rotateMotor(MOTOR_SPEED, -MOTOR_SPEED);
}
//If left sensor detects black line, then turn left
else if (ir1 == LOW && ir2 == LOW && ir3 == LOW && ir4 == HIGH && ir5 == HIGH)
{
rotateMotor(MOTOR_SPEED, -MOTOR_SPEED);
}
//If all the sensors detects black line, then go right
if (ir1 == HIGH && ir2 == HIGH && ir3 == HIGH && ir4 == HIGH && ir5 == HIGH)
{
rotateMotor(-MOTOR_SPEED, MOTOR_SPEED);
}
//If ir6 detects a wall
else if (ir6 == LOW)
{
rotateMotor(MOTOR_SPEED*1.2, MOTOR_SPEED/1.2);
delay(3000);
}
//If all sensors are on white
else if (ir1 == LOW && ir2 == LOW && ir3 == LOW && ir4 == LOW && ir5 == LOW && ir6 == LOW)
{
rotateMotor(MOTOR_SPEED, MOTOR_SPEED);
delay(2200);
}
}
void rotateMotor(int rightMotorSpeed, int leftMotorSpeed)
{
if (rightMotorSpeed < 0)
{
digitalWrite(rightMotorPin1,LOW);
digitalWrite(rightMotorPin2,HIGH);
}
else if (rightMotorSpeed > 0)
{
digitalWrite(rightMotorPin1,HIGH);
digitalWrite(rightMotorPin2,LOW);
}
else
{
digitalWrite(rightMotorPin1,LOW);
digitalWrite(rightMotorPin2,LOW);
}
if (leftMotorSpeed < 0)
{
digitalWrite(leftMotorPin1,LOW);
digitalWrite(leftMotorPin2,HIGH);
}
else if (leftMotorSpeed > 0)
{
digitalWrite(leftMotorPin1,HIGH);
digitalWrite(leftMotorPin2,LOW);
}
else
{
digitalWrite(leftMotorPin1,LOW);
digitalWrite(leftMotorPin2,LOW);
}
analogWrite(enableRightMotor, abs(rightMotorSpeed));
analogWrite(enableLeftMotor, abs(leftMotorSpeed));
}