Build Your Own Arduino Obstacle-Avoiding Car: A Fun & Educational Project!
Ever wanted to dive into robotics and see your creations move? An Arduino obstacle-avoiding car is the perfect entry point! It's a fantastic project for beginners and experienced makers alike, combining basic electronics, programming, and a touch of mechanics.
Ever wanted to dive into robotics and see your creations move? An Arduino obstacle-avoiding car is the perfect entry point! It's a fantastic project for beginners and experienced makers alike, combining basic electronics, programming, and a touch of mechanics.
What is it?
Imagine a small robotic car that can navigate around your room, automatically detecting and steering clear of walls, furniture, or anything else in its path. That's exactly what an obstacle-avoiding car does! It uses sensors to "see" its surroundings and an Arduino microcontroller to make decisions and control its movements.
Imagine a small robotic car that can navigate around your room, automatically detecting and steering clear of walls, furniture, or anything else in its path. That's exactly what an obstacle-avoiding car does! It uses sensors to "see" its surroundings and an Arduino microcontroller to make decisions and control its movements.
How does it work (in a nutshell)?
- Sensing the World: The car typically uses an ultrasonic sensor (like the HC-SR04) to emit sound waves and listen for their echo. By measuring the time it takes for the sound to return, it can calculate the distance to an object.
- The Brain (Arduino): The Arduino board (e.g., Uno) reads the data from the ultrasonic sensor.
- Making Decisions: Based on the distance readings, the Arduino's code decides what to do:
- If the path ahead is clear, keep moving forward.
- If an obstacle is detected within a certain distance, stop!
- Then, it might look left or right to find a clear path and turn accordingly.
- Moving Around: DC motors connected to wheels are controlled by a motor driver module (like the L298N) which receives commands from the Arduino to move forward, backward, left, or right.
- Sensing the World: The car typically uses an ultrasonic sensor (like the HC-SR04) to emit sound waves and listen for their echo. By measuring the time it takes for the sound to return, it can calculate the distance to an object.
- The Brain (Arduino): The Arduino board (e.g., Uno) reads the data from the ultrasonic sensor.
- Making Decisions: Based on the distance readings, the Arduino's code decides what to do:
- If the path ahead is clear, keep moving forward.
- If an obstacle is detected within a certain distance, stop!
- Then, it might look left or right to find a clear path and turn accordingly.
- Moving Around: DC motors connected to wheels are controlled by a motor driver module (like the L298N) which receives commands from the Arduino to move forward, backward, left, or right.
Why build one?
- Learn by Doing: Get hands-on experience with Arduino programming, circuit building, and basic robotics.
- Problem-Solving Skills: Debugging code and troubleshooting hardware issues will sharpen your analytical skills.
- Customization: There's endless room for improvement! Add more sensors, different actuators, or even integrate Bluetooth control.
- Pure Fun: There's a real sense of accomplishment watching your creation come to life and navigate on its own.
- Learn by Doing: Get hands-on experience with Arduino programming, circuit building, and basic robotics.
- Problem-Solving Skills: Debugging code and troubleshooting hardware issues will sharpen your analytical skills.
- Customization: There's endless room for improvement! Add more sensors, different actuators, or even integrate Bluetooth control.
- Pure Fun: There's a real sense of accomplishment watching your creation come to life and navigate on its own.
Ready to get started?
You'll typically need:
- An Arduino board (Uno is a great start)
- Chassis for the car
- DC motors and wheels
- Motor driver module (L298N or similar)
- Ultrasonic sensor (HC-SR04)
- Jumper wires, breadboard, and a power source (battery pack)
You'll typically need:
- An Arduino board (Uno is a great start)
- Chassis for the car
- DC motors and wheels
- Motor driver module (L298N or similar)
- Ultrasonic sensor (HC-SR04)
- Jumper wires, breadboard, and a power source (battery pack)
The Code
// Define pins for Ultrasonic Sensor
const int trigPin = 9; // Trigger Pin for Ultrasonic Sensor
const int echoPin = 10; // Echo Pin for Ultrasonic Sensor
// Define pins for Motor Driver (adjust based on your L298N or similar)
// These are examples, check your motor driver's documentation
// Motor A (e.g., Left Wheel)
const int motorA_In1 = 2;
const int motorA_In2 = 3;
const int motorA_Enable = 4; // PWM pin for speed control (optional, can be HIGH for full speed)
// Motor B (e.g., Right Wheel)
const int motorB_In3 = 5;
const int motorB_In4 = 6;
const int motorB_Enable = 7; // PWM pin for speed control (optional, can be HIGH for full speed)
// Obstacle detection threshold (distance in cm)
const int OBSTACLE_DISTANCE_CM = 20;
void setup() {
// Initialize Serial Communication for debugging
Serial.begin(9600);
// Set Ultrasonic Sensor pins
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
// Set Motor Driver pins
pinMode(motorA_In1, OUTPUT);
pinMode(motorA_In2, OUTPUT);
pinMode(motorA_Enable, OUTPUT);
pinMode(motorB_In3, OUTPUT);
pinMode(motorB_In4, OUTPUT);
pinMode(motorB_Enable, OUTPUT);
// Initially stop the motors
stopCar();
}
void loop() {
long duration;
int distance;
// --- Measure distance with Ultrasonic Sensor ---
// Clear the trigPin by setting it LOW for 2 microseconds
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
// Set the trigPin to HIGH for 10 microseconds to send a pulse
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
// Read the echoPin, returns the sound wave travel time in microseconds
duration = pulseIn(echoPin, HIGH);
// Calculate the distance in cm (Speed of sound is approx. 0.034 cm/microsecond)
// Divide by 2 because the sound travels to the object and back
distance = duration * 0.034 / 2;
Serial.print("Distance: ");
Serial.print(distance);
Serial.println(" cm");
// --- Decision Making and Motor Control ---
if (distance > OBSTACLE_DISTANCE_CM || distance == 0) { // distance == 0 implies sensor read error or no object
// Path is clear or sensor error, move forward
moveForward();
Serial.println("Moving Forward");
} else {
// Obstacle detected!
Serial.println("Obstacle Detected! Stopping and turning.");
stopCar();
delay(500); // Give a brief pause
// More advanced logic would involve looking left/right
// For simplicity, let's just reverse and turn
moveBackward();
delay(1000); // Reverse for a moment
stopCar();
delay(500);
turnRight(); // Or turnLeft(), try both!
delay(700); // Turn for a short duration
stopCar();
delay(500);
}
// A small delay to prevent rapid sensor readings and motor changes
delay(100);
}
// --- Motor Control Functions ---
void moveForward() {
// Motor A (Left)
digitalWrite(motorA_In1, HIGH);
digitalWrite(motorA_In2, LOW);
digitalWrite(motorA_Enable, HIGH); // Or analogWrite(motorA_Enable, 255) for speed control
// Motor B (Right)
digitalWrite(motorB_In3, HIGH);
digitalWrite(motorB_In4, LOW);
digitalWrite(motorB_Enable, HIGH); // Or analogWrite(motorB_Enable, 255)
}
void moveBackward() {
// Motor A (Left)
digitalWrite(motorA_In1, LOW);
digitalWrite(motorA_In2, HIGH);
digitalWrite(motorA_Enable, HIGH);
// Motor B (Right)
digitalWrite(motorB_In3, LOW);
digitalWrite(motorB_In4, HIGH);
digitalWrite(motorB_Enable, HIGH);
}
void turnLeft() {
// Motor A (Left) backward
digitalWrite(motorA_In1, LOW);
digitalWrite(motorA_In2, HIGH);
digitalWrite(motorA_Enable, HIGH);
// Motor B (Right) forward
digitalWrite(motorB_In3, HIGH);
digitalWrite(motorB_In4, LOW);
digitalWrite(motorB_Enable, HIGH);
}
void turnRight() {
// Motor A (Left) forward
digitalWrite(motorA_In1, HIGH);
digitalWrite(motorA_In2, LOW);
digitalWrite(motorA_Enable, HIGH);
// Motor B (Right) backward
digitalWrite(motorB_In3, LOW);
digitalWrite(motorB_In4, HIGH);
digitalWrite(motorB_Enable, HIGH);
}
void stopCar() {
digitalWrite(motorA_In1, LOW);
digitalWrite(motorA_In2, LOW);
digitalWrite(motorA_Enable, LOW); // Disable motor A to stop
digitalWrite(motorB_In3, LOW);
digitalWrite(motorB_In4, LOW);
digitalWrite(motorB_Enable, LOW); // Disable motor B to stop
}
// Define pins for Ultrasonic Sensor
const int trigPin = 9; // Trigger Pin for Ultrasonic Sensor
const int echoPin = 10; // Echo Pin for Ultrasonic Sensor
// Define pins for Motor Driver (adjust based on your L298N or similar)
// These are examples, check your motor driver's documentation
// Motor A (e.g., Left Wheel)
const int motorA_In1 = 2;
const int motorA_In2 = 3;
const int motorA_Enable = 4; // PWM pin for speed control (optional, can be HIGH for full speed)
// Motor B (e.g., Right Wheel)
const int motorB_In3 = 5;
const int motorB_In4 = 6;
const int motorB_Enable = 7; // PWM pin for speed control (optional, can be HIGH for full speed)
// Obstacle detection threshold (distance in cm)
const int OBSTACLE_DISTANCE_CM = 20;
void setup() {
// Initialize Serial Communication for debugging
Serial.begin(9600);
// Set Ultrasonic Sensor pins
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
// Set Motor Driver pins
pinMode(motorA_In1, OUTPUT);
pinMode(motorA_In2, OUTPUT);
pinMode(motorA_Enable, OUTPUT);
pinMode(motorB_In3, OUTPUT);
pinMode(motorB_In4, OUTPUT);
pinMode(motorB_Enable, OUTPUT);
// Initially stop the motors
stopCar();
}
void loop() {
long duration;
int distance;
// --- Measure distance with Ultrasonic Sensor ---
// Clear the trigPin by setting it LOW for 2 microseconds
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
// Set the trigPin to HIGH for 10 microseconds to send a pulse
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
// Read the echoPin, returns the sound wave travel time in microseconds
duration = pulseIn(echoPin, HIGH);
// Calculate the distance in cm (Speed of sound is approx. 0.034 cm/microsecond)
// Divide by 2 because the sound travels to the object and back
distance = duration * 0.034 / 2;
Serial.print("Distance: ");
Serial.print(distance);
Serial.println(" cm");
// --- Decision Making and Motor Control ---
if (distance > OBSTACLE_DISTANCE_CM || distance == 0) { // distance == 0 implies sensor read error or no object
// Path is clear or sensor error, move forward
moveForward();
Serial.println("Moving Forward");
} else {
// Obstacle detected!
Serial.println("Obstacle Detected! Stopping and turning.");
stopCar();
delay(500); // Give a brief pause
// More advanced logic would involve looking left/right
// For simplicity, let's just reverse and turn
moveBackward();
delay(1000); // Reverse for a moment
stopCar();
delay(500);
turnRight(); // Or turnLeft(), try both!
delay(700); // Turn for a short duration
stopCar();
delay(500);
}
// A small delay to prevent rapid sensor readings and motor changes
delay(100);
}
// --- Motor Control Functions ---
void moveForward() {
// Motor A (Left)
digitalWrite(motorA_In1, HIGH);
digitalWrite(motorA_In2, LOW);
digitalWrite(motorA_Enable, HIGH); // Or analogWrite(motorA_Enable, 255) for speed control
// Motor B (Right)
digitalWrite(motorB_In3, HIGH);
digitalWrite(motorB_In4, LOW);
digitalWrite(motorB_Enable, HIGH); // Or analogWrite(motorB_Enable, 255)
}
void moveBackward() {
// Motor A (Left)
digitalWrite(motorA_In1, LOW);
digitalWrite(motorA_In2, HIGH);
digitalWrite(motorA_Enable, HIGH);
// Motor B (Right)
digitalWrite(motorB_In3, LOW);
digitalWrite(motorB_In4, HIGH);
digitalWrite(motorB_Enable, HIGH);
}
void turnLeft() {
// Motor A (Left) backward
digitalWrite(motorA_In1, LOW);
digitalWrite(motorA_In2, HIGH);
digitalWrite(motorA_Enable, HIGH);
// Motor B (Right) forward
digitalWrite(motorB_In3, HIGH);
digitalWrite(motorB_In4, LOW);
digitalWrite(motorB_Enable, HIGH);
}
void turnRight() {
// Motor A (Left) forward
digitalWrite(motorA_In1, HIGH);
digitalWrite(motorA_In2, LOW);
digitalWrite(motorA_Enable, HIGH);
// Motor B (Right) backward
digitalWrite(motorB_In3, LOW);
digitalWrite(motorB_In4, HIGH);
digitalWrite(motorB_Enable, HIGH);
}
void stopCar() {
digitalWrite(motorA_In1, LOW);
digitalWrite(motorA_In2, LOW);
digitalWrite(motorA_Enable, LOW); // Disable motor A to stop
digitalWrite(motorB_In3, LOW);
digitalWrite(motorB_In4, LOW);
digitalWrite(motorB_Enable, LOW); // Disable motor B to stop
}
How to use this code:
Hardware Setup:
Ensure your ultrasonic sensor (HC-SR04) and L298N motor driver are wired correctly to your Arduino. Double-check the pin numbers in the code match your actual wiring!
trigPin and echoPin for the ultrasonic sensor.motorA_In1, motorA_In2, motorA_Enable for one motor.motorB_In3, motorB_In4, motorB_Enable for the other motor.- Connect the L298N's enable pins (ENA, ENB) to digital pins, or to PWM pins if you want speed control (
analogWrite). For simplicity, I've used digitalWrite(HIGH) on enable pins for full speed.
Ensure your ultrasonic sensor (HC-SR04) and L298N motor driver are wired correctly to your Arduino. Double-check the pin numbers in the code match your actual wiring!
trigPinandechoPinfor the ultrasonic sensor.motorA_In1,motorA_In2,motorA_Enablefor one motor.motorB_In3,motorB_In4,motorB_Enablefor the other motor.- Connect the L298N's enable pins (ENA, ENB) to digital pins, or to PWM pins if you want speed control (
analogWrite). For simplicity, I've useddigitalWrite(HIGH)on enable pins for full speed.
Arduino IDE:
- Copy and paste this code into a new sketch in the Arduino IDE.
- Select your Arduino board (e.g., Arduino Uno) under
Tools > Board. - Select the correct COM port under
Tools > Port. - Upload the code to your Arduino.
- Copy and paste this code into a new sketch in the Arduino IDE.
- Select your Arduino board (e.g., Arduino Uno) under
Tools > Board. - Select the correct COM port under
Tools > Port. - Upload the code to your Arduino.
Testing:
- Open the Serial Monitor (
Tools > Serial Monitor) to see the distance readings and car status. - Place your car on the floor and observe its behavior. Try placing obstacles in front of it.
- Open the Serial Monitor (
Tools > Serial Monitor) to see the distance readings and car status. - Place your car on the floor and observe its behavior. Try placing obstacles in front of it.
Next Steps and Improvements:
- Refined Turning Logic: Instead of just reversing and turning, you can:
- Scan left and right with the ultrasonic sensor (perhaps mounted on a servo for a wider field of view).
- Compare distances to left and right and turn towards the clearer path.
- PID Control: For smoother movement and more precise turns, consider implementing PID control for the motors.
- Multiple Sensors: Add more ultrasonic sensors for wider coverage, or even IR sensors for close-range detection.
- Line Following: Integrate line-following sensors to create a more versatile robot.
- Remote Control: Add a Bluetooth module (HC-05/06) or an IR receiver to control the car wirelessly.
- Power Management: Ensure your power source (batteries) can deliver enough current for the motors, especially under load.
This code provides a solid starting point for your Arduino obstacle-avoiding car. Happy building!
- Refined Turning Logic: Instead of just reversing and turning, you can:
- Scan left and right with the ultrasonic sensor (perhaps mounted on a servo for a wider field of view).
- Compare distances to left and right and turn towards the clearer path.
- PID Control: For smoother movement and more precise turns, consider implementing PID control for the motors.
- Multiple Sensors: Add more ultrasonic sensors for wider coverage, or even IR sensors for close-range detection.
- Line Following: Integrate line-following sensors to create a more versatile robot.
- Remote Control: Add a Bluetooth module (HC-05/06) or an IR receiver to control the car wirelessly.
- Power Management: Ensure your power source (batteries) can deliver enough current for the motors, especially under load.
This code provides a solid starting point for your Arduino obstacle-avoiding car. Happy building!




