Build a sign-driven delivery robot in three milestones. Its own distance sensor overrules the model, it reports back through the bridge, and it counts its deliveries.
Delivery robots on footpaths and in hospitals follow instructions, but their own sensors always get the last word: if something is in the way, they stop, whatever they were told.
The challenge puts the course together. You start from your careful sign robot (Signs: some mistakes cost more): Go after two Gos, Left and Right turn, everything else stops, with a watchdog. Then, in three milestones with less help each time:
In the simulator, the buttons stand in for the model (A Left, B Right, A+B Go, logo Stop). Drag a box in front of a robot to block it.
Make your prediction first. Help opens once you've locked it in.

radio.onReceivedString(function (receivedString) {
if (receivedString == "Go") {
goCount += 1
} else {
goCount = 0
}
mode = receivedString
lastHeard = input.runningTime()
})
basic.forever(function () {
if (input.runningTime() - lastHeard > 2000) {
mode = "Stop"
}
if (mode == "Go" && goCount >= 2) {
robot.motorTank(40, 40)
robot.setColor(0x00ff00)
} else if (mode == "Left") {
robot.motorTank(-30, 30)
robot.setColor(0xffff00)
} else if (mode == "Right") {
robot.motorTank(30, -30)
robot.setColor(0xffff00)
} else {
robot.motorStop()
robot.setColor(0xff0000)
}
})
input.onButtonPressed(Button.A, function () {
radio.sendString("Left")
})
input.onButtonPressed(Button.B, function () {
radio.sendString("Right")
})
input.onButtonPressed(Button.AB, function () {
radio.sendString("Go")
})
input.onLogoEvent(TouchButtonEvent.Pressed, function () {
radio.sendString("Stop")
})
let goCount = 0
let lastHeard = 0
let mode = ""
robot.elecfreaksCuteBot.start()
radio.setGroup(7)
Press A+B twice on one micro:bit, then drag a box in front of the other robot.

radio.onReceivedString(function (receivedString) {
if (receivedString == "Go") {
goCount += 1
} else {
goCount = 0
}
mode = receivedString
lastHeard = input.runningTime()
})
basic.forever(function () {
if (input.runningTime() - lastHeard > 2000) {
mode = "Stop"
}
if (mode == "Go" && goCount >= 2) {
robot.motorTank(40, 40)
robot.setColor(0x00ff00)
} else if (mode == "Left") {
robot.motorTank(-30, 30)
robot.setColor(0xffff00)
} else if (mode == "Right") {
robot.motorTank(30, -30)
robot.setColor(0xffff00)
} else {
robot.motorStop()
robot.setColor(0xff0000)
}
})
input.onButtonPressed(Button.A, function () {
radio.sendString("Left")
})
input.onButtonPressed(Button.B, function () {
radio.sendString("Right")
})
input.onButtonPressed(Button.AB, function () {
radio.sendString("Go")
})
input.onLogoEvent(TouchButtonEvent.Pressed, function () {
radio.sendString("Stop")
})
let goCount = 0
let lastHeard = 0
let mode = ""
robot.elecfreaksCuteBot.start()
radio.setGroup(7)
Which part should decide each of these?
Robot obstacle distance is in Robot › Sensors.
In forever, before the Go branch: if obstacle distance < 15, then stop and set red; turn the old if into else if.
If something is closer than 15 cm, the robot stops and shows red, whatever the model says.
This ticks by itself when your blocks do what is asked.
The bridge passes these on to the board, where they appear as values (in_dist, in_blocked).
A second forever: radio send value dist, obstacle distance, then pause 500.
A variable blocked (false at the start). When it stops for a box and blocked is false: radio send value blocked 1 and set blocked to true. When the way is clear again: send blocked 0 and set it to false.
The robot sends its distance twice a second, and sends blocked 1 once when it stops for something and blocked 0 once when the way is clear.
This ticks by itself when your blocks do what is asked.
Download milestone 2 to the robot, and the bridge program to the micro:bit on the computer. Drive with your signs and watch the robot's distance arrive. Block it with your hand.
Drive with your signs while the robot reports back: get Go sent, and at least 10 replies from the robot.
Use the board. This ticks when you get there.
Count deliveries: a Stop sign that arrives while the robot is going. Send the count back and show it when the robot is shaken. Then make it yours: a library book trolley, a lunch-order runner, a parcel robot. Change the signs, lights and sounds to suit.
A delivery is a Stop sign that arrives while the robot was going (mode = Go).
Send the count with send value. Pick a short name, such as done: names are 8 characters at most, so deliveries would be cut short.
The robot counts deliveries (a Stop that arrives while going), sends the count back, and shows it when shaken.
This ticks by itself when your blocks do what is asked.
Students build a sign-driven delivery robot in three milestones; its distance sensor overrules the model, it reports back through the bridge, and it counts deliveries. About 60 minutes.
Open the teacher guide: answers, solutions, slides and a worksheet.
The challenge: everything from AI robots plus Robotics challenges. The robot starts as the careful sign robot (Go twice, Unsure and silence stop it). The milestones add no new blocks:
if obstacle distance < 15 → stop goes first in forever. The model only knows what the camera sees on the sign; the sensor knows what is in front of the robot. Jo's robot (the check last) is the mistake to watch for.dist twice a second; blocked 1 and blocked 0 go once each, using a variable (the same "send once" idea as Patrol and alert). The bridge turns them into lines such as dist:23, which the board shows as values.Without robots: every milestone works in the simulator (buttons stand in for the model; drag a box to block). The full-system step is typical.
Putting the sensor check first so it overrules the model. When the robot pushes boxes, ask which question in the chain is asked first.
Stretch: Make the robot slow down (motor tank 20) between 15 and 30 cm, and stop under 15.
Support: Give milestone 1's if complete; students write the reports in milestone 2.
Where this leads: real robots fuse a camera model with many sensors (distance, bump, line), and safety checks always win. The Python pathway's Machine learning with Gradio trains models in code.