Tutorial · Beginner · 18 min
Servo-Scan an Ultrasonic Sensor to Find Open Space
Mount an HC-SR04 on an SG90 servo and sweep it to measure distance at several angles, so your robot turns toward the most open direction instead of guessing.
Published
A single forward-facing distance sensor can tell a robot that something is ahead, but not which way is clear. So it turns blindly, often straight into another obstacle or a dead end. Mounting the HC-SR04 on an SG90 servo fixes this: the robot stops, looks left and right, and turns toward whichever direction is most open—the same trick a person does at a blind corner.
Why one fixed sensor traps the robot
Picture a robot that only sees straight ahead. It meets a wall, knows it must turn, but has no idea whether left or right is better. Pick wrong and it drives into the corner it just came from. A servo-mounted sensor turns one number (distance ahead) into a small map of the space around the front of the robot, so the turn is an informed choice, not a coin flip.
Mounting the sensor on the servo
Fix the HC-SR04 to the servo horn and mount the servo at the front-centre of the chassis, oriented so the horn sweeps the sensor left-to-right (not up and down). At the servo’s centre position the sensor should face dead ahead. That gives you a clean sweep from one side, through straight-on, to the other side.
Sweep and sample
Step the servo across a handful of angles and take a filtered reading at each. Reuse the clean distance function from reading the HC-SR04—a raw ping mid-sweep is far too noisy to steer on.
#include <Servo.h>
Servo scanner;
const int ANGLES[] = {30, 60, 90, 120, 150};
const int N = 5;
int bestAngle() {
long best = -1;
int bestA = 90;
for (int i = 0; i < N; i++) {
scanner.write(ANGLES[i]);
delay(180); // let the servo REACH the angle first
long d = medianCm(); // filtered read from the previous tutorial
if (d > best) { best = d; bestA = ANGLES[i]; }
}
scanner.write(90); // re-centre for driving
return bestA; // > 90 = open to the left, < 90 = right
}
Don’t read mid-move
The single most common bug here is reading before the servo arrives. servo.write() returns instantly, but the SG90 takes time to swing to the new angle. Ping too soon and the distance belongs to wherever the sensor was, not where you asked it to point. A short delay after each write()—enough for the servo to settle—makes every reading trustworthy.
Turning the scan into a decision
The angle with the largest distance is the most open direction. A couple of refinements keep it sensible:
- Prefer straight ahead on ties. If two directions read similar, bias toward centre so the robot doesn’t weave needlessly.
- All directions close? That’s a dead end—back up and scan again rather than nosing further in.
Speed versus coverage
More angles give a finer picture but a slower loop, and a slow loop means the robot reacts late. Three to five angles—left, ahead, right, plus a couple in between—is the usual sweet spot. Hand that “most open” decision to the obstacle-avoidance algorithm, and try the whole behaviour in the obstacle avoidance simulator before you build it.
Explore the graph
Part of these builds
Projects and learning paths that include this tutorial.
Further reading