Building an Obstacle-Avoiding Robot with Ultrasonic Sensors

An obstacle-avoiding robot works by turning a single sensor reading into a repeated decision: fire the HC-SR04's ultrasonic pulse, time how long it takes to bounce back, convert that time to a distance in centimetres, and compare the result against a safety threshold on every pass through the Arduino's main loop. As long as the nearest object stays farther than the threshold, the robot keeps driving forward; the moment a reading drops below it, the firmware stops both motors, reverses briefly, and turns before resuming — rather than the car continuing straight into whatever it just measured. Nothing about this requires the robot to "see" a scene or classify an object; it only needs a fast, repeated distance measurement and a fixed number to compare it against.

What parts does an obstacle-avoiding robot need?

Underneath the specific parts, five roles have to be filled:

  • Microcontroller — an Arduino Uno reads the sensor, runs the decision logic, and drives the motor driver's control pins.
  • Distance sensor — an HC-SR04 ultrasonic module measures how far away the nearest object in front of the robot is, from roughly 2cm out to 4 metres.
  • Motor driver — the Arduino's GPIO pins output a few milliamps at 5V, nowhere near enough to turn a DC motor. An L298N dual H-bridge module sits between the Arduino and the motors, taking low-power direction and speed signals and switching the higher current the motors actually draw.
  • Drive motors and chassis — two DC gear motors, one per side, mounted on a two-wheel-drive chassis, so the robot can turn by driving each side differently.
  • Power supply and wiring — a battery to run the motors and logic, plus jumper wire to connect everything, since the sensor, driver, and motors are all separate boards until wired together.

How does the Arduino decide when to turn?

The HC-SR04 doesn't report distance directly — it reports a pulse duration, and the Arduino does the conversion. The firmware pulls the sensor's TRIG pin HIGH for 10 microseconds, the sensor emits an ultrasonic burst and pulls its ECHO pin HIGH for exactly as long as the round trip to the nearest object and back takes, and the Arduino's pulseIn() function measures that duration. Dividing by roughly 58 (half the speed of sound, unit-converted to centimetres and microseconds) turns the raw echo time into a distance reading. That single number is then compared against one fixed threshold, checked every time through the loop: stay above it and the robot drives forward, drop below it and the firmware reacts immediately. In the real firmware generated for this exact build, that reaction was described plainly: "If an obstacle is detected within 20cm, the robot will stop, reverse briefly, and then turn right to avoid it. Otherwise, it will drive forward." There's no path-planning or memory of what it saw a second ago — each loop iteration is an independent measurement and an independent decision.

Should the ultrasonic sensor be fixed or on a servo?

A single HC-SR04 bolted straight to the front of the chassis is the simpler and cheaper build, and it's what this exact tray produces — no servo motor was included, so the sensor only ever looks straight ahead. That's enough to make the robot stop and turn away from anything directly in its path, but it can't compare "how clear is left" versus "how clear is right" before choosing a direction; a fixed-sensor build typically just picks one turn direction (right, in the generated firmware above) whenever anything is close, rather than picking the actually clearer side. Mounting the same sensor on a small servo lets the firmware sweep it left and right at the moment an obstacle is detected, take a reading at each angle, and steer toward whichever side reads the longer distance — a meaningfully smarter robot, at the cost of one more part, one more set of wiring, and servo-timing code layered on top of the distance-and-motor logic. For a first build, starting with the fixed sensor and confirming the stop-reverse-turn behaviour works reliably is the more debuggable path; a scanning servo is a reasonable upgrade once that baseline is solid.

How do you wire it all together?

Arduino Uno Connects to Purpose
5V HC-SR04 VCC sensor power
GND HC-SR04 GND sensor ground
Digital Pin 2 HC-SR04 TRIG trigger pulse out
Digital Pin 3 HC-SR04 ECHO echo pulse in
Digital Pin 9 L298N ENA left motor speed (PWM)
Digital Pin 8 L298N IN1 left motor direction
Digital Pin 7 L298N IN2 left motor direction
Digital Pin 10 L298N ENB right motor speed (PWM)
Digital Pin 6 L298N IN3 right motor direction

The L298N's motor-side terminals take the battery's power directly (6–46V rated, separate from the Arduino's own supply), while its logic side runs on 5V shared with the Arduino. This is the exact pin layout Soldr generated for this tray, shown in the firmware capture below; the sensor and driver both run on 5V logic, so no level-shifting is needed anywhere in this build. One more L298N direction pin (IN4, completing the right motor's control pair) continues past what's captured in the screenshot.

Watch it built live

We typed one sentence into Compoden's AI build assistant on the storefront and let it pick real, in-stock parts — unscripted, screenshotted as it happened:

"I want to build an autonomous robot car that avoids obstacles using an ultrasonic sensor, with an Arduino Uno"

Compoden AI build assistant screenshot: Arduino Uno obstacle-avoiding robot parts tray with HC-SR04 sensor

It matched 8 in-stock parts and explained its reasoning for each one:

"This build creates an autonomous robot car that avoids obstacles. The car uses an ultrasonic sensor to detect objects in its path and then steers around them, all controlled by a small computer board."

"The L298N Motor Driver Module is needed because the microcontroller cannot directly power the motors. This module acts as an intermediary, taking control signals from the microcontroller and using a separate, higher-power supply to drive the motors."

It also caught a real gap in the tray and said so rather than quietly shipping an incomplete build: the build log itself flagged "Wheels — not in stock yet," and the reply added, "This build is missing wheels for the robot chassis. Please ask us if you would like to add a set of wheels to your order." When we asked it to add a set of wheels compatible with the gear motors, it did not actually add wheels — it added an unrelated second motor instead and dropped the jumper wire kit from the tray. We're reporting that plainly rather than smoothing it over: the parts list and pricing below are the clean, first-pass tray with the wheels gap left as an open item to source separately (most 2WD chassis motor kits list a matching wheel pair on the same product page). It also ran a power-budget check and flagged a real sizing note: the two gear motors and the L298N's motor-side draw can peak well past what a single 9V snap-connector battery reliably sustains under load.

Watch the firmware get generated

We then asked Compoden's build companion, Soldr, to write the actual obstacle-avoidance firmware for this exact hardware combination.

Soldr firmware editor screenshot: generated Arduino Uno obstacle-avoidance firmware with HC-SR04 and L298N pin definitions

Soldr matched all 7 parts in its own catalog resolution and generated the firmware in one pass. It described the result as: "Here is the firmware for your Arduino Uno robot. It continuously measures distance using the HC-SR04 sensor. If an obstacle is detected within 20cm, the robot will stop, reverse briefly, and then turn right to avoid it. Otherwise, it will drive forward." It also included practical setup notes rather than leaving them out: "Upload this sketch to your Arduino Uno using the Arduino IDE. Ensure your serial monitor is set to 115200 baud to see debug output." The generated source defines TRIG_PIN 2 and ECHO_PIN 3 for the sensor and ENA_PIN 9, IN1_PIN 8, IN2_PIN 7, ENB_PIN 10, IN3_PIN 6 for the L298N driver, matching the wiring table above exactly.

Who this build is for

This is a reasonable second robotics project once you've wired at least one sensor to an Arduino before, since the new skill here is coordinating a sensor reading with motor control rather than either one alone. Soldr's own build profile for this tray rated it "Difficulty: Beginner (every part plugs in, no soldering)" and suitable for "roughly 10+", with an adult handling the battery wiring and the wheels gap noted above before assembly. Budget an evening for chassis assembly and wiring, and a second short session for uploading and tuning the distance threshold once it's driving.

Get everything in this build

The exact parts Soldr picked above, at today's live price and stock — each links straight to checkout, or add the whole tray in one click. This tray does not include wheels for the chassis; source a wheel pair matching the TT gear motors' D-shaft separately before assembly.

Part Qty Price
Arduino Uno R3 CH340G ATmega328P Board 1 ₹230 Add to cart →
HC-SR04 Ultrasonic Sensor 1 ₹85 Add to cart →
L298N Motor Driver Module 1 ₹180 Add to cart →
TT Gear Motor (1:48, Dual Shaft) 2 ₹360 Add to cart →
2WD Robot Chassis Kit 1 ₹280 Add to cart →
9V Battery Snap Connector 1 ₹35 Add to cart →
Dupont Jumper Wire Kit (M-M, M-F, F-F, 20cm, 22AWG) 1 ₹60 Add to cart →
23 AWG Multi-Strand Breadboard Wire 1 ₹10 Add to cart →
Total ₹1,240 Add all to cart →

Prices and stock verified live at the time this was written; Compoden's storefront always reflects the current price at checkout. As flagged above, a single 9V battery is a workable starting power source for testing but is worth upgrading once both motors are running under load together, and a wheel pair for the two TT gear motors needs sourcing separately from this tray.

Built and Backed by Compoden

Every part above ships from Compoden's own India stock, checked for compatibility before it's carded together. Delivery in 3–7 days across India, with COD and UPI available at checkout. This exact tray also carries over into Soldr.dev after purchase, already populated with these parts, where it generates the wiring diagram, firmware, and test steps for this specific hardware combination rather than a generic robot-car guide. If a part doesn't perform as described, Compoden's support team will help you troubleshoot or replace it.

FAQ

What distance should the obstacle threshold be set to?
In the real firmware generated for this build, the threshold was 20cm — close enough that the robot doesn't stop for objects well off to the side within the sensor's roughly 15-degree cone, but far enough to stop and turn before contact given the motors' speed. It's a single number in the code, so it's easy to raise or lower once the robot is driving.

Can this robot avoid obstacles on both sides, or does it always turn the same way?
With a single fixed-forward HC-SR04 and no servo, the firmware generated for this exact tray always turns the same direction (right) once it detects something close, because it only has one distance reading to react to. Picking the actually clearer side requires either a second sensor or a servo-mounted sensor that can sweep and compare left versus right before choosing.

Does the Arduino Uno need a separate battery for the motors?
Yes in practice. The L298N motor driver's motor-side terminals run on a separate supply (6–46V) from its 5V logic side, and the two gear motors plus the driver can draw well past what a single 9V snap-connector battery sustains once both motors are moving the robot's weight. The Arduino and sensor logic can share the same battery through the driver's 5V logic rail, but sizing that battery for the motors' real draw, not just the Arduino's, matters for reliable operation.

How much does this exact build cost?
In a real live quote from Compoden's storefront, the eight parts — Arduino Uno, HC-SR04 sensor, L298N driver, two TT gear motors, a 2WD chassis kit, a 9V battery snap connector, and two types of wire — came to ₹1,240 total, not counting a wheel pair that the build assistant flagged as needed separately.

Back to blog