DEV Community

Cover image for Arduino Uno HC-SR04: Build an Obstacle-Avoiding Robot
Shilleh
Shilleh

Posted on Originally published at shillehtek.com

Arduino Uno HC-SR04: Build an Obstacle-Avoiding Robot

Originally published on ShillehTek IoT & Beyond.

Project Overview

Arduino Uno + HC-SR04 obstacle-avoiding robot: Build a 2WD rover that uses an HC-SR04 ultrasonic sensor on a servo to scan left and right, compare distances, and steer toward the open path instead of getting stuck in corners.

  • Time: ~2 hours
  • Skill level: Intermediate
  • What you will build: A 2WD autonomous rover with an L298N driver, ultrasonic ranging, servo look-around, and clean movement functions you can reuse in any robot.

Arduino Uno obstacle-avoiding robot with HC-SR04 ultrasonic sensor mounted on a servo

Look, decide, drive - the loop every autonomous robot runs.

Parts List

From ShillehTek

External

  • A 2WD robot chassis with two wheels and a caster
  • A 7.4-12 V battery pack (2×18650 or 6×AA) - the L298N drops about 2 V, so give it headroom

Note: Power the motors from the battery through the L298N and let the L298N's 5 V output (jumper on) feed the Uno's 5V pin - one battery, common ground. Never run motors from the Uno's own regulator; the resets that follow are the number-one beginner robot bug.

Step-by-Step Guide

Step 1 - Assemble the Chassis

Goal: Something that rolls.

What to do: Bolt the motors and caster to the chassis, fit the wheels, and mount the Uno and L298N on top with the battery pack underneath or behind.

Fix the servo at the front with the HC-SR04 on its horn (a hot-glued bracket or a small 3D-printed holder works), pointing forward at the servo's 90° position.

2WD robot chassis assembled with Arduino Uno, L298N driver, and HC-SR04 sensor on a front-mounted servo

Motors below, electronics on top, sensor up front.

Expected result: A rolling platform with the sensor head centered.

Step 2 - Wire Driver, Sensor, and Servo

Goal: Every signal on the right pin.

What to do: L298N: IN1 → D5, IN2 → D4 (left motor), IN3 → D7, IN4 → D6 (right motor); leave the ENA/ENB jumpers on for full speed.

Battery + → L298N 12V, battery - → L298N GND, L298N 5V → Uno 5V, L298N GND → Uno GND.

HC-SR04: TRIG → D9, ECHO → D10, VCC → 5V, GND → GND. Servo: signal → D3, power from 5V/GND.

Wiring diagram showing Arduino Uno connected to L298N motor driver, HC-SR04 ultrasonic sensor, and a servo for sensor scanning

Motor inputs on D4-D7, ultrasonic on D9/D10 - add the servo on D3.

Expected result: A fully wired rover.

Step 3 - Upload the Sketch

Goal: Program the robot to drive forward, detect obstacles, scan left and right, and turn toward the clearer side.

Code:

#include <Servo.h>

const int TRIG = 9, ECHO = 10, SERVO_PIN = 3;
const int L_FWD = 5, L_REV = 4, R_FWD = 7, R_REV = 6;
const int STOP_CM = 20;
Servo head;

long readCm() {
  digitalWrite(TRIG, LOW);  delayMicroseconds(2);
  digitalWrite(TRIG, HIGH); delayMicroseconds(10);
  digitalWrite(TRIG, LOW);
  long us = pulseIn(ECHO, HIGH, 25000);
  return us == 0 ? 400 : us * 0.034 / 2;          // no echo = treat as far away
}

void drive(bool lf, bool lr, bool rf, bool rr) {  // one function for every motion
  digitalWrite(L_FWD, lf); digitalWrite(L_REV, lr);
  digitalWrite(R_FWD, rf); digitalWrite(R_REV, rr);
}
void forward()  { drive(1, 0, 1, 0); }
void backward() { drive(0, 1, 0, 1); }
void left()     { drive(0, 1, 1, 0); }            // spin in place
void right()    { drive(1, 0, 0, 1); }
void stopAll()  { drive(0, 0, 0, 0); }

long lookAt(int angle) {                          // aim the sensor, settle, measure
  head.write(angle); delay(350);
  long d = readCm(); head.write(90); return d;
}

void setup() {
  pinMode(TRIG, OUTPUT); pinMode(ECHO, INPUT);
  for (int p : {L_FWD, L_REV, R_FWD, R_REV}) pinMode(p, OUTPUT);
  head.attach(SERVO_PIN); head.write(90);
  delay(1000);                                    // a second to put it down
}

void loop() {
  long ahead = readCm();
  if (ahead > STOP_CM) { forward(); delay(50); return; }

  stopAll(); delay(200);                          // obstacle: back off and look around
  backward(); delay(400); stopAll(); delay(200);
  long leftCm = lookAt(160), rightCm = lookAt(20);
  if (leftCm > rightCm) left(); else right();
  delay(450);                                     // ~90 degrees; tune for your chassis
  stopAll(); delay(100);
}
Enter fullscreen mode Exit fullscreen mode

What to do: Upload with the robot on a stand (wheels free), check that forward really is forward (swap a motor's two wires if it runs backwards), then set it on the floor.

Expected result: It drives until something is within 20 cm, backs up, glances left and right, and turns toward the clearer direction.

Step 4 - Tune the Turn

Goal: Ninety degrees, every time.

What to do: The 450 ms turn delay depends on your motors, battery, and floor. Adjust until a turn is roughly a right angle.

For finer control, remove the ENA/ENB jumpers and drive them with PWM: move the ultrasonic to A0/A1 and the motor inputs to D4, D7, D8, D12 so that D5 and D6 are free for ENA and ENB, then use analogWrite to set speed. Slower robots avoid better, and you can creep up to obstacles instead of charging them.

Expected result: Clean turns and no more scraping along walls.

Step 5 - Level Up

Goal: From wanderer to robot.

What to do: Add a three-point scan (left, center, right) for smarter path choice; a stuck detector that reverses and spins if the front reading hasn't changed in three seconds; an HC-05 so a phone can take over; or the line-follower sensors from our other guide for a robot that does both. Swap in the TB6612 driver for a lighter, more efficient build.

Expected result: A platform for every robot idea you have next.

Conclusion

This Arduino Uno obstacle-avoiding robot combines an HC-SR04 ultrasonic sensor with a servo scan and an L298N motor driver to create a simple sense-decide-drive loop that can explore without constantly getting stuck.

Want the exact parts used in this build? Grab them from ShillehTek.com. If you want help customizing this project or building something for your product, check out our IoT consulting services.

Credits

All photos and images in this tutorial are credited to Raushan Kumar on Hackster.io. The original guide by Raushan Kumar served as the reference for this ShillehTek version (shared under Apache-2.0). We thank him for his excellent work in the maker community.

Top comments (0)