Table of Contents
This is important in robotics, especially for autonomous vehicles which we require to navigate on their own. The application commonly found in this domain is the Arduino uno specifications based obstacle avoiding car that detects obstacles with ultrasonic sensors and avoids it using servo motors. The ease of which they are able to explore environments without collisions, these cars are perfect for tasks such as surveillance or remote monitoring. Although this project uses the Arduino Uno, the car can be made from a Arduino Nano based on size requirements and power availability.
Project Overview
In this detailed tutorial on how to build an obstacle avoiding car using an Arduino Uno! Arduino Cost Our car is smarter at avoiding obstacles as we use a servo mounted ultrasonic sensor and thus can detect the obstacles not only in the front but also on sides simultaneously. An L298N DC motor driver will allow the four geared motors hooked to the wheels to be powered by this car as well. The frame and assembly of the car for this guide requires the use of a standard Arduino car kit.
Arduino Uno: Specifications
Ok, before we start digging into it, let’s take a look at the Arduino Uno specs that make it perfect for this project. The Arduino Uno comes equipped with:
-
- 6 PWM outputs (from 14 digital I/O pins).
-
- 6 Analog Inputs,
-
- A clock speed of 16 MHz,
-
- 32 KB Flash memory to store (code)
-
- An ATmega328P microcontroller powered it.
This means the Arduino Uno is powerful enough to track multiple inputs and outputs at once, something that is necessary for receiving signals from sensors, motors, LED’s, etc. in this obstacle avoiding car project.
Components Required
-
- To get started, you will need the following components:
-
- You will need Arduino Uno or Arduino Nano (What you prefer).
-
- 1x MG90 Metal Gear Servo Motor
-
- HC-SR04 Ultrasonic Sensor,
-
- RGB LEDs (3x),
-
- L298N Motor Driver,
-
- Laser cut chassis 2WD Arduino Car Kit.
-
- 12V Li-ion Battery,
-
- LM2596 DC-DC Buck Converter,
-
- Switch,
-
- Jumper Wires,
-
- Breadboard or PCB,
-
- Screws, Nuts, and Spacers.
-
- Working Principle of the Car
-
- The HC-SR04 Ultrasonic Sensor is the heart of the obstacle-avoiding car. How This Sensor Works: It emits ultrasonic sound waves at 40 kHz. If these waves hit an obstacle, they bounce back and the sensor will notice them. The Arduino works out how far away the car is from the obstacle by measuring how long it takes for the echo to come back. The Arduino turns the motors one way or another depending on the readings.
BUILDING Obstacle Avoiding Car
Step 1: Assembling the Car Kit
To build the body of your robot, you can use any off the shelf robotic car kit. These kits generally include a chassis, wheels, together with a mounting bracket for the electronic components. For this project, we’ve picked a more car like kit with front bumper, spoilers, etc. Projects such as a Human Following Robot and Pick and Place Arduino Robot Car used similar kits for your interest.
Step 2: Circuit Diagram
You need a carefully planned circuit for the project. An ultrasonic sensor is mounted on a servo motor such that directional measurements are allowed. The sensor sweeps from side to side, detecting objects ahead of and to the side of the car.
Servo Motor Connection
To connect the servo motor, plug the signal of the servo motor to any PWM pin on the Arduino Uno. The first being that you connect the power wire to the 5V output from the DC-DC converter and the ground wire to one of the Arduino’s GND pins.
Ultrasonic Sensor Connection
Then connect sensor VCC pin to 5V pin on Arduino, GND pin to ground and TRIG to digital pin 2 and ECHO to digital pin 4. By this point, the ultrasonic sensor is connected to the Arduino, so it can read distance from the sensor and process the data.
RGB LEDs Connection
Threading the RGB LED cathode (ground) of each of the LEDs to a common ground rail on the breadboard. Then connect A1, A2, and A3 to the LED’s red terminal, and digital pins 5, 6, and 13 to the green terminal. The advantage of this configuration is you can have the Arduino control the color of the RGB LEDs as you need.
L298N Motor Driver Connection
The L298N motor driver is what lets us control the motor of the car. Connect the breadboard’s positive rail to Arduino’s Vin and the breadboard’s ground rail to Arduino’s ground. Second, connect the 5V output from the LM2596 to the positive rail and the LM2596 ground to the ground rail. L298N’s IN1 and IN2 for the first motor needs to be connected to Arduino pins 7 and 8. Now to connect to the second motor, connect IN3 and IN4 to pins 12 and 11. Lastely connect L298N’s ENA and ENB pins to the Arduino PWM pins 9 and 10, enabling the independent control of each motor.
Power Connections
The positive terminal from 12V Li-ion battery is connected to the LM2596’s Vin input and negative terminal is connected to the ground rail of breadboard. Connect the battery’s positive terminal to L298N motor driver’s 12V input and the battery’s negative terminal to L298N’s ground pin as well.
Additional Enhancements
Additional features you could add, in order to improve the car’s design, include a power switch, a DC charging socket and a Li-ion battery level indicator. Coming from the back of the car is this indicator, featuring a slider switch that allows you to check the battery status without the need to power on the whole system. When you charge the battery, the switch goes into the ‘up’ position.
Arduino Uno Specifications: Why The Project Is Perfect for It?
In this project, Arduino Uno is a popular choice with its easy to use ATmega328P microcontroller and an easy to configure pin. Its specifications include:
Input voltage rang of 7–12V, operating voltage of 5V.
Enough flash memory to hold multiple lines of code, 32 KB, is provided.
We have 6 analog inputs with 10 bits of resolution which is ideal for reading sensor data,
14 digital I/O pins of which 6 can provide PWM output to control motors and LEDs.
A 16 MHz clock speed for responsible sensor data processing.
Final Steps and Precautions
Screw, nut and spacer all components to the car frame. Secure all connections so that short circuits do not occur. First, before powering on the circuit, double check the connection and you will confirm that it’s arduino power switch off.
Conclusion and Code
After you have made your Arduino based obstacle avoiding car, upload the code to the Arduino Uno. Here the HC-SR04 sensor is set up to find distances and output signals to the motor pins according to those distances. You can customize the code based on your needs, e.g. modify the threshold distance and adjust the speed control of the motor.
For this project, the Arduino Uno’s specifications are perfect, as it has a number of features available that make it more versatile with connection and controls. Now that everything is in order, your obstacle avoiding car is equipped to explore autonomously, without bumping into obstacles!
include
This block includes the Servo library, which is necessary for controlling the servo motor.
// Ultrasonic sensor pins
define trig 2
define echo 4
// RGB led pins
define LR 9 // Led Right
define LC 13 // Led Center
define LL 10 // Led Left
define LRR A3 // Led Right Red
define LCR A2 // Led Center Red
define LLR A1 // Led Left Red
In this block, various pin constants are defined for components such as the Ultrasonic sensor and RGB LEDs. These constants are used to specify which pins on the Arduino are connected to each component.
// Motor control pins
define LEFT_MOTOR_PIN1 8
define LEFT_MOTOR_PIN2 7
define RIGHT_MOTOR_PIN1 12
define RIGHT_MOTOR_PIN2 11
define ENA 6 // Enable A pin for motor speed control
define ENB 3 // Enable B pin for motor speed control
// Distance thresholds for obstacle detection
define MIN_DISTANCE_BACK 12
This block defines threshold values. MIN_DISTANCE_BACK represents the minimum distance required from an obstacle to stop.
void setup() {
// Set motor control pins as outputs
pinMode(LEFT_MOTOR_PIN1, OUTPUT);
pinMode(LEFT_MOTOR_PIN2, OUTPUT);
pinMode(RIGHT_MOTOR_PIN1, OUTPUT);
pinMode(RIGHT_MOTOR_PIN2, OUTPUT);
pinMode(ENA, OUTPUT);
pinMode(ENB, OUTPUT);
pinMode(LR, OUTPUT);
pinMode(LC, OUTPUT);
pinMode(LL, OUTPUT);
pinMode(LRR, OUTPUT);
pinMode(LCR, OUTPUT);
pinMode(LLR, OUTPUT);
digitalWrite(LR, LOW);
digitalWrite(LC, LOW);
digitalWrite(LL, LOW);
analogWrite(LRR, 0);
analogWrite(LCR, 0);
analogWrite(LLR, 0);
servoLook.attach(5);
//Set the Trig pins as output pins
pinMode(trig, OUTPUT);
//Set the Echo pins as input pins
pinMode(echo, INPUT);
analogWrite(ENA, 53.5); // speed for motor A 0-LOW speed, 255-Full speed
analogWrite(ENB, 45); // speed for motor B
// Initialize the serial communication for debugging
Serial.begin(9600);
}
In the setup() function, various initializations take place. This includes configuring motor control pins, LED pins, and sensor pins as either OUTPUT or INPUT. It also sets the initial states for LEDs and RGB LEDs to LOW or 0. Additionally, the Servo motor is attached to pin 5, motor speed is adjusted using analogWrite() for ENA and ENB, and serial communication is initiated for debugging (though this part is optional).
void loop()
{
servoLook.write(90);
delay(750);
int distance = getDistance();
if (distance >= MIN_DISTANCE_BACK)
{
moveForward();
Serial.println("forward"); }
while(distance >= MIN_DISTANCE_BACK)
{
distance = getDistance();
delay(50);
}
Stop();
int turnDir = checkDirection();
Serial.println(turnDir);
switch(turnDir)
{
case 0: //Turn left
Serial.println("Left");
turnLeft();
delay(425);
Stop();
break;
case 2: //Turn right
Serial.println("Right");
turnRight();
delay(415);
Stop();
break;
case 3: //move forward
Serial.println("Forward");
moveForward();
break;
}
}
These lines define digital pins of Arduino (pin7,pin8,pin12 and pin11) for the L298N motor driver inputs to control the DC motors. The pins in1 and in2 control one motor, and the pins in3 and in4 control the other motor. Ena and Enb control the speed of the motor.
This is the main loop of the code, executed continuously. The servo motor is set to look straight ahead, and there’s a delay for it to settle. The getDistance() function is used to measure the distance using the Ultrasonic sensor. If the measured distance is greater than or equal to MIN_DISTANCE_BACK, the robot is instructed to move forward. While the distance is above the threshold, it continues moving forward. When the distance becomes less than MIN_DISTANCE_BACK, the Stop() function is called to stop the robot.The checkDirection() function is used to determine if there’s an obstacle in the left, right, or front direction. Based on the detected direction, the robot will turn left, turn right, or move forward. Serial messages are printed to help with debugging.
int getDistance() //Measure the distance to an object{
unsigned long pulseTime; //Create a variable to store the pulse travel time
int distance; //Create a variable to store the calculated distance
digitalWrite(trig, HIGH); //Generate a 10 microsecond pulse
delayMicroseconds(10);
digitalWrite(trig, LOW);
pulseTime = pulseIn(echo, HIGH); //Measure the time for the pulse to return
distance = pulseTime / 29 / 2; //Calculate the object distance based on the
pulse time
Serial.println(distance);
return distance;
This function measures the distance to an object using the Ultrasonic sensor. It generates a trigger pulse and measures the time for the pulse to return. Calculate and returns the distance based on the measured time.
int checkDirection() //Check the left,Front and right directions and decide which way to turn
int distances [3] = {0,0,0}; //Left ,right and Front distances
int turnDir; //Direction to turn, 0 left, 1 turn around, 2 right, 3 forward
servoLook.write(180); //Turn servo to look left
delay(500);
distances [0] = getDistance(); //Get the left object distance
servoLook.write(90); //Turn servo to look front
delay(500);
distances [3] = getDistance(); //Get the front object distance
servoLook.write(0); //Turn servo to look right
delay(1000);
distances [1] = getDistance(); //Get the right object distance
if (distances[0]<=25 && distances[1]<=25) //If both directions are blocked, move forward turnDir = 3; else if (distances[0]>=distances[1]) //If left has more space, turn left
turnDir = 0; //left
else if (distances[0]<distances[1]) //If right has more space, turn right
turnDir = 2; //right
//else if (distances[0]<=50 && distances[1]<=50 && distances[3]<=50) //If All directions are blocked, turn around
//turnDir = 1;
return turnDir;
}
This section of the code handles the obstacle-avoidance strategy for the car’s movement. It continually monitors obstacle distances in three directions left, right, and front by utilizing a servo motor. After each scan, it calculates the distances to nearby obstacles. If both the left and right directions have close obstacles, the car proceeds forward. If there’s more space on the left side, it steers the car left, and if the right side is more open, it directs the car to the right. If all three directions (front, left, and right) have obstructions nearby, the car is instructed to perform a U-turn. These directions are communicated by returning specific values: 0 for left, 2 for right, 3 for forward, and 1 for turning around.
include
This block includes the Servo library, which is necessary for controlling the servo motor.
// Ultrasonic sensor pins
define trig 2
define echo 4
// RGB led pins
define LR 9 // Led Right
define LC 13 // Led Center
define LL 10 // Led Left
define LRR A3 // Led Right Red
define LCR A2 // Led Center Red
define LLR A1 // Led Left Red
In this block, various pin constants are defined for components such as the Ultrasonic sensor and RGB LEDs. These constants are used to specify which pins on the Arduino are connected to each component.
// Motor control pins
define LEFT_MOTOR_PIN1 8
define LEFT_MOTOR_PIN2 7
define RIGHT_MOTOR_PIN1 12
define RIGHT_MOTOR_PIN2 11
define ENA 6 // Enable A pin for motor speed control
define ENB 3 // Enable B pin for motor speed control
These lines define digital pins of Arduino (pin7,pin8,pin12 and pin11) for the L298N motor driver inputs to control the DC motors. The pins in1 and in2 control one motor, and the pins in3 and in4 control the other motor. Ena and Enb control the speed of the motor.
// Distance thresholds for obstacle detection
define MIN_DISTANCE_BACK 12
This block defines threshold values. MIN_DISTANCE_BACK represents the minimum distance required from an obstacle to stop.
void setup() {
// Set motor control pins as outputs
pinMode(LEFT_MOTOR_PIN1, OUTPUT);
pinMode(LEFT_MOTOR_PIN2, OUTPUT);
pinMode(RIGHT_MOTOR_PIN1, OUTPUT);
pinMode(RIGHT_MOTOR_PIN2, OUTPUT);
pinMode(ENA, OUTPUT);
pinMode(ENB, OUTPUT);
pinMode(LR, OUTPUT);
pinMode(LC, OUTPUT);
pinMode(LL, OUTPUT);
pinMode(LRR, OUTPUT);
pinMode(LCR, OUTPUT);
pinMode(LLR, OUTPUT);
digitalWrite(LR, LOW);
digitalWrite(LC, LOW);
digitalWrite(LL, LOW);
analogWrite(LRR, 0);
analogWrite(LCR, 0);
analogWrite(LLR, 0);
servoLook.attach(5);
//Set the Trig pins as output pins
pinMode(trig, OUTPUT);
//Set the Echo pins as input pins
pinMode(echo, INPUT);
analogWrite(ENA, 53.5); // speed for motor A 0-LOW speed, 255-Full speed
analogWrite(ENB, 45); // speed for motor B
// Initialize the serial communication for debugging
Serial.begin(9600);
}
In the setup() function, various initializations take place. This includes configuring motor control pins, LED pins, and sensor pins as either OUTPUT or INPUT. It also sets the initial states for LEDs and RGB LEDs to LOW or 0. Additionally, the Servo motor is attached to pin 5, motor speed is adjusted using analogWrite() for ENA and ENB, and serial communication is initiated for debugging (though this part is optional).
void loop()
{
servoLook.write(90);
delay(750);
int distance = getDistance();
if (distance >= MIN_DISTANCE_BACK)
{
moveForward();
Serial.println("forward"); }
while(distance >= MIN_DISTANCE_BACK)
{
distance = getDistance();
delay(50);
}
Stop();
int turnDir = checkDirection();
Serial.println(turnDir);
switch(turnDir)
{
case 0: //Turn left
Serial.println("Left");
turnLeft();
delay(425);
Stop();
break;
case 2: //Turn right
Serial.println("Right");
turnRight();
delay(415);
Stop();
break;
case 3: //move forward
Serial.println("Forward");
moveForward();
break;
}
}
This is the main loop of the code, executed continuously. The servo motor is set to look straight ahead, and there’s a delay for it to settle. The getDistance() function is used to measure the distance using the Ultrasonic sensor. If the measured distance is greater than or equal to MIN_DISTANCE_BACK, the robot is instructed to move forward. While the distance is above the threshold, it continues moving forward. When the distance becomes less than MIN_DISTANCE_BACK, the Stop() function is called to stop the robot.The checkDirection() function is used to determine if there’s an obstacle in the left, right, or front direction.Based on the detected direction, the robot will turn left, turn right, or move forward.Serial messages are printed to help with debugging.
int getDistance() //Measure the distance to an object{
unsigned long pulseTime; //Create a variable to store the pulse travel time
int distance; //Create a variable to store the calculated distance
digitalWrite(trig, HIGH); //Generate a 10 microsecond pulse
delayMicroseconds(10);
digitalWrite(trig, LOW);
pulseTime = pulseIn(echo, HIGH); //Measure the time for the pulse to return
distance = pulseTime / 29 / 2; //Calculate the object distance based on the
pulse time
Serial.println(distance);
return distance;
This function measures the distance to an object using the Ultrasonic sensor. It generates a trigger pulse and measures the time for the pulse to return. Calculate and returns the distance based on the measured time.
int checkDirection() //Check the left,Front and right directions and decide which way to turn
int distances [3] = {0,0,0}; //Left ,right and Front distances
int turnDir; //Direction to turn, 0 left, 1 turn around, 2 right, 3 forward
servoLook.write(180); //Turn servo to look left
delay(500);
distances [0] = getDistance(); //Get the left object distance
servoLook.write(90); //Turn servo to look front
delay(500);
distances [3] = getDistance(); //Get the front object distance
servoLook.write(0); //Turn servo to look right
delay(1000);
distances [1] = getDistance(); //Get the right object distance
if (distances[0]<=25 && distances[1]<=25) //If both directions are blocked, move forward turnDir = 3; else if (distances[0]>=distances[1]) //If left has more space, turn left
turnDir = 0; //left
else if (distances[0]<distances[1]) //If right has more space, turn right
turnDir = 2; //right
//else if (distances[0]<=50 && distances[1]<=50 && distances[3]<=50) //If All directions are blocked, turn around
//turnDir = 1;
return turnDir;
}
This section of the code handles the obstacle-avoidance strategy for the car's movement. It continually monitors obstacle distances in three directions left, right, and front by utilizing a servo motor. After each scan, it calculates the distances to nearby obstacles. If both the left and right directions have close obstacles, the car proceeds forward. If there's more space on the left side, it steers the car left, and if the right side is more open, it directs the car to the right. If all three directions (front, left, and right) have obstructions nearby, the car is instructed to perform a U-turn. These directions are communicated by returning specific values: 0 for left, 2 for right, 3 for forward, and 1 for turning around.
// Motor control functions
void moveForward() {
analogWrite(ENA, 60.5); // speed for motor A
analogWrite(ENB, 52); // speed for motor B
digitalWrite(LR, HIGH);
digitalWrite(LC, HIGH); // All Green light turn on
digitalWrite(LL, HIGH);
analogWrite(LRR, 0);
analogWrite(LCR, 0); // All Red light turn off
analogWrite(LLR, 0);
digitalWrite(LEFT_MOTOR_PIN1, LOW);
digitalWrite(LEFT_MOTOR_PIN2, HIGH);
digitalWrite(RIGHT_MOTOR_PIN1, LOW);
digitalWrite(RIGHT_MOTOR_PIN2, HIGH);
}
void moveBackward() {
digitalWrite(LR, LOW);
digitalWrite(LC, LOW); // All Green light turn off
digitalWrite(LL, LOW);
analogWrite(LRR, 255);
analogWrite(LCR, 255); // All Red light turn on
analogWrite(LLR, 255);
digitalWrite(LEFT_MOTOR_PIN1, HIGH);
digitalWrite(LEFT_MOTOR_PIN2, LOW);
digitalWrite(RIGHT_MOTOR_PIN1, HIGH);
digitalWrite(RIGHT_MOTOR_PIN2, LOW);
}
void turnRight() {
analogWrite(ENA, 100); // speed for motor A
analogWrite(ENB, 90); // speed for motor B
digitalWrite(LR, HIGH);
digitalWrite(LC, LOW); // right side Green light turn on
digitalWrite(LL, LOW);
analogWrite(LRR, 0);
analogWrite(LCR, 255); // Left and Middle Red light turn on
analogWrite(LLR, 255);
digitalWrite(LEFT_MOTOR_PIN1, HIGH);
digitalWrite(LEFT_MOTOR_PIN2, LOW);
digitalWrite(RIGHT_MOTOR_PIN1, LOW);
digitalWrite(RIGHT_MOTOR_PIN2, HIGH);
}
void turnLeft() {
analogWrite(ENA, 100); // speed for motor A
analogWrite(ENB, 90); // speed for motor B
digitalWrite(LR, LOW);
digitalWrite(LC, LOW); // left side Green light turn on
digitalWrite(LL, HIGH);
analogWrite(LRR, 255);
analogWrite(LCR, 255); // right and Middle Red light turn on
analogWrite(LLR, 0);
digitalWrite(LEFT_MOTOR_PIN1, LOW);
digitalWrite(LEFT_MOTOR_PIN2, HIGH);
digitalWrite(RIGHT_MOTOR_PIN1, HIGH);
digitalWrite(RIGHT_MOTOR_PIN2, LOW);
}
void Stop() {
analogWrite(ENA, 0); // speed for motor A
analogWrite(ENB, 0); // speed for motor B
digitalWrite(LR, LOW);
digitalWrite(LC, LOW);
digitalWrite(LL, LOW);
analogWrite(LRR, 255);
analogWrite(LCR, 255);
analogWrite(LLR, 255);
analogWrite(ENA, 0); // speed for motor A
analogWrite(ENB, 0); // speed for motor B
digitalWrite(LEFT_MOTOR_PIN1, LOW);
digitalWrite(LEFT_MOTOR_PIN2, LOW);
digitalWrite(RIGHT_MOTOR_PIN1, LOW);
digitalWrite(RIGHT_MOTOR_PIN2, LOW);
The 2WD Obstacle-Avoiding Car: Control Functions
Specific functions that move and determine the direction of the car depending on detected obstacles form the core of the Arduino based obstacle avoiding car.
moveForward(): This function lets the robot move forward by setting motors of both to move. The green lights are lit when going forward, and red are not lit.
moveBackward(): This function activates the red lights while the motor speeds are updated to move the car backward when the car needs to move backward. The switches are turned off so the lights on the green save image.
turnRight(): Appropriately changing the motor speed makes this function turn the car to the right. While the other lights are red, it turns on the right – side green light to indicate a right turn.
turnLeft(): This function adjusts the motor speed for turning left, and turns the left-side green light green, and the others red to show the car has turned left.
Stop(): This function will bring the car to a halt, by turning off all lights and set their motor speeds to zero.
The Obstacle avoiding Car, how it works
The HC SR04 Ultrasonic Sensor is the primary component behind the car’s obstacle detection using sound waves to determine how far is the car from the nearby objects. Due to its affordable cost and its size, the sensor is effective for projects that require sensitivity to distance.
The project consists of six essential components: I was also using the Arduino obstacle avoiding 2WD kit, Arduino Uno, an ultrasonic sensor, DC motors, servo motor, and an L298N motor driver. When powered on, the servo motor starts rotating to measure distances in three directions: left, right, and front. Wherever you have more space, the car decides where it’s going.
For example, the Arduino Uno is pre programmed with a threshold distance that a robot will react when it is reached. Ultrasound used to detect objects closer than this distance and if it does it signals the Arduino which then commands the motor driver for STOP. The car turns in whatever direction has been determined by the servo motor to be the best direction after the servo motor re scans the surrounding area. This repeats and the car autonomously navigates without hitting obstacles.
RGB LEDs provide Visual Feedback.
To provide visual cues for movement, three RGB LEDs are mounted on the car’s underside:
Red LEDs indicate a stop.
The car forward is lit by Green LED.
When right or left, the right or left side LED turns green and all others turn red.
Summary and Applications
An autonomous obstacle avoiding car using Arduino Uno is successfully demonstrated in this project. It comprises an ultrasonic sensor for measuring the distance, a servo motor for scanning the surrounding, and an L298N motor driver for controlling car motors. This car demonstrates important concepts of autonomous robotics, and can additionally be used as a practical beginner level educational project. This project has such wide possibilities for expansion and adaptation as far as extending to delivery robots or warehouse management systems.
Once enthusiasts have a good understanding of these basics, (they) will be able to make more advanced projects in robotics and electronics easily. If you like what you see, feel free to explore some of our other robotic projects we’ve built in the past for other inspiring ideas.
//Arduino Obstacle Avoiding Car Code
//by ElectroGlobal
#include
// Ultrasonic sensor pins
#define trig 2
#define echo 4
// RGB led pins
#define LR 9 // Led Right
#define LC 13 // Led Center
#define LL 10 // Led Left
#define LRR A3 // Led Right Red
#define LCR A2 // Led Center Red
#define LLR A1 // Led Left Red
// Motor control pins
#define LEFT_MOTOR_PIN1 8
#define LEFT_MOTOR_PIN2 7
#define RIGHT_MOTOR_PIN1 12
#define RIGHT_MOTOR_PIN2 11
#define ENA 6 // Enable A pin for motor speed control
#define ENB 3 // Enable B pin for motor speed control
// Distance thresholds for obstacle detection
//#define MAX_DISTANCE 80
#define MIN_DISTANCE_BACK 12
//float timeOut = 2*(MAX_DISTANCE+10)/100/340*1000000;
// Maximum and minimum motor speeds
#define MAX_SPEED 100
#define MIN_SPEED 75
Servo servoLook;
void setup() {
// Set motor control pins as outputs
pinMode(LEFT_MOTOR_PIN1, OUTPUT);
pinMode(LEFT_MOTOR_PIN2, OUTPUT);
pinMode(RIGHT_MOTOR_PIN1, OUTPUT);
pinMode(RIGHT_MOTOR_PIN2, OUTPUT);
pinMode(ENA, OUTPUT);
pinMode(ENB, OUTPUT);
pinMode(LR, OUTPUT);
pinMode(LC, OUTPUT);
pinMode(LL, OUTPUT);
pinMode(LRR, OUTPUT);
pinMode(LCR, OUTPUT);
pinMode(LLR, OUTPUT);
digitalWrite(LR, LOW);
digitalWrite(LC, LOW);
digitalWrite(LL, LOW);
analogWrite(LRR, 0);
analogWrite(LCR, 0);
analogWrite(LLR, 0);
servoLook.attach(5);
//Set the Trig pins as output pins
pinMode(trig, OUTPUT);
//Set the Echo pins as input pins
pinMode(echo, INPUT);
analogWrite(ENA, 53.5); // speed for motor A 0-LOW speed, 255-Full speed
analogWrite(ENB, 45); // speed for motor B
// Initialize the serial communication for debugging
Serial.begin(9600);
}
void loop() {
servoLook.write(90);
delay(750);
int distance = getDistance();
if (distance >= MIN_DISTANCE_BACK) {
moveForward();
Serial.println("forward");
}
while(distance >= MIN_DISTANCE_BACK)
{
distance = getDistance();
delay(50);
}
Stop();
int turnDir = checkDirection();
Serial.println(turnDir);
switch(turnDir)
{
case 0: //Turn left
Serial.println("Left");
turnLeft();
delay(425);
Stop();
break;
case 2: //Turn right
Serial.println("Right");
turnRight();
delay(415);
Stop();
break;
case 3: //move forward
Serial.println("Forward");
moveForward();
break;
}
}
int getDistance() //Measure the distance to an object
{
unsigned long pulseTime; //Create a variable to store the pulse travel time
int distance; //Create a variable to store the calculated distance
digitalWrite(trig, HIGH); //Generate a 10 microsecond pulse
delayMicroseconds(10);
digitalWrite(trig, LOW);
pulseTime = pulseIn(echo, HIGH); //Measure the time for the pulse to return
distance = pulseTime / 29 / 2; //Calculate the object distance based on the pulse time
Serial.println(distance);
return distance;
}
int checkDirection() //Check the left and right directions and decide which way to turn
{
int distances [3] = {0,0,0}; //Left ,right and Front distances
int turnDir; //Direction to turn, 0 left, 1 turn around, 2 right, 3 forward
servoLook.write(180); //Turn servo to look left
delay(500);
distances [0] = getDistance(); //Get the left object distance
servoLook.write(90); //Turn servo to look left
delay(500);
distances [3] = getDistance();
servoLook.write(0); //Turn servo to look right
delay(1000);
distances [1] = getDistance(); //Get the right object distance
if (distances[0]<=25 && distances[1]<=25) //If both directions are blocked, move forward
turnDir = 3;
else if (distances[0]>=distances[1]) //If left has more space, turn left
turnDir = 0; //left
else if (distances[0]