Challenge 1
Make the robot report properly. It must write READY before it starts, count each press-up on screen as it happens, and write DONE at the end. If it stalls part-way, the last number on screen must tell you which rep it died on.
EV3 Robotics›Level 1 · Beginner›Lesson 32
Level 1 · Lesson 32 · EV3-L01-3260 minutes · Ages 9–16 · Model: Push-up Robot
The Push-up Robot: the Brick lying flat as a body, with a Large Motor on each side working an arm. It presses itself up off the table and lowers itself back down, over and over.
Every model so far has moved something else — a fan blade, a barrier, a wheel. This one lifts itself, and a Brick is the heaviest thing in the kit.
Which means this is the model that will genuinely run out of strength. And when an EV3 motor runs out of strength, it does something you have not seen yet: it does not stop, and it does not carry on. The program simply stays where it is, for ever.
A press-up is the standard test of whether you can move your own body weight. No equipment, no weights — just you, the floor, and however many you have got left.

Two arms, working together, lifting a load that does not change. That is why press-ups are a good test: the weight is always exactly you, so the only thing that varies is how much strength you have left.
And there is a point — everybody has one — where the arms are pushing as hard as they can and the body does not rise. Not slowly. Not at all. You are working flat out and nothing is happening.
Now think about that moment from the outside. Somebody watching sees a person lying still, apparently doing nothing, straining.
A robot in that state looks even less dramatic. A stalled EV3 motor makes a faint buzz and holds still, and the Brick shows no error, no message, no light. It has not crashed. It is following your program exactly, waiting for a movement that is never going to finish.
The most confusing failure in robotics is not a crash. It is a machine doing precisely what it was told, for ever.
A measured motor block waits until the movement is finished. If the movement can never finish, the block never finishes either — and everything below it never runs.
You have relied on this behaviour since Lesson 5 without noticing it. A block like run [clockwise v] for (2) [rotations v] does not just start the motor — it holds the program there until two rotations have actually happened. That is what makes measured movement useful.
It is also the trap. The block is not counting seconds. It is counting degrees the shaft has actually turned. Jam the shaft and the count stops, and the block waits.
when program starts :: events hat [A v] set speed to (30) % :: motors [A v] run [clockwise v] for (90) [degrees v] :: motors [A v] reset degrees counted :: motors write [HOME SET] at line (1) :: display
Watch the Brick screen, not the arm. HOME SET is the block after the motor block, so a blank screen means the program never got past it.
Look at what the demo uses as proof: a block after the motor block, and a screen that stays blank. You cannot see “the block has not finished” — a stalled motor looks exactly like a stopped one. What you can see is that the next thing never happened.
| Block | What it does if the shaft jams |
|---|---|
[A v] run [clockwise v] for (1) [rotations v] :: motors | Hangs. Waits for a rotation that will not come. |
[A v] run [clockwise v] for (2) [seconds v] :: motors | Finishes. Two seconds pass whether the shaft moves or not. |
wait until <(timer) > (5)> | Finishes. The escape hatch from Lesson 20 — the clock runs regardless. |
So there are two honest fixes, and they are the same fix in different clothes: measure something that cannot get stuck. Time always passes. Rotations do not always happen.
To find out whether a program is stuck, put a block after the suspect one and watch for it. Silence is not information; a missing message is.
The Large Motor is the bigger of the two EV3 motors. It turns more slowly than the Medium Motor but pushes far harder, which is why it drives wheels and lifts loads. If a mechanism struggles or stalls with a Medium Motor, this is usually the answer.
| Block | What it does |
|---|---|
[B v] run [clockwise v] for (3) [rotations v] :: motors | Turns the motor a measured amount, then stops. |
[B v] run [clockwise v] for (2) [seconds v] :: motors | Turns it for a length of time rather than a distance, then stops — however far the shaft actually got. |
[B v] set speed to (40) % :: motors | Sets how fast the next movement will be. |
[B v] start motor [clockwise v] :: motors | Starts it turning and carries straight on. |
Give both motors the same program and the same arm. With nothing on the arm the Medium Motor wins easily — which is why it is tempting to treat it as simply the better motor. Then the demo hangs a weight on both arms and runs it again.
and on the Large Motor, only the port changes
Turning the speed up would not rescue the Medium Motor here — a stalled motor needs more force, which means gearing it down or using the Large Motor.
That is the whole difference. The Medium Motor is quicker; the Large Motor is stronger. A motor that cannot produce enough force does not move slowly — it stops altogether and strains, which is the buzzing, going-nowhere failure almost every LEGO builder meets sooner or later.
Being stronger buys the Large Motor a bigger load, not an infinite one. Every winch runs out of cable and every lift reaches the top of its rails, and when a motor arrives at a limit it stalls: the shaft stops turning and the motor sits there straining.
That is a problem for the program, not just the mechanism. run for (3) rotations does not finish when three rotations’ worth of time has gone by — it finishes when the shaft has actually turned three times. A winch that reaches the top after two and a half will never report three, so the block waits, and every block after it is unreachable. Nothing crashes. The motor keeps pushing and the rest of the program simply never happens.
The third setting in that dropdown is the way out. for () seconds drives the motor for a duration and then stops regardless, so it always finishes and the program always moves on. Drive into a limit slowly, for a comfortably long time, and then call that position zero:
when program starts :: events hat [B v] set speed to (30) % :: motors [B v] run [counterclockwise v] for (3) [seconds v] :: motors [B v] reset degrees counted :: motors
The lift ends up against its own stop, the encoder is zeroed there, and every measured move afterwards starts from a place you know. The rule is the same for both motors: if the movement ends against something solid, run for seconds; if it ends somewhere in the middle, measure it. The Medium Motor module has the animation for it — see The Medium Motor, which is where this bites hardest, because a Medium Motor is usually the one doing the lifting.
The blocks are identical apart from the port letter, so swapping one motor for the other is a build change, not a programming change.
Real machines match the motor to the load. A lift uses a powerful, slow motor; the button panel beside it uses tiny ones. Choosing the wrong size is the most common reason a LEGO mechanism whines but does not move.
There are two ways to tell an EV3 motor how much to move: give it a length of time, or give it an amount of turn. Only the second one is repeatable, and that difference decides whether a machine works reliably or only sometimes.
| Block | What it does |
|---|---|
[A v] run [clockwise v] for (1) [rotations v] :: motors | One full turn of the motor shaft, then stop. The program waits for it. |
[A v] run [clockwise v] for (180) [degrees v] :: motors | Half a turn. 360 degrees is one rotation. |
The counters below tick up in step with the shaft, so you can watch a rotation being counted rather than take it on trust.
the same movement, written in degrees
The two motor read-outs are the same measurement — 1 rotation is 360°. Use whichever makes the number easier to read.
Notice that the two motor counters finish together: 2.00 rotations and 720° are the same instant, because they are the same measurement in different units. So pick whichever makes the number easier to read. A winch that needs eight full turns is clearest in rotations. A gate that lifts a quarter turn is clearest in degrees — 90 rather than 0.25.
The third counter is the one that catches people out. The block counts turns of the motor, not of the thing it drives — and the gear in the demo is three times the size, so two motor rotations move it only 0.67 of a turn. Ask for two rotations and the mechanism does not move two rotations’ worth unless the gearing is one to one.
That is why a number that works on one build has to be retuned when the gearing changes — the program is right, the mechanism is different.
A printer feeds paper an exact distance; a lift stops level with the floor; a robot arm returns to the same place a thousand times. None of that is possible by timing a motor — they all count turns.
Say this back before moving on: “A run-for-rotations block waits for the shaft. If the shaft stops, the program stops with it.”
| Part | What it is doing here |
|---|---|
| EV3 Intelligent Brick | Runs the program — and is the load. Everything the arms lift is this. |
| Large Motor ×2 | The two arms, ports B and C. The strong motor, and this model needs every bit of it. |
The hardest point is at the bottom. Just like a real press-up: the moment of pushing off from the lowest position is where it either goes or does not.
Sensors go in ports 1, 2, 3, 4. Motors go in ports A, B, C, D. They are not interchangeable, and nothing will tell you politely if you swap them.
| Part | Port | Why this one |
|---|---|---|
| Left arm motor | B | B and C are the pair, as on the Frog in Lesson 26. Two motors doing the same job at the same time is exactly what the pair is for. |
| Right arm motor | C | Right is C. Sit behind the robot to decide which is which. |
| Sensors | none | Worth noticing: the robot cannot feel that it is stuck. That is the whole problem. |
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.
Stay connected today, whichever you choose. You are deliberately going to make this program hang, and the stop button on the computer is how you get out of it. A stalled motor left pushing gets hot.
Seven blocks. Five press-ups, and then a word on the screen — and that last block is the most important one in the program.
when program starts :: events hat set movement motors to [B v] and [C v] :: movement set movement speed to (50) % :: movement repeat (5) move [forward v] for (120) [degrees v] :: movement move [backward v] for (120) [degrees v] :: movement end write [DONE] at line (1) :: display
Walk it in the order the Brick runs it:
What success looks like: five clean press-ups, the body clearly rising off the table each time, and DONE appearing on the screen at the end. All three parts matter — especially the third.
If DONE never appears, the robot is stalled. Stop the program from the computer, then check: is the surface hard, are both arms flat, are both motors Large, is 120 degrees more than the arms can actually sweep?
Today you are going to cause a stall on purpose, so you can recognise one for the rest of the course. Keep the stop button within reach, and never leave a stalled motor pushing for more than a couple of seconds.
Step 4 is the trade this whole lesson is about. Measured movement is exact and can hang. Timed movement always finishes and is not exact. Neither one is the right answer everywhere.
Rotations promise a distance and can wait for ever. Seconds promise an ending and cannot promise a distance. Pick the promise your machine actually needs.

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.
Make the robot report properly. It must write READY before it starts, count each press-up on screen as it happens, and write DONE at the end. If it stalls part-way, the last number on screen must tell you which rep it died on.
Find the depth at which it stalls. Increase the degrees of the push, a little at a time, until the robot can no longer lift itself, and record the largest value that still completes five reps. Then explain why deeper is harder, in terms of where the arms are pushing.
Build a version that cannot hang. Using seconds instead of rotations, make a press-up routine that always reaches its final block even if you hold the robot down throughout. Then say plainly what you gave up to get that guarantee.
Make a machine that knows when it has failed. Your Push-up Robot must attempt a set of press-ups and then report honestly what happened: how many it completed, and whether it finished or was stopped. Somebody who did not watch the run must be able to tell from the Brick alone whether it succeeded. Plan on paper before you build, and plan for the failure first. A stalled measured block never returns, so anything that must run afterwards has to be reached another way. Work out how before you write a block. Two questions when you demonstrate it. Hold the robot down mid-run and show us what your machine says about it. And is there any way your robot could report success while lying flat and stalled?