Steer in proportion to the error from the target distance.
What the message means
On or off steering swings the robot from side to side. A proportional correction is smoother and settles.
Fix it in this order
- Choose a target distance from the wall.
- Measure the side distance and subtract the target.
- Multiply the error by a small gain to get a steering change.
- Limit the steering change to a safe maximum.
- Ignore tiny errors with a small dead zone.
- Filter the sensor readings first.
Why it happens
A bang-bang rule, turning left or right by a fixed amount, makes the robot swing across the target distance. Proportional control turns by an amount proportional to the error, so small errors give small corrections. A gain that is too high makes it oscillate; one that is too low makes it drift into the wall.
Example: proportional steering
const int TARGET_CM = 20;
const float KP = 3.0; // start low, raise until it just starts to wobble, then back off
const int BASE = 150; // base PWM
void followWall(int distanceCm) { // use a median-filtered reading
int error = distanceCm - TARGET_CM; // + means too far from the wall
int correction = constrain((int)(KP * error), -60, 60);
setMotors(BASE - correction, BASE + correction); // your function: left, right
}
Example sketch: change pins and values for your own wiring. It has not been bench-tested on your hardware.
Tuning
Filter the distance reading first so spikes do not become steering kicks, and limit the correction so one bad sample cannot spin the robot. Change one value at a time, and test the same stretch of wall each time.
If you see this, do this
| You see | Do this |
|---|---|
| Swings side to side | Gain too high. |
| Drifts away from the wall | Gain too low. |
Related
Last reviewed: November 2026. These are the usual causes and the order that finds them fastest. Test on your own board; clones and cables differ.
Why this happens
On-off steering reacts only to the sign of the error: too close, turn away; too far, turn toward. It cannot correct small errors gently, so it overshoots on every correction and the robot weaves. Proportional steering computes the turn from the size of the error, so a small error gives a small correction and the robot settles on the target.
Sensor rate also matters. An HC-SR04 style sensor is usually read every 50 to 60 ms at most. If the gain is large, a correction is applied for several loops before the robot sees its effect, and it overshoots again. A moderate gain and a filtered reading give the smoothest path.
How to confirm the cause
- Print the distance reading and the correction together. If the reading jumps by large amounts between samples, filter it before blaming the gain.
- Place the robot parallel to the wall at the target distance. It should go straight. If it veers, the motors are unbalanced, not the control.
- Start with a low gain. Increase it until the robot begins to weave, then use about half of that value.
- Watch which side the robot errs. A constant offset from the target means the sensor is angled or the target value is wrong.
- Check the correction limits. If the output sits at the limit for long periods, the gain is too high for the base speed.
Worked example
Working through the numbers with the wall on the left, target 20 cm, gain 3 and base speed 150:
distance 26 cm -> error = 26 - 20 = +6 -> correction = 3 x 6 = 18
left = 150 - 18 = 132, right = 150 + 18 = 168 -> turns left, toward the wall
distance 14 cm -> error = -6 -> correction = -18
left = 168, right = 132 -> turns right, away from the wall
int median3(int a, int b, int c) {
return max(min(a, b), min(max(a, b), c));
}Common mistakes
- Mixing the sign convention, so the robot steers into the wall.
- Using a gain that is too large and hiding the wobble with a slower base speed.
- Reading the sensor faster than it can measure, which gives false echoes.
- Mounting the sensor so it looks forward along the wall as well as sideways, which changes the readings in corners.
- Using no limit on the correction, so a bad sample spins the robot.
If this did not fix it
- Unequal motors, which make a constant drift that proportional control then has to fight.
- A wall with gaps or doors that the sensor sees as sudden jumps; add a rule for large steps.
- Adding derivative or integral terms too early. Get the proportional part stable first.