Kevin Corvisier
← All projects

Project 03, 2022

Obstacle-Avoiding Robot Car

A small four-wheeled robot that drives until something gets in its way, then turns its ultrasonic "head" to look left and right and heads for the side with more room. A pair of speakers and an MP3 module give it a voice.

Small black 3D-printed robot car with four rubber wheels, a twin-eye ultrasonic sensor at the front and a speaker opening on the side
The finished car. The ultrasonic sensor sits low at the front, and there is a speaker behind the opening on each side of the shell.
Controller
Arduino Uno
Drive
4 × DC gear motors (3–12 V) on an L298N dual H-bridge
Sensing
HC-SR04 ultrasonic rangefinder, swept by an MG90S metal-gear micro servo
Sound
DFPlayer Mini MP3 module + 2 × CQRobot 3 W, 4 Ω speakers in series, one per side
Body
Two-deck chassis and shell, designed in Fusion 360 and printed in PETG on a Creality Ender 3
Code
Arduino C++, about 200 lines

Design

I designed the car in Fusion 360 and printed every structural part in PETG on a Creality Ender 3. It is built in two decks. The lower deck carries the four gear motors, the motor driver, the battery pack and the sensor servo. The upper deck holds the Arduino Uno with a breadboard for the wiring, and the two speakers, one facing out of each side. A two-part printed shell covers everything. The ultrasonic sensor sits on a bracket on the servo at the front, low enough to see obstacles at wheel height.

Exploded CAD view of the car: wheels and yellow gear motors on the lower plate, a servo with the ultrasonic sensor at the front, the upper plate with the speakers, and the two-part shell above
Exploded view of the Fusion 360 model: lower deck with the motors and driver, upper deck, and the two-part shell.
Side view of the car showing the wheels, yellow gear motors, the two decks and one of the speaker openings
Side view: both decks, the gear motors and one of the two speaker openings.
Front view of the car showing the HC-SR04 ultrasonic sensor below the shell
Front view: the HC-SR04's two transducers look out under the shell.

Wiring

Everything runs from one Arduino Uno, with the connections made on a breadboard beside it on the upper deck. The motors are driven in two channels of the L298N, with PWM on the enable pins setting the speed. The servo and the ultrasonic sensor use three digital pins. The MP3 module talks over a software serial port, with a 1 kΩ resistor in series on the line into the module, as is usual for the DFPlayer. The two 4 Ω speakers are wired in series, so the module's amplifier sees 8 Ω, comfortably within what it can drive. In parallel they would present only 2 Ω.

Wiring: Arduino pins 3, 2, 7, 4, 5 and 11 go to the L298N's ENA, IN1 to IN4 and ENB; pin 12 to the MG90S servo; pins 9 and 10 to the HC-SR04 trigger and echo; pin 8 through a 1 kilohm resistor to the DFPlayer's RX, and pin 6 to its TX; the DFPlayer drives the two speakers, wired in series. L298N driver ENA IN1 IN2 IN3 IN4 ENB OUT1·2 OUT3·4 Motors Aone side Motors Bother side Arduino Uno D3 ~ D2 D7 D4 D5 D11 ~ D12 D9 D10 D8 (TX) D6 (RX) MG90S servo SIG carries HC-SR04 TRIG ECHO DFPlayer Mini RX TX SPK1 SPK2 1 kΩ Speakerleft, 4 Ω Speakerright, 4 Ω
Signal wiring, drawn from the pin numbers in the code. In colour: the PWM lines that set motor speed, and the servo signal. The two speakers are in series. Power and ground lines are left out for clarity.

How it avoids obstacles

The HC-SR04 sends a 10 µs ultrasonic burst and times the echo: half the round trip, times the speed of sound, gives the distance. If no echo comes back within 25 ms, meaning nothing is within about 4 m, the road counts as clear.

The car checks straight ahead every 40 ms or so while driving. When something is closer than 40 cm, it stops, plays a sound, and looks around: the servo turns the sensor 40° to the right, then 40° to the left, taking a reading each way. The car then spins in place toward whichever side had more room, and starts again.

Top view: the sensor checks straight ahead while driving; within 40 cm of an obstacle it looks 40 degrees right and 40 degrees left and turns toward the longer reading 40 cm obstacle 90°: checked while driving 50°: look left 130°: look right turn toward the longer reading
Top view of one decision, not to scale. The servo angles come from the code: 90° is straight ahead, 50° and 130° are the two side looks.
Control loop flowchart: measure ahead; if clear, drive forward and repeat; if an obstacle is within 40 cm, stop and play a sound, look right then left, turn toward the side with more room, stop briefly, and repeat Measure distance aheadservo at 90° obstacle within 40 cm? Drive forwardboth sides at PWM 100 Stop and play a sound Look right, then leftservo to 130°, then 50° more room on the right? Turn right in placePWM 200 for 0.5 s Turn left in placePWM 200 for 0.5 s Stop for 0.2 s no yes yes no
The whole control loop. Turns are timed rather than measured: half a second of spinning at higher power, then a short stop before the next reading.

Sound

The DFPlayer Mini reads MP3 files from a microSD card and drives the two speakers directly with its built-in amplifier. The Arduino only sends it short serial commands, such as set the volume or play track 2, so playing audio costs almost no processing time. The car plays one track when it starts up and another when it finds an obstacle.

Looking back

This is the oldest project on this site, and looking at the code now, there are three things I'd do differently:

Those limits (no feedback, no state estimation, a single sensor) are exactly what the hexapod later took on, with odometry, sensor fusion and lidar.