The Chinook: the twin-rotor transport helicopter, with a Medium Motor driving the rotors and an Ultrasonic Sensor underneath, measuring its height above whatever is below it.
You are going to make it hold a hover — keep a set distance from the ground as you move a board up and down beneath it. That is Lesson 5’s closed loop, and if you write it the same way it will twitch continuously.
By the end of the lesson your helicopter will hold its height and then go genuinely still — not because it stopped correcting, but because you told it what close enough means.
In the real world 5 min
Where you have seen it
The CH-47 Chinook has two big rotors turning in opposite directions, one at each end. That layout means it needs no tail rotor — the two cancel each other’s twist — and it can lift a great deal for its size. It has been flying since 1962 and is still in service, which is unusual for any aircraft.
Helicóptero CH-47 Chinook, Museo de los Vestigios de la Guerra de Vietnam, Ciudad Ho Chi Minh, Vietnam, 2013-08-14, DD 01. Photo: Diego Delso / Wikimedia Commons (CC BY-SA 3.0).
Its hardest routine job is the hover: holding position over a spot on a hillside while people or a load come off the ramp. The aircraft is never actually still. It is being pushed by gusts and by its own downwash bouncing off the ground, and the pilot and the flight-control system are correcting constantly.
Why it is built that way
An autopilot that tried to correct every millimetre of drift would be worse than one that did not. The controls would chatter, the airframe would be worked constantly, and the passengers would be shaken by a machine trying too hard to be perfect.
So every real control system has a deadband: a zone around the target inside which it deliberately does nothing. A house thermostat works the same way — it does not switch the boiler on and off at exactly 20°C, or the relay would clatter every few seconds. It heats to 20.5 and waits until 19.5 before starting again.
What would go wrong without it
Relays wear out. Motors overheat. Fuel is wasted. And the machine is noisy and unpleasant in a way that a slightly less accurate one is not. Chasing the last millimetre costs more than the millimetre is worth.
Perfect is expensive. Every real machine decides how wrong it is willing to be, and then rests.
The main concept — a zone where you do nothing 6 min
Lesson 5’s loop corrects whenever the error is anything other than zero — and the error is never exactly zero, because sensors are noisy and motors overshoot. So it corrects for ever. A deadband says: below this much error, do nothing at all.
forever
set [error v] to ((target) - ([4 v] distance in cm)) :: variables
[A v] start motor at ((error) * (3)) % speed :: motors
end
Lesson 5 as written. An error of 0.2 cm still commands 0.6% speed, so the motor is always doing something. This is the twitch.
forever
set [error v] to ((target) - ([4 v] distance in cm)) :: variables
if <([abs v] of (error)) > (2)> then
[A v] start motor at ((error) * (3)) % speed :: motors
else
[A v] stop motor :: motors
end
end
With a deadband of 2 cm. Inside 2 cm of the target the motor is genuinely off, and the model is genuinely still.
abs is why there is only one test. The absolute value throws away the sign, so “more than 2 cm out” covers too high and too low at once. Without it you would need two comparisons and an or.
The trade-off, stated honestly
Deadband
What you get
What you pay
None
As accurate as the sensor allows.
Never still. Motor always working, always buzzing.
Small (1–2 cm)
Still, and close.
Settles a little off target. Usually the right answer.
Large (10 cm)
Very still, very calm.
Visibly wrong — it stops well short and calls it done.
There is no setting that gives you both. Stillness is bought with accuracy, and choosing the exchange rate is the engineer’s job, not the program’s.
The other half: two thresholds, not one
A deadband stops the twitching around a target. A related trick stops flickering at a boundary: use a different threshold for switching on than for switching off.
if <(state) = [rest]> then
if <([abs v] of (error)) > (4)> then
set [state v] to [correct] :: variables
end
end
if <(state) = [correct]> then
[A v] start motor at ((error) * (3)) % speed :: motors
if <([abs v] of (error)) < (1)> then
set [state v] to [rest] :: variables
end
end
Starts correcting at 4 cm, stops at 1 cm. A value sitting on one boundary cannot flick back and forth, because the two boundaries are different.
That gap has a name — hysteresis — and you have already used it. Lesson 7’s chicken stopped at 15 cm and walked on at 25 cm, for exactly this reason.
ComponentControl5 min
Comparing and combining
A sensor that reports a number cannot be used to make a decision on its own — 23 is neither true nor false. An operator turns that number into an answer by comparing it with something.
Blocks reference
Block
What it does
<(x) > (50)>
True when the left value is bigger than the right.
<(x) < (50)>
True when it is smaller.
<<> and <>>
True only when both conditions are true.
<<> or <>>
True when at least one of them is.
Try it: which way round does it go?
Forget the symbols for a moment. A comparison is a question about position on a number line: is x to the left of the other number, or to the right? Left is smaller, right is bigger — and that is the whole of it.
Drag the orange x and the black marker, and change the comparison. The green stretch is every position of x that would make the answer true — so you can see where the answer flips before you get there. Turn not on and watch the green jump to the other side.
Drag either marker, or use the arrow keys.
-3 < 4true
is x to the LEFT of it?
< is true while x sits on the left. Slide x past the marker and it flips.
> is the same question the other way round — so exactly one of the two is true, unless the markers are on the same spot.
= is true for one single position out of twenty-one. Try landing on it. That is why a sensor is almost never compared with =: a reading passes straight through the exact number without ever being measured there.
not flips the answer, whatever it was. not (x < 4) covers everything x < 4 does not — including landing exactly on 4.
Try it: which numbers make it true?
The lab above asks one question at a time: is this x true? A robot never has just one x, though — a sensor reading slides up and down all the time, so what really matters is which stretch of the line makes the condition true. This one draws the whole answer at once.
Drag the circle to move the number you are comparing against, and change the comparison. Everything shaded green is a value of x that would make it true.
Drag the circle, or use the arrow keys. It moves in steps of 0.2.
x < 0.2x < 0.2
Every number to the left of 0.2 — but not 0.2 itself, so the circle is hollow.
Watch the circle, because it carries the part everyone gets wrong:
Hollow ○ — the boundary is not included. x < 0.2 shades everything left of 0.2 but leaves 0.2 itself out, because 0.2 is not less than 0.2.
Filled ● — the boundary is included. Choose = and nothing is shaded at all: one single number qualifies.
Now turn not on with x > 2 selected and watch two things happen together. The shading jumps to the other side, and the circle fills in — because “not greater than 2” means 2 or less, and 2 has to be part of it. That pairing is the whole reason a hollow circle is worth drawing.
Why a robot cares. Two conditions that look almost identical — light < 30 and not (light > 30) — differ by exactly one value, the reading of precisely 30. A robot sitting right on its threshold behaves differently under the two, and that is the sort of bug that only shows up occasionally and looks like a broken sensor.
Try it: and, or, not
These three join answers together rather than numbers. The trap is that English is looser than a program: “stop if it is close and the bumper is pressed” sounds like it covers both situations, when it covers neither on its own.
Flip the two conditions and watch the table. There are only four possible situations in total, and and and or differ on exactly two of them.
close: trueandbumper: falsefalse
close
bumper
and
or
true
true
true
true
true
false
false
true
false
true
false
true
false
false
false
false
and is fussy: it wants both. Three of the four rows are false.
and is true on one row out of four. It narrows — the robot acts less often, but more certainly.
or is true on three rows out of four. It widens — the robot acts more readily.
The two agree on the top and bottom rows and disagree in the middle. Whenever swapping one for the other seems to make no difference, you have only tried the rows where they agree.
Watch them decide
Two sensors are running below: an Ultrasonic reporting a number, and a Touch Sensor reporting true or false. Watch the comparison turn the number into an answer, and watch and and or disagree.
when program starts
forever
if distance < 15 and is pressed? then
stop moving
if distance < 15 or is pressed? then
play beep 60 for 0.2 seconds
Nothing is within 15 cm and the bumper is out. Both conditions are false.Something comes close. The comparison flips to true — the bumper has not been touched.It backs away, and instead the bumper is pressed. Now the other condition is the true one.Close AND pressed. Only now is «and» true — while «or» has been true ever since the first of them was.Finished. Four situations, and the two operators disagreed in three of them.
and false · or false
and was true in one row out of four. or was true in three. That is the whole difference, and it is why one of them makes a robot look broken.
The comparison is doing one job: it takes a reading that is neither true nor false and, by holding it against a number you chose, produces something a decision can use. The moment the blue fill crosses the black marker is the moment the answer changes.
Choosing the threshold
The number you compare against is a design decision, not a fact. “Close” for a parking sensor might be 15 cm; for a robot arm it might be 3. Pick it by measuring what the sensor actually reads in the situation you care about, then leave a margin.
Combining two conditions
and narrows: both must hold, so the robot acts less often but more certainly — stop only if something is close and the bumper is pressed. or widens: either will do, so the robot acts more readily — stop if something is close or the bumper is pressed.
In the four situations above, and was true in one of them and or in three. That is the practical difference: swapping one for the other does not adjust a robot slightly, it changes how often it reacts at all.
ComponentSensing6 min
The Ultrasonic Sensor
The Ultrasonic Sensor measures distance. It sends out a burst of sound too high for people to hear, listens for the echo, and works out how far away the surface is from how long the echo took — exactly how a bat finds a moth, and how a submarine uses sonar.
front
side
The two round openings on the front are the point of this sensor: one sends the burst of sound out, the other listens for the echo coming back.
Blocks reference
Block
What it does
([4 v] distance in [cm v] :: sensors)
Reports how far away the nearest thing in front of the sensor is, as a number in centimetres.
wait until <([4 v] distance in [cm v] :: sensors) < (15)>
Holds the program until something comes closer than 15 cm.
A number, not a yes or no
This is the important step up from the Touch Sensor. Touch gives you true or false; the Ultrasonic gives you a number, and the deciding is left to you. Pick a threshold below and watch where the robot ends up.
when program starts
start moving straight: 0
4 wait until distance <15cm
stop moving
60cm · reading15cm · threshold
Nothing is close. The sensor reports about 60 cm and the program waits.The robot drives forward. The sensor is sending a burst of sound and timing its echo, over and over, and the number falls.The reading has dropped past the threshold. The condition is true, so the robot stops.Try another threshold. The program is identical — only that one number is different.Finished. The threshold is yours to choose — the sensor only supplies the number.
stopped
The black line on the bar is the threshold; the blue fill is the reading. The robot stops the instant the fill crosses the line.
Three different robots, and only one number is different between them. That is what having a number rather than a yes-or-no buys you: the behaviour is tuned by editing one slot, not by rebuilding the program. It also means the sensor can never tell you it is “close” — close is a decision you make about a reading.
Why it matters
Car parking sensors, automatic doors at a shopping centre, and the sensor that stops a lift door closing on somebody all work this way. Reacting before contact is what makes a machine feel safe.
If your set has an Infrared Sensor instead
The Home/Retail EV3 set (31313) ships an Infrared Sensor and a Beacon in place of the Ultrasonic and Gyro sensors. The Infrared Sensor also measures distance, so the programs in this module work with it — but it reports a rough 0–100 proximity rather than real centimetres, and it is affected by sunlight and by dark surfaces in ways the Ultrasonic is not.
IR Sensor
Beacon
The Infrared Sensor and its Beacon, from the Home set. If your kit has these, expect proximity numbers rather than centimetres — and retune any threshold accordingly.
ComponentControl6 min
Making a decision
Up to now a robot has been able to wait for a sensor. Deciding is different: the robot checks the sensor and does one thing or another depending on the answer — and then carries on either way.
Blocks reference
Block
What it does
if <> then
end
Runs the blocks inside only when the condition is true. Otherwise skips them.
if <> then
else
end
Runs one set of blocks when true and a different set when false.
Deciding again and again
A decision made once, at the start, is almost never what you want. Here are two robots with the identical if-else, testing the identical sensor against the identical number — one inside a loop and one not.
decision inside a loop
forever
if distance < 15 then
stop moving
else · start moving
the same decision, once
if distance < 15 then
stop moving
else · start moving
247checks · in a loop1check · once only
Nothing is close, so both robots ask «is the wall within 15 cm?», both hear no, and both take the else branch and drive.The left robot is asking again, and again, and again. The right one asked once and has finished asking.Under 15 cm. The left robot's next check says stop, so it stops. The right robot has no next check.Same condition. Same sensor. Same number. Only the loop is different.Finished. One robot is parked; the other is against the wall.
wall far
A decision is only worth as much as the last time it was made. Inside a loop, that is a few milliseconds ago.
Nothing is wrong with the right-hand program’s decision. It asked the question, got a truthful answer, and acted on it correctly. It simply never asked again, and the world moved on. Decisions belong inside a loop, so the robot keeps re-deciding as things change.
when program starts :: events hat
forever
if <([4 v] distance in [cm v] :: sensors) < (15)> then
stop moving :: movement
else
start moving [straight: 0] :: movement
end
end
Four shapes, and how to choose
Once there is more than one question, decisions can be arranged in four ways. They look nearly identical stacked up in the editor, which is exactly why they get muddled — the thing that differs is not what the blocks say, it is which routes through them exist.
One question sorts them almost completely:
Are the questions…
Use
How many bodies can run
independent — any combination can be true
separate ifs
none, some, or all
one question, two answers
if / else
exactly one
the second only matters when the first is true
nested if
one, and only via the outer
mutually exclusive cases — exactly one should win
chained if / else
exactly one, the first that matches
Separate ifs — independent questions
Each if is asked no matter what the others answered, so any number of them can fire on the same pass. That is the right shape when the conditions genuinely have nothing to do with each other.
Both questions are always asked, so one pass can turn on the lamp, the fan, both, or neither. Dark and hot are unrelated — there is no reason answering one should stop the other being asked.
forever
if <[3 v] is ambient light intensity [< v] (20) %? :: sensors> then
[A v] start motor [clockwise v] :: motors
end
if <[4 v] is distance [< v] (15) [cm v]? :: sensors> then
[D v] start motor [clockwise v] :: motors
end
end
if / else — one question, two answers
Exactly one branch runs, every time. Reach for this whenever the robot must do something either way — and in preference to two ifs testing opposite conditions, which is the same idea written twice and can drift apart.
There is no route through this that runs both boxes, and none that runs neither. That guarantee is the reason to prefer it over two opposite ifs.
Nested if — a follow-up question
Putting one if inside another means the inner question is only ever asked when the outer one is true. Use it when the second question is meaningless otherwise: there is no point asking which side an obstacle is on when there is no obstacle.
The inner question sits on the outer one's yes route, so it is only reached when something is close. If nothing is close, the robot never asks which side it is on — because there is nothing to have a side.
if <[4 v] is distance [< v] (15) [cm v]? :: sensors> then
if <([2 v] angle :: sensors) < (0)> then
start moving [right: 50] :: movement
end
end
When not to nest. If you only want “both true” and nothing happens at the outer level, an and says it in one block and reads better:
if <<[4 v] is distance [< v] (15) [cm v]? :: sensors> and <([2 v] angle :: sensors) < (0)>> then
start moving [right: 50] :: movement
end
Nesting earns its place when something happens at the outer level too, or when there is an else at each level and the two mean different things.
Chained if / else — one winner out of several
This is the shape for a list of cases where exactly one should win: colour bands, distance bands, speed ranges. EV3 Classroom has no else-if block, so you build a chain by putting the next if inside the else of the last one.
Each question is only reached down the previous one's no route. The first that matches acts, and everything below it is never even asked — which is what makes overlapping bands safe.
And here is why it matters, because this is the single commonest bug in this whole module. Three bands written as three separate ifs are each perfectly correct, and together they are wrong: a reading of 20 is under 30 and under 60 and under 90, so all three run and the last one to run is the one that sticks.
three separate ifs
if light < 30 then
stop
if light < 60 then
go slowly
if light < 90 then
go fast
chained — if / else / if
if light < 30 then
stop
else
if light < 60 then
go slowly
else
go fast
↑ the rest is inside the else — never asked
3bands matchedgo fastseparate ifs dostopchained does
Separate ifs: 3 matched, last one winsChained: first match wins, rest never asked
The sensor reads 20 — a dark surface. Both programs should stop.The three separate ifs each ask their own question. 20 is under 30, so it stops… then 20 is also under 60, so it goes slowly… then 20 is under 90 too, so it goes fast. All three ran, and the last one wins.The chained version asked the same first question, got `yes`, and stopped. The other two live inside its else, so they were never even asked.Slide the reading up to 75 and both agree again — because only one band matches. The bug only shows itself where the bands overlap, which is most of the range.Finished. Same three bands, same reading — two different answers, because one shape stops asking and the other does not.
reading 20
Separate ifs are not wrong here so much as unguarded: nothing stops a second one matching. Chaining is what makes “the first one wins” true.
The rule to carry away: if the cases are meant to be exclusive, they must be made exclusive. Chaining does it by construction. Separate ifs only work if you are careful to write non-overlapping bands yourself — light < 30, 30 to 60, 60 and over — which is more to get right and easy to break later.
Why it matters
This is the point at which a machine stops following a script and starts responding. A thermostat, an automatic door, a robot vacuum — all of them are a decision inside a loop.
Decide how wrong is acceptable, then stop. A machine that never rests is not more accurate — it is just busier.
▶The closed loopFrom Lesson 5 — measure, compare, correct. Today it learns when not to.Show meHide
ComponentSensing6 min
The Ultrasonic Sensor
The Ultrasonic Sensor measures distance. It sends out a burst of sound too high for people to hear, listens for the echo, and works out how far away the surface is from how long the echo took — exactly how a bat finds a moth, and how a submarine uses sonar.
front
side
The two round openings on the front are the point of this sensor: one sends the burst of sound out, the other listens for the echo coming back.
Blocks reference
Block
What it does
([4 v] distance in [cm v] :: sensors)
Reports how far away the nearest thing in front of the sensor is, as a number in centimetres.
wait until <([4 v] distance in [cm v] :: sensors) < (15)>
Holds the program until something comes closer than 15 cm.
A number, not a yes or no
This is the important step up from the Touch Sensor. Touch gives you true or false; the Ultrasonic gives you a number, and the deciding is left to you. Pick a threshold below and watch where the robot ends up.
when program starts
start moving straight: 0
4 wait until distance <15cm
stop moving
60cm · reading15cm · threshold
Nothing is close. The sensor reports about 60 cm and the program waits.The robot drives forward. The sensor is sending a burst of sound and timing its echo, over and over, and the number falls.The reading has dropped past the threshold. The condition is true, so the robot stops.Try another threshold. The program is identical — only that one number is different.Finished. The threshold is yours to choose — the sensor only supplies the number.
stopped
The black line on the bar is the threshold; the blue fill is the reading. The robot stops the instant the fill crosses the line.
Three different robots, and only one number is different between them. That is what having a number rather than a yes-or-no buys you: the behaviour is tuned by editing one slot, not by rebuilding the program. It also means the sensor can never tell you it is “close” — close is a decision you make about a reading.
Why it matters
Car parking sensors, automatic doors at a shopping centre, and the sensor that stops a lift door closing on somebody all work this way. Reacting before contact is what makes a machine feel safe.
If your set has an Infrared Sensor instead
The Home/Retail EV3 set (31313) ships an Infrared Sensor and a Beacon in place of the Ultrasonic and Gyro sensors. The Infrared Sensor also measures distance, so the programs in this module work with it — but it reports a rough 0–100 proximity rather than real centimetres, and it is affected by sunlight and by dark surfaces in ways the Ultrasonic is not.
IR Sensor
Beacon
The Infrared Sensor and its Beacon, from the Home set. If your kit has these, expect proximity numbers rather than centimetres — and retune any threshold accordingly.
Say this back before moving on: “Close enough is a number, and I choose it.”
What’s in this build 4 min
Two electronic parts, and one of them is the reason this lesson is hard. Find the sensor and look at what it is pointing at.
Part
What it is doing here
EV3 Intelligent Brick
The fuselage. Its screen is an instrument today — you will watch the error hover near zero and see whether the motor is running.
Medium Motor — the rotors and the height arm
Drives the rotor gearing and, through it, the arm that raises and lowers the model. Medium because the response must be quick — a loop correcting through a slow motor oscillates however well it is tuned.
Ultrasonic Sensor — underneath
Measures height above the surface below. This is the noisy part: an ultrasonic reading jitters by a centimetre or so even against a still surface, and that jitter is exactly what a deadband absorbs.
The rotor gearing (not electronic)
Turn it by hand. Slack in the gear train shows up as the model overshooting on every correction — the motor stops but the arm keeps travelling.
Ultrasonic sensors dislike soft and angled surfaces. Cloth absorbs the pulse; a sloped board bounces it away. Use a flat, hard board as your “ground” and hold it level, or you will spend the lesson tuning against a sensor that is guessing.
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
Rotors / height (Medium)
A
The only motor, and the whole output of the loop.
Height sensor (Ultrasonic)
4
Ultrasonic stays on 4 across the course.
Check your own build now:
Motor in A, Ultrasonic in 4.
Point the sensor straight down. A sensor angled even slightly reads the distance along its own line, not the height — and the error grows the higher the model goes.
Hold a flat board 20 cm below and read the Brick screen. Watch the number for ten seconds without moving anything. Note how much it wanders — that is your noise floor, and your deadband must be bigger than it.
Check the height arm moves freely through its whole range.
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.
USB is the practical choice. You will change one number and download, many times over — this lesson is mostly tuning. Just keep the lead clear of the space under the sensor, because a cable in the beam is a surface.
Confirm the connection 2 min
Check the Brick icon: connected, or not.
One motor tile — A.
One sensor tile — 4, in centimetres.
Write down two numbers before you program anything: the height you want to hold, and how far the reading wanders when nothing moves. The first is your target; the second is the smallest deadband worth having.
Stuck? The long version, with a photograph of every screen, is in the Brick & Bluetooth guide.
Make it move 10 min
Write the twitchy one first. You need to see and hear the problem before the fix means anything.
Step 1 — no deadband
when program starts :: events hat
set [target v] to (20) :: variables
clear display :: display
forever
set [error v] to ((target) - ([4 v] distance in cm)) :: variables
[A v] start motor at ((error) * (3)) % speed :: motors
write (error) at line (3) :: display
end
Hold the board 20 cm below and keep it still. Watch line 3 and listen to the motor — it never stops working.
Step 2 — add the deadband
when program starts :: events hat
set [target v] to (20) :: variables
set [band v] to (2) :: variables
clear display :: display
forever
set [error v] to ((target) - ([4 v] distance in cm)) :: variables
if <([abs v] of (error)) > (band)> then
[A v] start motor at ((error) * (3)) % speed :: motors
set status light to [orange v] :: display
write [CORRECTING] at line (1) :: display
else
[A v] stop motor :: motors
set status light to [green v] :: display
write [HOLDING] at line (1) :: display
end
write (error) at line (3) :: display
end
Green and silent inside the band; orange and working outside it. The status light turns an idea into something you can see across a room.
The deadband is a named variable, not a number in a test. You are about to change it repeatedly, and one named place is the difference between tuning and hunting.
The light is not decoration. It reports which branch is running, which is the fastest way to tell “holding” from “too weak to move”.
Move the board slowly up and down. The model should follow it, then settle and go quiet when you hold still.
The error will not read 0 when it holds. It will read something inside your band, and that is the whole design — not a failure.
What success looks like: the model chases the board while it moves, then the light goes green, the motor goes silent, and it stays there.
If it never goes green, your band is smaller than the sensor’s noise — raise it above the wander you measured in step 8. If it goes green a long way from the target, the band is too wide, or the gain is too weak to close the last of the gap before it enters the band.
Change it and test 8 min
One change at a time. Predict, then run, then look.
Set band to 0. You are back to step 1. Listen — this is the sound of a machine with no tolerance.
Set band to 10. Very calm, and visibly wrong: it settles well short and declares itself happy. Measure how far off it stops.
Find your smallest band that still goes reliably green. Write it on the board with the noise figure you measured. The two should be close, and that relationship is the real lesson.
Raise the gain to 8 with your good band. It reaches the band faster and overshoots through it. Gain and deadband interact — neither is tuned alone.
Build the hysteresis version from the concept section: in at 4, out at 1. Hold the board exactly on the boundary and compare with the single-threshold version, which will flicker.
The deadband must be bigger than the noise, or the machine can never believe it has arrived.
Where this goes 3 min
Your helicopter holds a height and rests. It does one thing, though — everything in the program is about that single loop.
The next model drives somewhere and raises a bridge, and the two jobs need to agree with each other while both are running. Two parallel stacks, one shared variable, and a new class of bug: both of them writing to it.
Two stacks sharing a variable is the last structural idea in this half of Level 3 — and the one where reading the value at the wrong moment gives an answer that was true a fraction of a second ago and is not any more.
Lesson 5 made it correct. Today made it settle. Next it has to share.
This is what you are building: the EV3 Chinook helicopter.
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
Find your machine's smallest honest deadband.
Measure how much the Ultrasonic reading wanders when nothing moves. Then find the smallest band that still lets the status light go green and stay green.
Write both numbers on the board. The band should be a little bigger than the wander, and now you know why.
Challenge 2
Report how good the hover is.
While it holds, keep the largest error seen in the last few seconds and show it on screen.
That number is the honest quality of your hover. Change the gain and watch it change — you now have a measurement instead of an opinion.
Challenge 3
Two thresholds, no flicker.
Rebuild the loop with hysteresis: start correcting when the error exceeds 4 cm, stop when it falls below 1 cm.
Hold the board exactly at the boundary and compare against the single-threshold version. Then explain where you have seen this before — the chicken did it in Lesson 7 without naming it.
Mission
Hold a hover through a disturbance and prove how well it did.
The helicopter must hold a set height while a partner moves the board slowly up and down, then holds it still at a new height. It must settle — genuinely silent, light green — within three seconds of the board stopping, and settle within 3 cm of the target.
Both of those are measurable, and the machine must measure them itself: show the settling time and the final error on screen at the end of each disturbance.
Two rules:
1. Deadband, gain and target are all named variables at the top. No number buried in a test.
2. You must be able to state the trade-off you chose — how much accuracy you gave up to get stillness — as a number, not a feeling.
Then try to beat another group. The interesting part is not who wins, but whether the winner settled faster or simply declared victory sooner with a wider band. Check their deadband before you concede.
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.