Challenge 1
Build a three-line panel: the machine's name on line 1, the arm's state on line 3, and the speed you are running at on line 5. All three must be on screen at the same time, and only the state line may change while the arm moves.
EV3 Robotics›Level 1 · Beginner›Lesson 15
Level 1 · Lesson 15 · EV3-L01-1560 minutes · Ages 9–16 · Model: Folding Fire Escape
The Folding Fire Escape: a tower with a long arm hinged at its base. A motor winds a string, the string pulls, and the arm swings up and out with a hook at its tip.
Let the string back out and the arm folds down against the tower again. That is the whole machine — one motor, one string, one pivot, and a lot of reach.
The Brick has been telling people things for a while now: a picture in Lesson 9, a line of text in Lesson 15, a colour in Lesson 16. Each of those said one thing at a time. A rescue machine needs to say several at once, and today the screen stops being a message and becomes a panel.
A fire engine with a ladder that unfolds off its roof and reaches up the side of a building. In Malaysia the Bomba run them in every major town, and they matter more every year, because the buildings keep getting taller.

The arm turns about a fixed pivot at its base. It does not grow out of the truck like a telescope — it swings, the way your arm swings from your shoulder, and that is what “folding” means here.
Pulling it up with a string is a clever trick worth noticing. A string can only pull, never push, so the same motor raises the arm by winding in and lowers it by letting gravity do the work. You get two directions of movement out of one direction of force.
Now think about the crew. The person at the controls is at the bottom and cannot see the top. They need to know several things at the same time: how high the arm is, which way it is moving, and whether it is safe to climb.
One thing at a time is no use to them. A display that showed the height, then wiped it and showed the direction, then wiped that, would be worse than a piece of paper.
An operator needs a panel, not a conversation. Several facts, all visible at once, each in the place they always live.
The Brick’s screen holds eight lines of text, numbered 1 at the top to 8 at the bottom. Writing to one of them leaves the other seven exactly as they were.
| Block | What it does |
|---|---|
write [EV3] at line (1) :: display | Puts text on that line only. Everything else on the screen stays. |
write [EV3] at x: (1) y: (1) with font [normal black v] :: display | Places it by pixel instead of by line, and lets you pick the font. More control, more to get wrong. |
clear display :: display | Wipes all eight lines at once. The only thing that does. |
That first row is the whole idea. Write a title to line 1 at the start of the program and it will still be there ten blocks later, because nothing you do to line 3 can reach it. So you can build a layout: line 1 is what this machine is, line 3 is what it is doing, line 5 is a number that keeps changing.
the screen is 178 pixels across and 128 down
The arrows are the two numbers. The one along the top is x; the one down the side is y, and it counts downwards from the top edge.
One trap, and it is the same one from Lesson 9. Writing a short word over a longer one does not erase the tail of the old one. Put DOWN over RISING and the line reads DOWNNG. Pad your words to the same length with spaces, or clear the display first.
Decide what lives on which line before you write a block. A panel with a fixed layout can be read at a glance; one that moves around cannot.
The Brick’s screen is a small black-and-white whiteboard. You can wipe it, draw one of the built-in pictures on it, or write your own words at a spot you choose. It is how the robot tells a person what it is doing.
| Block | What it does |
|---|---|
clear display :: display | Wipes the screen blank, ready for something new. |
display [Eyes / Neutral v] :: display | Draws a built-in picture chosen from a list — eyes, faces, arrows, symbols. |
display [Eyes / Neutral v] for (2) seconds :: display | Draws the picture, holds the program for that long, and then carries on. Handy when a face should be seen before anything else happens. |
write [Hello] at line (1) :: display | Writes your own text on one of the screen’s eight lines. |
write [Hello] at x: (10) y: (40) with font [normal black v] :: display | Writes text at an exact spot instead of a line, and lets you choose the size. Use it when a message has to line up with something else on the screen. |
The screen has no memory of whose writing is whose. It keeps every mark until something wipes it — including the marks left by the last run. Watch the same program with and without its clear display block.
with clear display
without it
Let it loop two or three times. The left screen still reads cleanly; the right one is the same program with one block missing.
Both Bricks are told exactly the same thing. The left one wipes the screen first, so line 7 holds one message and reads correctly. The right one never wipes, so each new message is drawn over the last and the words turn into a smudge. This is why a program that seems to display nonsense is usually displaying the truth — several times over.
There are two blocks for writing text, and they describe where in two completely different ways. Watch one message move around the screen under both of them.
the screen is 178 pixels across and 128 down
The arrows are the two numbers. The one along the top is x; the one down the side is y, and it counts downwards from the top edge.
write [EV3] at line (1) is the simple one. You give it a line number and it puts the text there, starting hard against the left edge — you do not choose how far across, only how far down.
For most robots this is all you need: a status word on line 1, a reading on line 3, a warning on line 5. Pick your lines at the start and keep each one for one job, the way you would keep one colour of status light for one meaning.
write [EV3] at x: () y: () with font [] treats the screen as a grid of pixels — 178 across and 128 down — and lets you put the text anywhere on it.
The block ends with a font dropdown, and normal black is the usual choice. A larger font makes the writing easier to read from across the room but takes more room across the screen, so fewer characters fit before the text runs off the edge.
The text slot of either block will take a reporter, so a sensor value can be shown directly: drop (4 distance in cm) into the slot and the screen shows the reading. That is the EV3’s version of a print statement, and it is the fastest way to find out what a robot actually thinks it is seeing.
A bare number on its own is hard to read, though. To show DIST: 23 rather than 23, use the operator block join [DIST: ] () to glue the label to the value, and put the join into the write block’s text slot.
when program starts :: events hat clear display :: display forever write (join [DIST: ] ([4 v] distance in [cm v] :: sensors)) at line (1) :: display end
Note the forever: a value written once is a value from the start of the program. To watch a reading change, the write block has to be inside a loop.
Once one value is on the screen the rest follows, and the useful trick throughout is join: it glues two pieces of text together and hands the result to the write block. Anything that reports a value can go in either slot — a variable, a sensor, or another join.
Counting is the classic case. A variable counts how many times the Touch Sensor has been pressed, and a bare 5 on the screen tells nobody anything — PRESSED: 5 tells them everything:
when program starts :: events hat clear display :: display set [count v] to (0) :: variables forever wait until <[1 v] is pressed? :: sensors> change [count v] by (1) :: variables write (join [PRESSED: ] (count)) at line (1) :: display wait until <not <[1 v] is pressed? :: sensors>> end
The two wait until blocks are what make it count presses rather than counting as fast as the loop runs while your finger is down. That is the Touch Sensor’s own lesson, but it shows up here because a counter on the screen is where you first notice it going wrong.
Give every reading its own line and keep it. A line that changes meaning halfway through a program is unreadable at a glance, which is the only speed a screen on a moving robot gets read at.
when program starts :: events hat clear display :: display forever write (join [DIST: ] ([4 v] distance in [cm v] :: sensors)) at line (2) :: display write (join [DEG: ] ([A v] degrees counted :: sensors)) at line (5) :: display end
degrees counted is worth putting on the screen the first time you use it — it is the fastest way to find out whether a motor is turning as far as you think it is, and it is the block behind every “why did it stop early” question.
Sensors report numbers, and people read words. The Colour Sensor reports 5; the person watching wants RED. A chain of if … then … else blocks does the translation, and it is worth doing once into a variable rather than in every write block:
if <([3 v] color :: sensors) = (5)> then
set [name v] to [RED] :: variables
else
if <([3 v] color :: sensors) = (4)> then
set [name v] to [YELLOW] :: variables
else
set [name v] to [OTHER] :: variables
end
end
write (join [COLOR: ] (name)) at line (4) :: displayThe same shape turns a distance into a warning. Here the screen carries the number and what the number means, which is what lets somebody across the room tell whether the robot is about to hit something:
if <([4 v] distance in [cm v] :: sensors) < (10)> then
set [status v] to [TOO CLOSE!] :: variables
else
if <([4 v] distance in [cm v] :: sensors) < (30)> then
set [status v] to [OBSTACLE FOUND] :: variables
else
set [status v] to [NOTHING FOUND] :: variables
end
end
write (status) at line (3) :: displayDrive all four of those at once below. The screen is the real thing — five write blocks, five lines, and every one of them a join.
Drive the sensors and read the screen. Every line is one write block with a join in its text slot.
| Line | What goes in the write block | On the screen now |
|---|---|---|
| 1 | join "PRESSED: " (count) | PRESSED: 3 |
| 2 | join "DIST: " (4 distance in cm) | DIST: 24 |
| 3 | (status) — set by the if chain | OBSTACLE FOUND |
| 4 | join "COLOR: " (name) | COLOR: RED |
| 5 | join "DEG: " (A degrees counted) | DEG: 180 |
Line 4 says COLOR: RED, but the sensor only ever said 5. The if chain in between is what turns a number into a word.
The moment a reading goes inside a loop, one of two things goes wrong, and which one depends on where the clear display block went.
Almost everybody tries clear inside the loop first. It gives the right text — and a screen that blinks several times a second, because between the clear and the write there is genuinely nothing on the screen and the loop goes round faster than your eye.
So the clear gets moved to the start of the program, the blinking stops, and the words go wrong. Writing text paints only the characters it has and leaves everything past them exactly where it was. Write RED over YELLOW and the LOW is still there: the screen says REDLOW. Go the other way — yellow first, then red — and it looks fine, which is why this bug takes so long to pin down.
when program starts :: events hat clear display :: display forever write (name) at line (3) :: display end
Watch the bottom three rows rather than the Brick. They are what the screen is actually doing: old characters, new characters, and whatever survives.
The fix is to make the new text at least as long as the old one, and join already does that: pad it with spaces. RED plus three spaces is six characters — exactly enough to paint over YELLOW. Nothing is left behind, and nothing is ever blank.
write (join (name) [ ]) at line (3) :: display
Pad to the length of the longest thing that line can ever show. Six characters covers RED, BLUE and GREEN but not NOTHING FOUND — count the longest message, and add spaces to match. The same applies to numbers: DIST: 5 after DIST: 40 leaves a stray 0 on the end, so a line that shows a two-digit reading needs a trailing space.
Use clear-inside-the-loop when the whole screen changes at once and a flicker does not matter; use the padding trick whenever a value is being watched.
Once several values need showing, the line number becomes a counter and the values come out of a list: write item 1 at line 1, item 2 at line 2, and so on inside a repeat. That needs the list blocks rather than the display blocks, so it lives with them — Lists covers building one and reading it back item by item, and the loop that walks it is the same loop that fills the screen.
Machines in the real world tell you what they are doing: a microwave counts down, a lift shows its floor, a car dashboard warns you. A robot that shows WAITING and then OPEN is far easier to understand — and far easier to debug — than one that moves silently.
Say this back before moving on: “Writing to line 3 does not touch line 1. Only clear display wipes everything.”
Two electronic parts, and one piece of string that matters as much.
| Part | What it is doing here |
|---|---|
| EV3 Intelligent Brick | Runs the program and carries the screen — which today is the operator’s control panel. |
| Medium Motor | Winds and unwinds the string. The flat slab one. It is not lifting much, so speed matters more than force. |
| The string (no cable) | The part that actually raises the arm. It can pull and it cannot push — remember that when the arm refuses to go down. |
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 |
|---|---|---|
| Medium Motor (winds the string) | A | A single working motor takes A, as it has all course. |
| The screen | none | Part of the Brick. Nothing to plug in. |
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.
Either is fine, but keep the cable clear of the string. A USB lead lying across the winding axle will foul it, and the symptom — an arm that lifts partway and stops — looks exactly like a program with the wrong number in it.
Seven blocks, and two of them build the panel. Put your own measured number in place of the 180.
when program starts :: events hat clear display :: display write [FIRE ESCAPE] at line (1) :: display write [ARM: DOWN ] at line (3) :: display [A v] set speed to (25) % :: motors [A v] run [clockwise v] for (180) [degrees v] :: motors write [ARM: UP ] at line (3) :: display
Walk it in the order the Brick runs it:
Notice the spaces inside the brackets. ARM: DOWN and ARM: UP are padded to the same length on purpose. Without them, UP written over DOWN would leave the last two letters of DOWN behind, and the line would read ARM: UPWN.
What success looks like: a two-line panel, a slow steady lift, and the bottom line changing at the moment the arm arrives — with the title still sitting untouched above it.
One change at a time, and predict before each run — specifically, predict what the whole screen will look like, not just the line you changed.
Step 5 is the one worth keeping. Clear display is a hammer. Once you are running a panel, you almost never want it in the middle of a program — you want to overwrite the one line that changed and leave everything else alone.
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.
Build a three-line panel: the machine's name on line 1, the arm's state on line 3, and the speed you are running at on line 5. All three must be on screen at the same time, and only the state line may change while the arm moves.
Make the arm go up and come back down, with the panel correct at every stage — including while it is moving. RISING and LOWERING must appear during the movement, not only after it. You will need to think about where the write block sits relative to the motor block.
Defeat the leftover-characters trap deliberately, then fix it. First write RISING over DOWN with no padding and photograph what the screen actually says. Then make the panel correct for four different state words of different lengths, and explain in one sentence which fix you used and why.
Design the panel a fire crew would be given. Your fire escape must run a full cycle — raise, hold, lower — and the screen must be a control panel throughout: a fixed layout, in fixed places, that an operator could read at a glance without hunting for anything. At least three pieces of information, all live at once, none of them ever stale. Plan on paper before you build, and plan the layout first. Draw the eight lines, decide what lives on each, and only then work out which block writes what. A panel designed while you are typing is a panel that moves around. Two questions when you demonstrate it. Which line would an operator look at first in an emergency, and why is it in that position? And is there any moment in your cycle where the screen says something that is no longer true?
