← Back to STEM Lab
BeginnerRoboticsArduino Uno

Obstacle Avoiding Car

Build a smart car that detects obstacles using an ultrasonic sensor and automatically changes direction. The car scans left and right to find the clearest path β€” like a mini self-driving car!

⏱ 3-4 hoursπŸ’° ~Rs. 2,500 totalβš™ 10 componentsπŸ’» Arduino IDE

What You Will Learn

βœ“How ultrasonic sensors measure distance
βœ“Controlling DC motors with L298N driver
βœ“Using servo motors for scanning
βœ“Basic autonomous navigation logic
βœ“Arduino digital & analog I/O
βœ“PWM speed control for motors

Components Needed

Total estimated cost: Rs. 2,500 β€” Available on Daraz, OLX, or local electronics markets

ComponentQtyPrice
Arduino Uno R31Rs. 800
HC-SR04 Ultrasonic Sensor1Rs. 120
L298N Motor Driver Module1Rs. 250
DC Gear Motors (3-6V)2Rs. 150 each
SG90 Servo Motor1Rs. 200
Robot Car Chassis Kit1Rs. 400
18650 Battery Holder (2-cell)1Rs. 80
18650 Batteries (3.7V)2Rs. 200 each
Jumper Wires (M-M, M-F)20Rs. 100 pack
Mini Breadboard (optional)1Rs. 50

Step-by-Step Build Guide

1

Assemble the Chassis

Attach the two DC motors to the chassis using the screws provided. Mount the wheels on the motor shafts. Attach the caster wheel (free-spinning wheel) at the front. Your car should now have 2 drive wheels at the back and 1 caster wheel at the front.

2

Mount the Arduino & Motor Driver

Place the Arduino Uno on top of the chassis using double-sided tape or screws. Mount the L298N motor driver next to it. Make sure the screw terminals are accessible for connecting motor wires.

3

Connect the Motors to L298N

Connect the left motor wires to OUT1 and OUT2 on the L298N. Connect the right motor wires to OUT3 and OUT4. Tighten the screw terminals. If a motor spins the wrong way later, just swap its two wires.

4

Mount the Servo & Ultrasonic Sensor

Attach the servo motor to the front of the chassis (facing forward) using glue or a bracket. Mount the HC-SR04 ultrasonic sensor on the servo horn so it can rotate left and right. The servo will scan for obstacles by turning the sensor.

5

Wire Everything Up

Follow the wiring diagram below carefully. Connect all power (VCC/5V) wires first, then all ground (GND) wires, then signal wires. Double-check every connection before powering on. A wrong connection can damage components.

6

Install the Battery

Insert two 18650 batteries into the holder. Connect the battery holder's positive wire to L298N 12V input and negative to L298N GND. The L298N has a built-in 5V regulator β€” connect its 5V output to Arduino VIN to power the Arduino from the same battery.

7

Upload the Code

Connect the Arduino to your computer via USB cable. Open Arduino IDE, paste the code below, and click Upload. Once uploaded, disconnect USB β€” the car will run on battery power.

8

Test & Calibrate

Place the car on the floor and turn on the battery. The car should drive forward. When it detects an obstacle within 25cm, it will stop, scan left and right, and turn toward the clearer path. If motors spin wrong direction, swap the motor wires on L298N.

Wiring Diagram

Connect each wire carefully. Double-check before powering on!

FromToWire
HC-SR04 VCCArduino 5V
HC-SR04 GNDArduino GND
HC-SR04 TRIGArduino Pin 9
HC-SR04 ECHOArduino Pin 10
Servo Signal (Orange)Arduino Pin 6
Servo VCC (Red)Arduino 5V
Servo GND (Brown)Arduino GND
L298N IN1Arduino Pin 2
L298N IN2Arduino Pin 3
L298N IN3Arduino Pin 4
L298N IN4Arduino Pin 5
L298N ENAArduino Pin 11 (PWM)
L298N ENBArduino Pin 12
L298N 12VBattery + (7.4V)
L298N GNDBattery - AND Arduino GND
L298N 5V (output)Arduino VIN
Left MotorL298N OUT1 & OUT2
Right MotorL298N OUT3 & OUT4

Arduino Code

Copy this code and upload to your Arduino Uno using Arduino IDE

/*
 * Obstacle Avoiding Car β€” Arduino
 *
 * Components: Arduino Uno, HC-SR04, L298N, SG90 Servo, 2x DC Motors
 *
 * How it works:
 * 1. Car drives forward
 * 2. Ultrasonic sensor measures distance ahead
 * 3. If obstacle detected (< 25cm):
 *    a. Stop
 *    b. Servo scans left and right
 *    c. Compare distances
 *    d. Turn toward the clearer side
 * 4. Repeat
 *
 * Watni Digital STEM Lab
 * https://www.watnidigital.com/education/stem-lab
 */

#include <Servo.h>

// === PIN DEFINITIONS ===
// Ultrasonic Sensor
#define TRIG_PIN 9
#define ECHO_PIN 10

// Motor Driver L298N
#define IN1 2   // Left motor
#define IN2 3
#define IN3 4   // Right motor
#define IN4 5
#define ENA 11  // Left motor speed (PWM)
#define ENB 12  // Right motor speed

// Servo
#define SERVO_PIN 6

// === SETTINGS ===
#define OBSTACLE_DISTANCE 25  // cm β€” stop if obstacle closer than this
#define MOTOR_SPEED 180       // 0-255 β€” adjust for your motors
#define TURN_DURATION 400     // ms β€” how long to turn

Servo scanServo;

void setup() {
  Serial.begin(9600);

  // Motor pins
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT);
  pinMode(ENA, OUTPUT);
  pinMode(ENB, OUTPUT);

  // Ultrasonic pins
  pinMode(TRIG_PIN, OUTPUT);
  pinMode(ECHO_PIN, INPUT);

  // Servo
  scanServo.attach(SERVO_PIN);
  scanServo.write(90); // Face forward
  delay(1000);

  Serial.println("Obstacle Avoiding Car Ready!");
}

void loop() {
  int distance = measureDistance();
  Serial.print("Distance: ");
  Serial.print(distance);
  Serial.println(" cm");

  if (distance > OBSTACLE_DISTANCE) {
    // Path is clear β€” drive forward
    moveForward();
  } else {
    // Obstacle detected!
    stopMotors();
    delay(300);

    // Scan right
    scanServo.write(30);
    delay(500);
    int rightDistance = measureDistance();
    Serial.print("Right: ");
    Serial.println(rightDistance);

    // Scan left
    scanServo.write(150);
    delay(500);
    int leftDistance = measureDistance();
    Serial.print("Left: ");
    Serial.println(leftDistance);

    // Return to center
    scanServo.write(90);
    delay(300);

    // Decide which way to turn
    if (rightDistance > leftDistance && rightDistance > OBSTACLE_DISTANCE) {
      // Turn right
      turnRight();
      delay(TURN_DURATION);
    } else if (leftDistance > OBSTACLE_DISTANCE) {
      // Turn left
      turnLeft();
      delay(TURN_DURATION);
    } else {
      // Both sides blocked β€” reverse and turn
      moveBackward();
      delay(500);
      turnRight();
      delay(TURN_DURATION * 2);
    }

    stopMotors();
    delay(200);
  }

  delay(50); // Small delay between readings
}

// === MOTOR FUNCTIONS ===

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

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

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

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

void stopMotors() {
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4, LOW);
}

// === SENSOR FUNCTION ===

int measureDistance() {
  // Send ultrasonic pulse
  digitalWrite(TRIG_PIN, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIG_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW);

  // Read echo time
  long duration = pulseIn(ECHO_PIN, HIGH, 30000); // 30ms timeout

  // Calculate distance in cm
  int distance = duration * 0.034 / 2;

  // Return max 200 if no echo (no obstacle)
  if (distance == 0 || distance > 200) {
    return 200;
  }

  return distance;
}

How It Works

πŸ“‘ Ultrasonic Sensor

Sends sound waves and measures how long they take to bounce back. Shorter time = closer obstacle. Works like a bat's echolocation!

βš™ Servo Scanner

When an obstacle is detected ahead, the servo rotates the ultrasonic sensor left and right to measure distances in both directions.

🧠 Decision Logic

The Arduino compares left and right distances. It turns toward the side with more open space. If both sides are blocked, it reverses and tries again.

⚑ Motor Control

The L298N driver controls both motors independently. By spinning motors in different directions, the car can go forward, backward, or turn left/right.

Troubleshooting

Car doesn't move at all

Check battery voltage (should be 7-8V). Verify L298N connections. Make sure ENA/ENB pins are connected.

Motors spin wrong direction

Swap the two wires of that motor on the L298N screw terminal.

Car doesn't detect obstacles

Check HC-SR04 wiring (TRIG→Pin 9, ECHO→Pin 10). Open Serial Monitor at 9600 baud to see distance readings.

Servo doesn't move

Verify servo signal wire is on Pin 6. Check if servo is getting 5V power. Try a different servo.

Car turns but doesn't go straight

Motors may have different speeds. Adjust MOTOR_SPEED or add separate speed values for left and right motors.

Car behaves erratically

Power issue β€” motors draw too much current. Use fresh batteries. Add a capacitor (100uF) across motor power lines.

Level Up: Upgrade Ideas

Add Bluetooth Control

Add HC-05 module to switch between manual and auto mode from your phone

Speed Control

Add a potentiometer to adjust speed, or use PWM for smoother acceleration

Edge Detection

Add IR sensors underneath to detect table edges and prevent falling

LED Indicators

Add LEDs that show which direction the car is turning β€” like real car indicators

Built This Project?

Share your build with us! Tag @watnidigital on social media or send us photos.