Car Project 2 : Object Avoidance Robot Car

Overview

Have you ever wanted to build a robot car that can drive on its own and avoid obstacles like a mini self-driving car? 🚙✨ In this tutorial, you’ll learn how to build an object avoidance robot car using an ESP32, L298N motor driver, and an ultrasonic sensor.

This project is perfect for beginners who want to start exploring robotics and coding in a fun and hands-on way!

What you'll need

Techsage's Innovator Box Plus - its best AI & Robotics Kit 

Components

  • ESP32 
  • L298N motor driver
  • Ultrasonic sensor (HC-SR04)
  • 2 DC motors with wheels
  • Robot chassis kit
  • Jumper wires
  • Battery pack (7.4V or 12V recommended) and holder
  • Breadboard

How it works

The robot uses an ultrasonic sensor to detect obstacles in front. When it sees something too close (less than 20 cm), it stops and "looks" left and right to find the best path forward. If no clear path exists, it reverses and turns around.

Circuit connections

Diagram Representation:

Motors to L298N

  • Motor A (left): Connect to OUT1 and OUT2 on L298N.
  • Motor B (right): Connect to OUT3 and OUT4 on L298N.

L298N to ESP32

L298N Pin ESP32 GPIO Function
IN1 27 Left motor direction
IN2 26 Left motor direction
IN3 25 Right motor direction
IN4 33 Right motor direction
ENA 14 Left motor speed (PWM)
ENB 32 Right motor speed (PWM)

 

Ultrasonic sensor to ESP32

HC-SR04 Pin ESP32 GPIO Function
VCC 5V Power
GND GND Ground
Trig 5 Trigger
Echo 18 Echo

 

Power connections

  • Connect battery + (positive) to L298N VCC terminal.
  • Connect battery – (negative) to L298N GND, and also connect L298N GND to ESP32 GND.
  • Use L298N 5V output (with jumper connected) to power ESP32 VIN pin (or use a separate 5V supply).

Uploading the code

Here’s the full code you can directly copy and paste into the Arduino IDE (make sure you select ESP32 board and correct COM port) :

-----------------------------------------------------------------------------------------

#define ENA 14
#define IN1 27
#define IN2 26
#define IN3 25
#define IN4 33
#define ENB 32

#define TRIG_PIN 5
#define ECHO_PIN 18

const int SAFE_DISTANCE = 20; // in cm
const int MOTOR_SPEED = 150;
const int TURN_TIME = 300;
const int SCAN_DELAY = 200;

void setup() {
  Serial.begin(115200);
  delay(1000);

  pinMode(ENA, OUTPUT);
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT);
  pinMode(ENB, OUTPUT);
  pinMode(TRIG_PIN, OUTPUT);
  pinMode(ECHO_PIN, INPUT);

  Serial.println("Object Avoidance Car Initialized!");
}

void loop() {
  int distance = getDistance();

  if (distance > SAFE_DISTANCE) {
    moveForward();
    Serial.println("Moving Forward - Distance: " + String(distance) + " cm");
  } else {
    Serial.println("Obstacle ahead! Distance: " + String(distance) + " cm");
    handleObstacle();
  }

  delay(50);
}

void handleObstacle() {
  stopMotors();
  delay(100);

  // Check left
  turnLeft();
  delay(TURN_TIME);
  stopMotors();
  delay(SCAN_DELAY);
  int leftDistance = getDistance();
  Serial.println("Left distance: " + String(leftDistance) + " cm");

  // Return center
  turnRight();
  delay(TURN_TIME);
  stopMotors();
  delay(SCAN_DELAY);

  // Check right
  turnRight();
  delay(TURN_TIME);
  stopMotors();
  delay(SCAN_DELAY);
  int rightDistance = getDistance();
  Serial.println("Right distance: " + String(rightDistance) + " cm");

  // Return center
  turnLeft();
  delay(TURN_TIME);
  stopMotors();
  delay(100);

  if (leftDistance > SAFE_DISTANCE && rightDistance > SAFE_DISTANCE) {
    if (leftDistance >= rightDistance) {
      Serial.println("Turning left (better clearance)");
      turnLeft();
      delay(TURN_TIME * 2);
    } else {
      Serial.println("Turning right (better clearance)");
      turnRight();
      delay(TURN_TIME * 2);
    }
  } else if (leftDistance > SAFE_DISTANCE) {
    Serial.println("Turning left");
    turnLeft();
    delay(TURN_TIME * 2);
  } else if (rightDistance > SAFE_DISTANCE) {
    Serial.println("Turning right");
    turnRight();
    delay(TURN_TIME * 2);
  } else {
    Serial.println("Both sides blocked. Reversing...");
    moveBackward();
    delay(800);
    stopMotors();
    delay(200);
    turnRight();
    delay(TURN_TIME * 4);
  }

  stopMotors();
  delay(200);
}

int getDistance() {
  digitalWrite(TRIG_PIN, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIG_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW);

  long duration = pulseIn(ECHO_PIN, HIGH, 30000);
  if (duration == 0) {
    return 0;
  }

  int distance = duration * 0.034 / 2;
  if (distance > 200) {
    return 200;
  }

  return distance;
}

void moveForward() {
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, HIGH);
  digitalWrite(IN4, LOW);
  analogWrite(ENA, MOTOR_SPEED);
  analogWrite(ENB, MOTOR_SPEED);
}

void moveBackward() {
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, HIGH);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4, HIGH);
  analogWrite(ENA, MOTOR_SPEED);
  analogWrite(ENB, MOTOR_SPEED);
}

void turnLeft() {
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, HIGH);
  digitalWrite(IN3, HIGH);
  digitalWrite(IN4, LOW);
  analogWrite(ENA, MOTOR_SPEED);
  analogWrite(ENB, MOTOR_SPEED);
}

void turnRight() {
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4, HIGH);
  analogWrite(ENA, MOTOR_SPEED);
  analogWrite(ENB, MOTOR_SPEED);
}

void stopMotors() {
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4, LOW);
  analogWrite(ENA, 0);
  analogWrite(ENB, 0);
}

----------------------------------------------------------------------------------------

Testing

✅ After uploading, place the car on a flat surface.
✅ Make sure no wheels are stuck and motors spin freely.
✅ Watch your car start moving forward and avoid obstacles by turning left or right!

Tips & troubleshooting

  • If motors spin in the wrong direction, swap OUT1 & OUT2 or OUT3 & OUT4 motor wires on L298N.
  • Always power your motors from a battery — USB alone won’t be enough!
  • Adjust SAFE_DISTANCE and MOTOR_SPEED if your car is too fast or stops too late.
  • Use the Serial Monitor to see real-time distance and debug easily.

 

Have questions? Drop a comment below!

🚀 Share your car with us on Instagram and tag us — we’d love to feature your project!

Back to blog

Leave a comment