The Stair Climber: legs that reach up onto the next step, a body that hauls itself after them, and sensors that tell it whether any of that actually worked.
The obvious program is repeat 5 [climb one step]. It climbs two steps beautifully and then falls off, and the reason will be four cycles behind wherever you are looking.
By the end of the lesson your climber will confirm each step before attempting the next, retry when it fails, and stop and say so when retrying is not working.
In the real world 5 min
Where you have seen it
Climb a staircase in the dark and you will notice yourself doing it: each foot feels for the step and takes weight before the other foot lifts. You are not repeating a movement — you are repeating a movement plus a check.
The royal staircase at Palazzo Farnese. Photo: Livioandronico2013 / Wikimedia Commons (CC BY-SA 4.0).
The check is invisible until it fails. Miss one step at the top of a flight — the one that is not there — and the lurch you feel is your body discovering that the confirmation did not come.
Why it is built that way
Because in a repeated physical action, errors add up. A stair-climbing robot that ends each cycle two millimetres low is fine once, marginal twice and on the floor by the fifth.
So every serious repeated process verifies. A bottling line checks each cap went on. A pick-and-place machine checks the part is held before moving. A lift confirms it is level with the floor before the doors open — and if it cannot confirm, it does not open them.
What would go wrong without it
You get a machine that fails four cycles after the thing that went wrong, which is the hardest kind of bug to find. The symptom and the cause are in different places, and nothing on screen connects them.
A repeat block assumes. A verified loop knows — and can tell you which cycle failed.
The main concept — verify, retry, give up 6 min
A verified cycle has four parts, and most programs only ever have the first: do it, check it, retry if it failed, stop and report if retrying is not helping.
Part
On the climber
Without it
Do
Legs up, body hauled after them.
—
Check
Front foot in contact, and body angle back near level.
Failure is discovered several steps later, as a fall.
Retry
Back off slightly, try the lift again.
One marginal step ends the climb, even though a second attempt would have worked.
Give up
After three attempts: stop, report which step.
It retries for ever against a step it cannot climb. Stuck, not robust.
The check must test the outcome, not the command
“The motor reached 720 degrees” proves the motor turned. It does not prove the machine went up. Wheels slip, legs skid, the whole model can rock forward without gaining anything.
Check something that is only true if the climb succeeded — the front foot bearing on a surface, and the body back near level. Both are about the world, not about the program.
// this proves the motor moved
[B v] run for (2) [rotations v] at (40) % speed :: motors
// THIS proves the machine climbed
if <<[1 v] is pressed? :: sensors> and <([abs v] of ([2 v] angle)) < (8)>> then
set [step done v] to (1) :: variables
end
The first is a receipt for a command. The second is evidence about the world. Only the second can catch a slip.
Count the failures, not just the successes
A retry budget is one variable. Reset it when a step succeeds; add to it when one fails; stop when it hits three. Then the machine can distinguish “that was awkward” from “this is impossible” — and a robot that says “failed at step 4 of 6” has told you where to look.
ComponentSensing6 min
The Gyro Sensor
The Gyro Sensor measures how far the robot has turned, in degrees. Wheels slip and floors vary, so counting wheel rotations is a poor way to turn accurately — the gyro measures the turn itself rather than inferring it.
from above
front
The arrows moulded into the top show which way round the sensor measures. Mount it flat and the wrong way up and it will read your turns backwards.
Blocks reference
Block
What it does
([2 v] angle :: sensors)
Reports how far the robot has turned since the angle was last reset.
[2 v] reset angle :: sensors
Sets the current heading as zero.
Always reset before you turn
The angle is measured from wherever it was last zeroed — not from where this turn started. Here are two robots given the same instruction, one with a reset block and one without.
reset first
when program starts
2 reset angle
start moving right: 100
2 wait until angle >90
stop moving
no reset
start moving right: 100
2 wait until angle >90
0°actually turned · reset0°actually turned · no reset
Reset: a real 90° turnNo reset: 0°, and no warning
Both robots have been sitting still. Both gyros already read about 34° — left over from an earlier turn — and the reading is creeping upward even now. That creep is drift.The left program resets its angle to zero. The right program has no reset block.Both turn. Both stop the moment their gyro reads more than 90.The left robot turned 90°. The right one turned 55°, because it started counting from 34 — and it stopped at 90 all the same.Finished. Both readings say 90. Only one of the robots turned 90.
still
Both programs are correct about what they asked for. Only the left one asked the question from a known starting point.
Both programs did exactly what they said. Both gyros stopped at 90. But the robot on the right had 34 degrees already on the clock, so it only turned 55 — and nothing about the program looks wrong. Watch the first step too: neither robot is moving and the reading is still climbing. That is drift, and it is why the reset belongs immediately before the turn.
Reset with the robot completely still, as late as you can.
when program starts :: events hat
[2 v] reset angle :: sensors
start moving [straight: 0] :: movement
wait until <([2 v] angle :: sensors) > (90)>
stop moving :: movement
That program is the obvious one to write, and it will not give you a 90 degree turn. The next section is why.
Stop before you get there
Asking to stop at 90 does not stop the robot at 90. Between the gyro reaching 90 and the wheels actually standing still there is a delay — the sensor has to be read, the next block has to run, and the motors have to physically brake. The robot is still turning through all of it, so it ends up past where you asked.
The fix is to ask for less than you want. Aim for a 90 degree turn by waiting for 86: the robot coasts the last few degrees on its own and settles at roughly 89 to 91.
ask for exactly 90
2 reset angle
start moving right: 30
2 wait until angle >90
stop moving
stop 4° early
2 wait until angle >86
stop moving
slowthis run · 50°/s+4°carried past the stop86tolerance needed here
Asked for 90: ended at 0°Asked for 86: ended at 0°
Both robots are told to turn 90°. The left one waits for the angle to pass 90; the right one gives up 4° early and waits for 86.They turn. Each stops the moment its own condition is met — and then keeps going.That extra sweep in red is the latency: the time to read the gyro, decide, and actually halt the motors. Nothing was wrong with either program.Finished. At this speed the robot carries on about 4° past whatever angle the program stopped at.
slow turn
The tolerance has to match the speed. At 50°/s the number that lands this turn on 90° is 86 — let it loop, and watch that number change when the speed does.
The size of that gap is not a fixed property of the robot — it is the delay multiplied by how fast you are turning. The delay stays about the same whatever you do, so a turn at double the speed carries you about double the distance past the mark.
Turn speed
Carried past the stop
Wait for
Ends up at
slow
about 4°
86
about 90°
fast
about 10°
80
about 90°
So the tolerance and the speed have to be chosen together. Turn faster and you must give up more; if you speed a turn up and forget to lower the number, the robot starts overshooting every corner and the program that worked last week no longer does.
when program starts :: events hat
[2 v] reset angle :: sensors
start moving [right: 30] :: movement
wait until <([2 v] angle :: sensors) > (86)>
stop moving :: movement
Find your own number rather than copying this one — it depends on your robot’s weight, its wheels and the speed you turn at. Run the turn, measure where it actually stops, and move the number by however far it missed. Two or three tries is usually enough.
The other half of the answer is to slow down. A slower turn overshoots less, so it needs less guessing and repeats more reliably — which is why a turn worth getting right is rarely worth rushing.
Drift — the thing that catches everyone
A gyro slowly loses its zero even when nothing is moving. Leave a robot sitting still for a minute and the angle may have wandered several degrees all by itself. That is drift, and it is a property of the hardware, not a bug in your program.
Two habits deal with it: reset the angle as late as possible before a turn, and keep the robot dead still while the reset happens. Resetting while the robot is rolling bakes the error in permanently.
Why it matters
Aircraft, ships and phones all use gyros to know their orientation — it is how a phone knows you have turned it sideways. A robot that can turn exactly 90 degrees on any surface is far more reliable than one that guesses with wheel rotations.
ComponentSensing5 min
The Touch Sensor
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.
released
pressed
The red button out, and the same sensor with it pushed in. These two states are the entire output of this sensor — there is nothing in between.
Blocks reference
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.
Three different events
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.
when program starts
forever
if 1 is pressed? then
change count by 1
versus two hat blocks
1 when pressed
1 when bumped
0is pressed? in a loop0when pressed0when bumped
In a loop: 0 answers from one pressBumped: exactly one
Nobody is touching the sensor. All three programs are watching it.A finger presses the button. Watch the red button go in — a couple of millimetres is the sensor's entire movement.The finger is still down. The loop checking «is pressed?» has already run hundreds of times, and every one of them counted.The finger lifts. Only now does «bumped» count, because bumped means pressed AND released.One press. Three completely different answers.Finished. The same press, counted three ways.
released
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:
Pressed — the button is down right now. Good for “hold to run”.
Released — it is up again. Good for acting when somebody lets go.
Bumped — pressed and released. This is what you want for “click to start”, because it will not fire repeatedly while a finger stays down.
The classic bumper
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.
Why it matters
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.
ComponentData6 min
Variables
Why anybody needs one
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.
Abby never remembers the numberBen never sees a henThe wall holds it for both
Abby has a gate and a wall. Before a single hen comes through she chalks 0 on the wall — that is where the number is going to live.A hen goes through. Abby rubs out the 0 and chalks 1. Another goes through, and she does it again.Three hens have been through, and the wall says 3. Abby is not remembering the number — she is reading her own wall each time and writing the next one.Ben has been at the market all morning. He has not seen one hen. He walks up, reads the wall, and knows the answer — without asking Abby anything.That is a variable. Not a number in somebody's head, but a place both of them agreed on: one writes to it, the other reads from it, and it keeps the number in between.Finished. Abby wrote, Ben read, and the wall is what joined them up.
the wall holds it
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.
The paper, and the two things you can do to it
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.
score
0
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.
change leaves a trail — every value follows from the one before it. This is what counting is.
set wipes the sheet. Use it to start a count, never to continue one.
Press set score to 0 after counting up a few times and watch the whole history vanish. That is what happens to a count when a set block ends up in the wrong place — and it is the commonest variable bug there is.
Blocks reference
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, or change?
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
when program starts
set count to 0
repeat 4
A run clockwise for 1rotations
change count by 1
set inside it
repeat 4
set count to 0
A run clockwise for 1rotations
change count by 1
Before the loop: counted 0Inside the loop: stuck at 0
Both programs count the turns of a motor. The left sets the count to zero before the loop; the right sets it inside.Turn 1. Both counters read 1, and so far the two programs agree.Turn 2. The left count is 2. The right was set back to zero at the top of the loop, so it is 1 again.Turn 3. The left reads 3. The right still reads 1.Turn 4. The motor turned four times on both robots — only one of them counted them.Finished. Four turns, and one of the two counts is fiction.
stopped
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.
Anything oval is a number you can pick up
EV3 Classroom tells you what a block does by its shape, and once you have noticed that, a whole set of questions answers itself:
Oval — reports a number. The blue degrees counted, the timer, a distance, your own variable.
Pointed — reports true or false. These go in an if or a wait until, not in a variable.
Block-shaped — does something. These stack up; they do not fit inside anything.
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
set degree_turn to A degrees countedkeep it in a variable of your own
A degrees counted+10do arithmetic with it
A degrees counted>50compare it with a number
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.
Reset at the start, every time
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.
Why it matters
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.
Check the world, not the command. Retry a few times. Then say what failed and where.
▶Guard clausesFrom Lesson 19 — refusing to start something whose preconditions are not met. Verification is the same idea at the end of a cycle instead of the beginning.Show meHide
ComponentData6 min
Variables
Why anybody needs one
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.
Abby never remembers the numberBen never sees a henThe wall holds it for both
Abby has a gate and a wall. Before a single hen comes through she chalks 0 on the wall — that is where the number is going to live.A hen goes through. Abby rubs out the 0 and chalks 1. Another goes through, and she does it again.Three hens have been through, and the wall says 3. Abby is not remembering the number — she is reading her own wall each time and writing the next one.Ben has been at the market all morning. He has not seen one hen. He walks up, reads the wall, and knows the answer — without asking Abby anything.That is a variable. Not a number in somebody's head, but a place both of them agreed on: one writes to it, the other reads from it, and it keeps the number in between.Finished. Abby wrote, Ben read, and the wall is what joined them up.
the wall holds it
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.
The paper, and the two things you can do to it
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.
score
0
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.
change leaves a trail — every value follows from the one before it. This is what counting is.
set wipes the sheet. Use it to start a count, never to continue one.
Press set score to 0 after counting up a few times and watch the whole history vanish. That is what happens to a count when a set block ends up in the wrong place — and it is the commonest variable bug there is.
Blocks reference
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, or change?
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
when program starts
set count to 0
repeat 4
A run clockwise for 1rotations
change count by 1
set inside it
repeat 4
set count to 0
A run clockwise for 1rotations
change count by 1
Before the loop: counted 0Inside the loop: stuck at 0
Both programs count the turns of a motor. The left sets the count to zero before the loop; the right sets it inside.Turn 1. Both counters read 1, and so far the two programs agree.Turn 2. The left count is 2. The right was set back to zero at the top of the loop, so it is 1 again.Turn 3. The left reads 3. The right still reads 1.Turn 4. The motor turned four times on both robots — only one of them counted them.Finished. Four turns, and one of the two counts is fiction.
stopped
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.
Anything oval is a number you can pick up
EV3 Classroom tells you what a block does by its shape, and once you have noticed that, a whole set of questions answers itself:
Oval — reports a number. The blue degrees counted, the timer, a distance, your own variable.
Pointed — reports true or false. These go in an if or a wait until, not in a variable.
Block-shaped — does something. These stack up; they do not fit inside anything.
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
set degree_turn to A degrees countedkeep it in a variable of your own
A degrees counted+10do arithmetic with it
A degrees counted>50compare it with a number
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.
Reset at the start, every time
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.
Why it matters
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: “What would be true only if this step really worked?”
What’s in this build 4 min
Lift the model onto a step by hand and watch the Gyro and the Touch Sensor as it settles. Then do it badly, leaving it half on. The two readings should differ clearly — if they do not, no check you write will work.
Part
What it is doing here
EV3 Intelligent Brick
The log. When the climb fails it must say which step and why — a blank screen after a fall teaches nobody anything.
Large Motor ×2 — the legs
Do the climbing. Their degree counts are the receipt, not the evidence — an important distinction on a machine that can slip.
Medium Motor — the body lift
Hauls the body up after the legs. Where most of the small losses come from, and therefore what the retry re-attempts.
Touch Sensor — the front foot
Pressed only when the foot is genuinely bearing on a surface. Half the check, and the half that catches a foot hanging in space.
Gyro Sensor — the body angle
The other half. A climber that ended a cycle nose-up did not finish the step, even if its foot is touching something.
Build the staircase from identical blocks and measure the rise. If the steps differ, a failed cycle could be the machine or could be that one step — and you will not be able to tell which. Control the stairs before you debug the climber.
Ports — and the rule 4 min
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
Body lift (Medium)
A
The precise motor.
Left leg (Large)
B
The climbing pair.
Right leg (Large)
C
The other half.
Front foot (Touch)
1
Touch stays on 1 across the course.
Body angle (Gyro)
2
Gyro stays on 2 across the course.
Check your own build now:
Lift in A, legs in B and C, foot in 1, gyro in 2.
Sit the climber level on the floor and reset the Gyro to zero there. Every angle check is relative to that.
Measure your step rise in millimetres and write it on the stairs.
Put something soft where the climber would land if it fell backwards.
Connect the Brick 4 min
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.
▶How to connect the BrickUSB and Bluetooth, step by step, with a photograph of every screen. Open it if you have not done this before — or if pairing is not working.Show meHide
USB — the reliable one
Switch the Brick on with the dark grey centre button.
Cable into the Brick’s PC port — the small square socket beside the numbered ports, not one of the numbered ones.
Other end into the computer.
Bluetooth — name it first
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.
Name your Brick. On the Brick: Settings (the spanner) → Brick Name. Type something nobody else will pick, then press the tick. Every Brick is called EV3 until somebody changes it.
Turn Bluetooth on. Settings → Bluetooth. Tick Bluetooth and Visibility. Leave iPhone/iPad/iPod unticked.
Connect from EV3 Classroom. Click the Brick icon at the top of the programming area, find your Brick by name, and click Connect.
Say yes on the Brick. It asks “Connect?” with the computer’s name — choose the tick, then accept the passkey, which is already 1234.
Where to read it. The name sits in the bar across the very top of the screen, on every screen — so you can check which Brick you are holding at any moment without going into a menu. This one is EV3VE. A Brick nobody has renamed says EV3.Step 3, and the reason step 1 exists. Three Bricks in range — read the name before you click Connect. Pairing with the wrong one is not an error: it works perfectly, on somebody else’s robot.
Step 2.Bluetooth switches the radio on; Visibility is what lets the computer find you. With Visibility off your Brick works perfectly and simply never appears in the list.Step 4. Look at the Brick. It asks whether to accept and names the computer. Choose the tick.Then the passkey, already 1234. Press the tick again and you are connected.
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, definitely. A cable running down a staircase pulls the climber backwards a little on every step — which is exactly the small, cumulative error this lesson is about, arriving from your desk instead of from the machine.
Confirm the connection 2 min
Check the Brick icon: connected, or not.
Three motor tiles — A, B and C.
Two sensor tiles — 1 and 2.
Place the climber properly on a step, note both readings; then place it badly and note them again. Those two pairs of numbers define your success test. Write them down — you are about to encode them.
Stuck? The long version, with a photograph of every screen, is in the Brick & Bluetooth guide.
Make it move 10 min
Step 1 — the loop that assumes
when program starts :: events hat
repeat (5)
[B v] start motor [clockwise v] at (40) % speed :: motors
[C v] start motor [clockwise v] at (40) % speed :: motors
wait (1.5) seconds :: control
[B v] stop motor :: motors
[C v] stop motor :: motors
[A v] run to position (180) [degrees v] at (50) % speed :: motors
[A v] run to position (0) [degrees v] at (50) % speed :: motors
end
Five identical attempts and no idea whether any of them worked. Run it and count how far it gets — then run it again and watch it get a different distance.
Step 2 — verify, retry, give up
when program starts :: events hat
set [steps wanted v] to (5) :: variables
set [steps done v] to (0) :: variables
set [max tries v] to (3) :: variables
[2 v] reset gyro :: sensors
clear display :: display
repeat until <(steps done) = (steps wanted)>
set [tries v] to (0) :: variables
set [ok v] to (0) :: variables
repeat until <<(ok) = (1)> or <(tries) = (max tries)>>
change [tries v] by (1) :: variables
write (steps done) at line (1) :: display
write (tries) at line (3) :: display
// ---- DO: legs up, then haul the body after them ----
[B v] start motor [clockwise v] at (40) % speed :: motors
[C v] start motor [clockwise v] at (40) % speed :: motors
wait (1.5) seconds :: control
[B v] stop motor :: motors
[C v] stop motor :: motors
[A v] run to position (180) [degrees v] at (50) % speed :: motors
[A v] run to position (0) [degrees v] at (50) % speed :: motors
wait (0.5) seconds :: control
// ---- CHECK: did the WORLD change, not just the motors ----
if <<[1 v] is pressed? :: sensors> and <([abs v] of ([2 v] angle)) < (8)>> then
set [ok v] to (1) :: variables
else
// ---- RETRY: back off a little and let it settle ----
play sound [Mechanical / Blip 2 v] :: sound
[B v] run for (0.3) [rotations v] at (-30) % speed :: motors
[C v] run for (0.3) [rotations v] at (-30) % speed :: motors
wait (0.5) seconds :: control
end
end
if <(ok) = (1)> then
change [steps done v] by (1) :: variables
set status light to [green v] :: display
else
// ---- GIVE UP: stop, and say exactly where ----
set status light to [red v] :: display
write [STUCK AT STEP] at line (5) :: display
write ((steps done) + (1)) at line (7) :: display
play sound [Mechanical / Error v] :: sound
stop [all v] :: control
end
end
write [TOP] at line (5) :: display
play sound [Communication / Cheering v] until done :: sound
Do, check, retry, give up — the four parts, in that order. The screen shows the step number and the attempt number the whole way up.
steps done only increases after a successful check. A failed attempt costs a try, never a step — that single rule is what makes the count mean something.
The check uses both sensors. Either one alone can be satisfied by a machine that has not climbed.
The retry backs off first. Trying the same thing from the same failed position usually fails the same way.
Giving up is a feature. “Stuck at step 4” is a diagnosis; retrying for ever is a machine grinding itself against a stair.
What success looks like: it climbs, and when a step goes badly you see the attempt counter go to 2 and the climb continue. Make one step deliberately too tall and it stops with that step’s number on screen.
If it retries on steps that clearly worked, your angle tolerance is too tight — use the two pairs of readings from step 8 and put the threshold between them.
Change it and test 8 min
One change at a time. Predict, then run, then look.
Make one step in the middle 5 mm taller. The verified version should retry there and carry on. Run the step 1 program on the same staircase and compare.
Make one step much too tall. It should stop and name that step. Check the number on screen is the right one — an off-by-one here makes the diagnosis useless.
Check only the Touch Sensor. Find a position where the foot touches but the machine has not climbed. That is why the check has two parts.
Set the retry budget to 1, then to 10. One gives up on recoverable steps; ten grinds against impossible ones. Say which failure each one is.
Log every attempt — build a list of tries per step and show it at the top. A climb that needed two attempts on step 3 every single run is telling you something about step 3.
“It failed” is not a diagnosis. “It failed at step 4 after three attempts” is.
Where this goes 3 min
The climber checks one thing at a time, as it goes. It never needs to know anything about the stairs before it starts.
The next model does. The Colour Sorter is faster and tidier if it looks at the whole batch first, works out what is in it, and only then starts moving things.
Surveying before acting is not always right — it costs time, and the world can change while you are looking. Knowing when to plan and when to just start is the next lesson’s real subject.
Today the machine checked as it went. Next it looks before it moves at all.
Build it 15 min
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.
Challenges & mission 27 min
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.
Challenge 1
Define what success actually looks like.
Place the climber properly on a step and record the touch and gyro readings. Then place it badly — half on, nose up — and record them again.
Report both pairs and the thresholds you put between them. A check written without those four numbers is a guess.
Challenge 2
Show that checking the motor is not checking the climb.
Find a position where the leg motors have turned their full amount and the machine has not gone up — let a wheel slip, or hold it back with a finger.
Say in one sentence why a degree count can never catch that, and what your check uses instead.
Challenge 3
Tune the retry budget.
Make one step slightly too tall. Run with a budget of 1, then 3, then 10.
Report what happens in each case, and name the failure that a budget of 1 causes and the different failure that a budget of 10 causes.
Mission
Climb a staircase that is out to get you.
Build a six-step staircase in which one middle step is 5 mm taller than the rest and one is 3 mm shorter, and climb it.
Requirements:
1. A check that tests the world — touch AND body angle — not the motor degree counts.
2. A retry that backs off before trying again, because repeating from a failed position usually fails the same way.
3. A retry budget, with a stop and a message naming the step number when it runs out.
4. The step number and attempt number on screen throughout the climb.
5. Steps counted only after a successful check, never after an attempt.
Then make one step impossible and run it again.
The machine must stop with the right step number on screen. Check it is the right number — an off-by-one here makes the diagnosis worse than useless, because it sends the next person to inspect a step that was fine. "It failed" is not a diagnosis; "it failed at step 4 after three attempts" is, and producing that is the entire point of this lesson.