If you’ve been working through our Academy, you know how to measure distance and control motors. Now, it’s time to build an Autonomous Obstacle Avoiding Robot Car. This robot will drive forward until its ultrasonic “eyes” detect a wall. It will then stop, panic, turn around, and drive into a different wall. It is the pinnacle of artificial stupidity.

How the Robot “Sees”

The HC-SR04 ultrasonic sensor works like a bat’s echolocation. It sends out a high-frequency sound wave and measures how long it takes for the echo to bounce back. By doing this dozens of times a second, the Arduino can constantly calculate the distance to the nearest object in front of the robot.

Required Components

Step 1: Wiring the Motors and Driver

Assemble the chassis according to the included instructions. Once the motors are mounted:

  1. Connect the left motor wires to the OUT1 and OUT2 terminals on the L298N.
  2. Connect the right motor wires to OUT3 and OUT4.
  3. Connect your battery pack’s positive (red) wire to the 12V terminal on the L298N.
  4. Connect the battery’s negative (black) wire to the GND terminal. CRITICAL: Also run a jumper wire from the L298N GND to an Arduino GND pin!

Connect the L298N control pins to the Arduino:

Step 2: Wiring the Ultrasonic Sensor

Step 3: The Code (Autonomous Navigation)

Upload the following code to your Arduino. This sketch constantly measures the distance. If an object is detected closer than 20cm, it commands the motors to stop, reverse, and pivot right before resuming forward motion.

// Define Motor Pins
const int IN1 = 7;
const int IN2 = 6;
const int IN3 = 5;
const int IN4 = 4;

// Define Ultrasonic Sensor Pins
const int trigPin = 9;
const int echoPin = 10;

// Variables for distance calculation
long duration;
int distance;

void setup() {
  // Set motor pins as outputs
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT);
  
  // Set sensor pins
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  
  Serial.begin(9600);
}

void loop() {
  // Measure Distance
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  
  duration = pulseIn(echoPin, HIGH);
  distance = duration * 0.034 / 2; // Convert to cm
  
  if (distance > 0 && distance < 20) {
    // Obstacle detected!
    stopMotors();
    delay(500);
    moveBackward();
    delay(500);
    turnRight();
    delay(500);
  } else {
    // Path is clear
    moveForward();
  }
  delay(50);
}

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

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

void turnRight() {
  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);
}

Next Steps

Turn on the battery pack and place your robot on the floor. It should start exploring the room! If your robot spins in circles instead of driving forward, you likely have one of the motors wired backward. Simply swap the wires on the L298N output block for that specific motor.

To take this project further, consider adding a servo motor to create a scanning “radar” like we did in Project 7. This will allow the robot to “look” left and right before deciding which way to turn!

Having power issues when the motors kick in? Read our guide on Why Your Arduino Keeps Restarting.