Challenge 1
Cross an arena and recover from at least three collisions without ever being touched by a person. The bump count on screen must match the number of collisions you saw.
EV3 Robotics›Level 2 · Intermediate›Lesson 39
Level 2 · Lesson 39 · EV3-L02-3960 minutes · Ages 9–16 · Model: Auto Floor Mopping
The Auto Floor Mopper: a driving base with a mopping head and a bumper on the front wired to a Touch Sensor. It cleans until it hits something, and then it deals with it.
Every sensor you have used so far has been there to stop something happening. The saw would not start, the forklift would not lift, the garden robot would not water the wall.
This one lets the crash happen. The bumper is not a warning; it is a report that the robot has already hit the wall. What matters is what it does next.
Cleaning machines are everywhere now — walk-behind scrubbers in supermarkets and airports, and increasingly robots doing the same job unattended overnight.

The robot on the right has expensive sensors that look ahead — and it still has a bumper. Every one of them does.
Because sensing ahead does not work every time. Glass is invisible to some sensors, a chair leg is thin enough to fall between beams, and something can move into the robot’s path faster than it can react. The bumper is the layer underneath, for everything the clever sensors missed — and the machine is designed on the assumption that they sometimes will.
You will have seen the same thinking on a household robot vacuum: it wanders, bumps, backs off, turns a little and carries on. It is not following a map. It is recovering, over and over, and covering the room by persistence.
A machine that only prevents has nothing to do when prevention fails. It either stops dead and waits for a human — which is useless for an overnight cleaner — or it keeps driving into the wall until the battery runs out.
Design for things going right, and the first surprise stops you. Design for recovery and the machine keeps working.
The recovery is three steps, always in the same order, and it is worth memorising because you will write it again and again.
| Step | Why |
|---|---|
| 1 · Back away | You are touching the obstacle. Nothing else can work until you are not — a robot that turns while pressed against a wall just grinds. |
| 2 · Turn | Change direction, or you will drive straight back into the same thing. |
| 3 · Carry on | Return to normal work. The recovery is finished and the machine forgets about it. |
if <[1 v] is pressed?> then move [backward v] for (1) [rotations v] :: movement move for (0.5) [rotations v] at (35) (-35) % speed :: movement end
Notice there is no else. Recovery is genuinely a “sometimes” behaviour — the Lesson 13 shape rather than the Lesson 14 shape — because most passes of the loop have nothing to recover from.
Turn before backing away and the robot pivots while jammed against the wall: one wheel grips, the other scrabbles, and it ends up at an angle still touching. Back away first and it has room to turn cleanly.
The bumper must release. Reverse far enough that the sensor is definitely no longer pressed. If the robot backs off two centimetres and the bumper is still touching, the next pass of the loop sees a fresh bump and it reverses again, for ever.
Put this robot in a corner and watch what happens. It bumps one wall, reverses, turns into the other wall, bumps, reverses, turns back into the first. It can do that all day.
Real machines handle this by counting — if there have been several bumps in quick succession, do something bigger: a longer reverse, a much larger turn, or give up on that area. And counting events is exactly what Lesson 26 gave you.
The Touch Sensor is the simplest input the EV3 has: a button that is either pressed or not. That sounds trivial, but it is how a robot knows it has hit a wall, reached the end of a track, or been told to start by a person.
| Block | What it does |
|---|---|
wait until <[1 v] is pressed? :: sensors> | Holds the program here until somebody presses the sensor. |
<[1 v] is pressed? :: sensors> | Reports true or false. Drop it into a condition to make a decision rather than a wait. |
[1 v] when [bumped v] :: events hat | Starts a whole stack of its own. The dropdown chooses the moment: pressed, released or bumped. |
A button is not only “pressed”. One press is three things: the moment it goes down, the time it stays down, and the moment it comes back up. Watch what a single press does to three programs at once.
versus two hat blocks
The middle counter is the one that surprises people. Nothing is wrong with it — a loop really does check that fast, and every check really is a separate answer.
Nothing there is broken. A loop really does get round hundreds of times a second, and each time it asks is pressed? the honest answer is still yes — so if that loop plays a sound or counts something, it does it hundreds of times from one finger. The two hat blocks each fire once, and they fire at different moments: pressed the instant the button goes down, bumped only when it comes back up.
The three options, and what each is for:
when program starts :: events hat set movement motors to [B v] and [C v] :: movement start moving [straight: 0] :: movement wait until <[1 v] is pressed? :: sensors> stop moving :: movement
The robot drives until something presses the sensor. Note that the movement is started unmeasured on purpose — the sensor decides when to stop, not a distance.
Touch sensors are everywhere in machines you cannot see into: a lift knows the doors are shut, a printer knows the lid is closed, a washing machine will not spin until it is latched. They are safety devices as much as inputs.
Back away first. Always. You cannot manoeuvre out of something you are still touching.
Long before there were computers, people had exactly this problem. A shepherd counting sheep through a gate, a trader counting sacks of grain, a builder counting days — none of them can hold the number in their head while they get on with the work. So they scratched a mark on a wall, cut a notch in a stick, or wrote a number on a piece of paper. The number lived outside the person, in a place they had agreed on, and they could go back to it, read it, and change it.
Better still, once the number is written down somebody else can use it. Watch these two: one of them counts and writes, the other never sees a single animal and simply reads the wall.
Notice what never happens: Ben never asks Abby. He does not need to — the number is not in her head, it is on the wall, and the wall is there for anyone who needs it.
Neither Abby nor Ben is holding the number — the wall is. And notice what never happens: Ben does not ask Abby. He does not need to, because the count is not in her head. It is in a place they both agreed on, which is what makes it useful to more than one of them.
That is all a variable is. The robot cannot hold a number in its head either, so you give it a wall of its own, write a name at the top so everyone knows which wall is which — score, count, degree_turn — and the program can read what is on it and write something new. One part of the program writes; another part reads. Exactly Abby and Ben.
Say we are counting rotations of a motor. Before we start we write 0 on the paper. Every time the motor completes a turn we cross out what is there and write one more: 0 becomes 1, then 2, then 3. That is change — it has to read the old number to work out the new one.
set is the other thing you can do, and it is completely different: rub the whole paper out and write the number you want. It does not care what was there. Press the buttons and watch what happens to the crossings-out.
The paper starts blank, so we write 0 on it. That is what a variable is: a place to keep a number while the robot works.
| Block | What it does |
|---|---|
set [count v] to (0) | Puts a value in, replacing whatever was there. |
change [count v] by (1) | Adds to what is already there. |
(count) | Reports the current value, for use in a comparison or on the display. |
set replaces; change adds. Counting things needs change. Starting a count needs set. Both programs below have both blocks — the only difference is whether the set block is inside the loop or above it.
set before the loop
set inside it
Both programs contain both blocks. Only the position of set [count] to 0 is different.
The count on the right is not broken; it is being told to start again on every pass. Each time round the loop it is wiped back to zero and then changed by one, so the honest answer is always 1 — while the motor cheerfully turns four times. A counter stuck at 1 almost always means a set block that has slipped inside the loop.
EV3 Classroom tells you what a block does by its shape, and once you have noticed that, a whole set of questions answers itself:
So when a slot is oval, any oval fits it — and it does not matter in the least where that number came from. You can take the motor’s own A degrees counted and keep it in a variable you named degree_turn, then compare that with a number later. Pick an oval below and watch the same one drop into all three kinds of slot.
pick an oval
the same oval fits all three
Every one of those slots is oval-shaped, and A degrees counted is an oval — so it drops in. Nothing about where the number came from matters.
This is what makes a variable more than a counter. A sensor reading is true only at the instant you read it; copying it into a variable freezes it, so the robot can compare where it is now against where it was when something happened:
when program starts :: events hat [A v] reset degrees counted :: motors set [degree_turn v] to ([A v] degrees counted :: sensors) start moving [right: 30] :: movement wait until <(([A v] degrees counted :: sensors) - (degree_turn)) > (400)> stop moving :: movement
Read the condition aloud: how far the motor has gone now, minus where it was when we started, is more than 400. Both are ovals, so both can go into a subtraction, and the subtraction is an oval too — which is why it can go into a comparison. Ovals nest inside ovals as deep as you need.
A variable keeps its value after the program ends. Run the program again without setting it back and the second run begins where the first left off — the count starts at 14, the robot thinks it has already done the job. Every variable a program changes must be set to its starting value at the top.
A variable is the difference between a machine that repeats a fixed routine and one that responds to how things have gone — counting parts, tracking a score, remembering where it started.
Say this back before moving on: “Reverse, turn, carry on.”
| Part | What it is doing here |
|---|---|
| EV3 Intelligent Brick | Watches the bumper while driving, and counts how many times it has been hit. |
| Large Motor ×2 — the drive | Ports B and C. Driven as a pair for straight running, and deliberately opposed for the recovery spin. |
| Medium Motor — the mop | Works the mopping head. Runs throughout, using the non-waiting start from Lesson 7. |
| Touch Sensor — the bumper | Mounted behind a bumper bar that sticks out wider than the robot. A bumper narrower than the machine lets the corners hit things the sensor never feels. |
Sensors go in ports 1, 2, 3, 4. Motors go in ports A, B, C, D. They are not interchangeable, and nothing will tell you politely if you swap them.
| Part | Port | Why this one |
|---|---|---|
| Left drive (Large) | B | B is left, as the Movement blocks assume. |
| Right drive (Large) | C | C is right. |
| Mop (Medium) | D | Off the movement pair, running at its own speed. |
| Touch Sensor (bumper) | 1 | Touch is always port 1 in this course. |
Check your own build now:
Two routes, and either is fine. USB is the reliable one and the one to fall back on when a room’s Bluetooth is busy; Bluetooth leaves the robot free to move, which some models need.
Do these in order. Naming the Brick after you go looking for it in the list is how groups end up driving each other’s robots.
EV3 until somebody changes it.EV3.The two failures, every class, every time. The Brick has gone to sleep while you were building — press the centre button to wake it. Or you have paired with the group at the next table, which is why the name matters.
The long version, including Port View and how to read the port tiles, is in the Brick & Bluetooth guide.
Bluetooth. This robot drives into things on purpose and reverses out of them. A cable will be run over within about two bumps.
Mop forward until something is hit, recover, carry on — and keep count of how many times it happened.
when program starts :: events hat
set movement motors to [B v] and [C v] :: movement
set movement speed to (30) % :: movement
set [langgar v] to (0)
clear display :: display
write [MOP] at line (1) :: display
[D v] start motor at (70) % speed :: motors
forever
start moving [straight: 0] :: movement
if <[1 v] is pressed?> then
change [langgar v] by (1)
write (langgar) at line (4) :: display
play beep (50) for (0.2) seconds :: sound
move [backward v] for (1) [rotations v] :: movement
move for (0.5) [rotations v] at (35) (-35) % speed :: movement
end
endWhat success looks like: the mopper crosses the arena, hits a wall, beeps, backs off, turns, and sets off in a new direction — without stopping and without being touched. The number on screen goes up by exactly one per collision.
If it reverses repeatedly from one bump, the reverse is too short and the bumper has not released. Make it 1.5 rotations. If the count jumps by two or three per hit, the bumper is bouncing — the same fix helps.
Same arena every run. Watch the bump count — it tells you how hard the robot is finding your layout.
<(langgar) > (5)> and does something bigger — a longer reverse and a half turn — then sets langgar back to 0. Test it in the same corner.Step 5 is where three lessons meet. The bumper is the sensor from Lesson 16, the decision is the Switch from Lesson 13, and the count that makes “stuck” detectable at all is the variable from Lesson 26. None of them could have solved it alone.
A recovery that always does the same thing can loop for ever. Counting is how a machine notices it is not getting anywhere.
Build the model before you read any further. Everything after this is about making it do something, and none of it will make much sense with nothing on the table in front of you.
Use the viewer's own controls to zoom and turn pages. Fullscreen makes it big enough to build from.
Check the finished build against the picture before you switch anything on. A motor mounted the wrong way round is far easier to spot now than it is to debug later, when it looks like a program fault.
Work through the challenges in order — each is harder than the last. The mission comes after all three, and it is meant to make you plan before you build.
Cross an arena and recover from at least three collisions without ever being touched by a person. The bump count on screen must match the number of collisions you saw.
Prove the order matters. Swap the reverse and the turn so it turns first, run it into a wall, and describe exactly what goes wrong. Then put it back.
Get it out of a corner. Drive it into a corner deliberately and watch it fail, then use the bump count to detect that it is stuck and do something bigger. Test the fix in the same corner.
Clean a whole room, obstacles and all. Mark out an area with walls and put two or three obstacles inside it. Your machine has to cover the floor and keep working no matter what it hits, without anybody rescuing it. Plan the recovery on paper first: how far it backs off, how far it turns, and what it does differently when it has bumped several times in a row. Decide how long you will let it run, and how you will judge coverage — chalk marks, scattered paper, or a sketch of where it went. Then run it for the full time without touching it. Note every place it got stuck. Two questions when you present it. Where did it fail to reach, and was that a recovery problem or a coverage problem? And your robot turns by the same amount after every bump — describe what turning by a random amount instead would change, and whether it would be better.
