Skip to content

Robotics

How a wall following robot keeps its distance

A wall following robot holds a set distance from a wall with one sideways distance sensor. It works out an error, the reading minus the reading it wants, and steers in proportion: drift away and it leans back toward the wall, get too close and it leans away, more the further off it is. A safety guard checked first stops it outright if the wall comes far too close.

The error

With the wall on the robot's right, a sensor reads 0 touching and 1023 at 90 cm. To run at about 45 cm, aim for 512:

e = range − 512

Too far, e is positive. Too near, e is negative. On target, zero.

Which way to lean

Too far from a wall on the right means the nose should swing right: speed up the left wheel and slow the right.

left = 180 + e ÷ 8 right = 180 − e ÷ 8

At a reading of 768, e is 256 and each wheel moves 32: left 212, right 148, a lean toward the wall. At 400, e is −112: left 166, right 194, a gentle lean away.

Get the sign wrong and the loop runs away from itself. Start 30 cm out, a reading of about 340, and e is about −170. With the signs swapped the left wheel speeds up to 201, the nose swings toward the wall, the reading drops, e grows more negative, and it leans harder still, straight into the wall.

Live experiment

Get the sign right

RANGE looks out of the rover's right side: 0 touching, 1023 at 0.9 m, so 512 is 45 cm. Start 30 or 50 cm out. Lean the right way, left wheel 180 + e ÷ 8, and it weaves in to about 45 cm and runs along. Lean the wrong way and from near it steers into the wall; from far it wanders off across the room.

Try it yourself: free lesson

“Keep your distance” is lesson 2 of 6 in Encoder Edge, Robotics World 2. Free with an account. Lessons unlock in order, so you’ll do the 8 before it first.

A guard, then the steering

Proportion handles the normal case. A guard handles the one that shouldn't happen:

void loop() {
  int range = analogRead(A0);
  if (range < 100) {                 // about 9 cm: far too close
    analogWrite(9, 0);  analogWrite(10, 0);
    return;                          // skip the steering this pass
  }
  int e = range - 512;
  analogWrite(9,  constrain(180 + e / 8, 0, 255));
  analogWrite(10, constrain(180 - e / 8, 0, 255));
}

The guard comes first and ends the pass with return, so nothing below it can start the wheels again. Most robot loops have this shape: a guard, then a proportion.

What one side sensor can't see

The sensor only looks sideways, so a wall straight ahead is invisible to it; corners need a front sensor or a bumper. Dark or angled surfaces can read further away than they are. Robot vacuums run along skirting boards exactly like this, with a bumper as the last guard.

Free lesson

Now build it yourself

Each lesson comes in three short parts: see the idea, try it on a live board, then build it yourself, with quick checks as you go.

Try it yourself: free lesson

“Keep your distance” is lesson 2 of 6 in Encoder Edge, Robotics World 2. Free with an account. Lessons unlock in order, so you’ll do the 8 before it first.

Or start from the very first lesson, no account needed

Practice questions

Three quick questions from the lessons. Pick an answer to check it.

  1. Question 1 of 3Why does the stop rule come before the steering code?
    Show the answer

    Answer: So nothing after it can drive the wheels once the wall is far too close. The guard sets both wheels to 0 and returns. If the steering ran first, or after without the return, it could set the wheels moving again.

    • Why not “To save memory”? Moving the guard doesn't change the memory used. It's about which command wins.
    • Why not “The order doesn't matter”? It does matter: the last analogWrite wins, so steering that runs after the stop could start the wheels again.
    • Why not “It runs faster”? The order doesn't change the speed noticeably. It decides which command the wheels end up with.
  2. Question 2 of 3The stop is written after the steering lines instead of before. When range reads 50…
    Show the answer

    Answer: The wheels are set by the steer, then set to 0: it stops, but it's fragile and the order matters. Last write wins, so it happens to work. But the moment someone adds a line after it, it breaks. Guard first, return, then steer.

    • Why not “The same”? It works today, but only by luck of order: add a line after it and the stop is overwritten.
    • Why not “It never stops”? The stop writes 0 last, so the wheels do stop. It just relies on staying last.
    • Why not “It crashes”? Nothing crashes. The last write to each wheel simply wins.
  3. Question 3 of 3return inside loop() does what?
    Show the answer

    Answer: Ends this pass; loop() runs again from the top next pass. loop() is called over and over. return just leaves it early this time.

    • Why not “Ends the program”? Arduino calls loop() again straight away, so return only cuts this pass short.
    • Why not “Nothing”? It skips everything after it in loop() for this pass, which is exactly what keeps the steering from running.
    • Why not “Restarts the board”? Nothing resets. The next pass starts from the top of loop(), with global variables as they were.
Keep practising: free lesson

“Keep your distance” is lesson 2 of 6 in Encoder Edge, Robotics World 2. Free with an account. Lessons unlock in order, so you’ll do the 8 before it first.

Questions people ask

What sensor should a wall following robot use?

Any distance sensor pointing sideways: an ultrasonic HC-SR04, an infrared Sharp sensor or a time-of-flight VL53L0X. Check which way its reading goes. Many IR sensors read higher when the wall is closer, which flips the sign of the error and every lean after it.

Why does my wall follower weave back and forth?

The gain is too high for its speed, or the sensor reacts late. Each lean overshoots the set distance and the next lean overshoots back. Divide e by a bigger number, slow down, or add a D term that pushes against how fast the distance is changing.

What does return do inside loop()?

It ends this pass of loop() early. Arduino calls loop() again at once, so the next pass starts from the top. That's what lets a guard at the top stop the wheels without the steering below it running and starting them again.

Every topic