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.
- 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.
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 Ω.
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.
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:
- Everything blocks. The program is built on
delay(), so the car is blind while it turns its head or spins: about 1.5 s per decision. A state machine timed withmillis()would let it keep measuring the whole time. - Turns are open-loop. A turn is "spin for 0.5 s", so the angle depends on battery charge and floor grip. Wheel encoders or an IMU would make turns repeatable.
- One narrow beam. A single ultrasonic sensor sees a cone in front of it, so thin obstacles like chair legs can slip past.
Those limits (no feedback, no state estimation, a single sensor) are exactly what the hexapod later took on, with odometry, sensor fusion and lidar.