A patrol robot sends an alert to a base station when its way is blocked, once, using a variable to remember it has already told.
Inspection robots patrol pipelines, warehouses and bush tracks on their own. They only call a person when they find something: a leak, a spill, a fallen tree.
So far a person told the robot what to do. Now the robot does its job on its own and reports back. It follows the line (lesson 5); when something blocks it, it stops and sends "blocked" by radio to a base station.
Both micro:bits run the same program, so each one has a role. Every micro:bit starts as a robot. Pressing A+B makes it the base: it stops driving and listens for alerts.
A true/false variable, alerted, remembers whether the robot has already told the base. if not alerted asks the opposite question: not (in Logic) turns true into false and false into true, so it runs only while alerted is still false.
Make your prediction first. Help opens once you've locked it in.

function followLine () {
if (robot.detectLine(RobotLineDetector.Left) && robot.detectLine(RobotLineDetector.Right)) {
robot.motorTank(40, 40)
} else if (robot.detectLine(RobotLineDetector.Left)) {
robot.motorTank(10, 40)
} else if (robot.detectLine(RobotLineDetector.Right)) {
robot.motorTank(40, 10)
} else {
robot.motorStop()
}
}
input.onButtonPressed(Button.AB, function () {
role = "base"
robot.motorStop()
basic.showString("B")
})
radio.onReceivedString(function (receivedString) {
if (role == "base") {
basic.showIcon(IconNames.No)
music.play(music.tonePlayable(880, music.beat(BeatFraction.Whole)), music.PlaybackMode.InBackground)
}
})
let alerted = false
let role = ""
robot.elecfreaksCuteBot.start()
radio.setGroup(1)
role = "robot"
basic.forever(function () {
if (role == "robot") {
if (robot.obstacleDistance() < 15) {
robot.motorStop()
if (!(alerted)) {
radio.sendString("blocked")
alerted = true
}
} else {
alerted = false
followLine()
}
}
})
Press A+B on the second micro:bit: it shows B and its robot stops. Drag a box onto the line in front of the first robot. Then drag the box away and let it patrol on.

function followLine () {
if (robot.detectLine(RobotLineDetector.Left) && robot.detectLine(RobotLineDetector.Right)) {
robot.motorTank(40, 40)
} else if (robot.detectLine(RobotLineDetector.Left)) {
robot.motorTank(10, 40)
} else if (robot.detectLine(RobotLineDetector.Right)) {
robot.motorTank(40, 10)
} else {
robot.motorStop()
}
}
input.onButtonPressed(Button.AB, function () {
role = "base"
robot.motorStop()
basic.showString("B")
})
radio.onReceivedString(function (receivedString) {
if (role == "base") {
basic.showIcon(IconNames.No)
music.play(music.tonePlayable(880, music.beat(BeatFraction.Whole)), music.PlaybackMode.InBackground)
}
})
let alerted = false
let role = ""
robot.elecfreaksCuteBot.start()
radio.setGroup(1)
role = "robot"
basic.forever(function () {
if (role == "robot") {
if (robot.obstacleDistance() < 15) {
robot.motorStop()
if (!(alerted)) {
radio.sendString("blocked")
alerted = true
}
} else {
alerted = false
followLine()
}
}
})

function followLine () {
if (robot.detectLine(RobotLineDetector.Left) && robot.detectLine(RobotLineDetector.Right)) {
robot.motorTank(40, 40)
} else if (robot.detectLine(RobotLineDetector.Left)) {
robot.motorTank(10, 40)
} else if (robot.detectLine(RobotLineDetector.Right)) {
robot.motorTank(40, 10)
} else {
robot.motorStop()
}
}
input.onButtonPressed(Button.AB, function () {
role = "base"
robot.motorStop()
basic.showString("B")
})
radio.onReceivedString(function (receivedString) {
if (role == "base") {
basic.showIcon(IconNames.No)
music.play(music.tonePlayable(880, music.beat(BeatFraction.Whole)), music.PlaybackMode.InBackground)
}
})
let alerted = false
let role = ""
robot.elecfreaksCuteBot.start()
radio.setGroup(1)
role = "robot"
basic.forever(function () {
if (role == "robot") {
if (robot.obstacleDistance() < 15) {
robot.motorStop()
if (!(alerted)) {
radio.sendString("blocked")
alerted = true
}
} else {
alerted = false
followLine()
}
}
})
Look at where alerted is set to true, and where it goes back to false.
Noah's robot (the rest of his program is the same):

basic.forever(function () {
if (role == "robot") {
if (robot.obstacleDistance() < 15) {
robot.motorStop()
radio.sendString("blocked")
} else {
followLine()
}
}
})
A person at the base wants to know when the problem is fixed. When the way is clear again, the robot sends "clear" (once), and the base shows a tick.
In the robot's else, before alerted is set to false: if alerted, send 'clear'.
On the base: if receivedString = 'clear', show a tick (icon Yes); else show the X and beep.
Make the base count the alerts and show how many there have been, like a log of a shift's problems.
Make a variable alerts. On the base, when the message is not 'clear': change alerts by 1.
Then show number alerts instead of the X.
When the way is clear again, the robot sends 'clear' once, and the base shows a tick.
This ticks by itself when your blocks do what is asked.
The base counts the alerts and shows how many there have been.
This ticks by itself when your blocks do what is asked.
Make a snake spotter for a bush track. The robot patrols the line; when something is in the way it:
The base shows the snake picture and sounds an alarm.
In the robot's forever: if the distance is less than 15, stop, red lights, send 'snake', pause 2000, then turn round (motor tank 50 −50 for 1200 ms). Else follow the line.
On the base: if the message is 'snake', show icon snake and play an alarm. Once it has turned round, the box is behind it, so it sends once.
A snake spotter: the robot patrols, and when something is in the way it stops, alerts 'snake', waits, then turns back; the base shows a snake and sounds an alarm.
This ticks by itself when your blocks do what is asked.
With real micro:bits, one stays with a person as the base (press A+B on it) and the other goes in the robot. Things to notice:
Students make a patrol robot that follows the line and sends a radio alert to a base station when it is blocked, using a true/false variable so it alerts once, then build a snake spotter. About 50 minutes.
Open the teacher guide: answers, solutions, slides and a worksheet.
This is the assistance strand: lesson 5's line following plus lesson 7's radio, in the other direction. The robot works on its own and reports back. Two new ideas:
Messages are words (send string, on radio received receivedString). On real hardware the base can be a bare micro:bit (untested whether the robot start block errors without a robot; if so, give the base a copy without it).
An alert in forever is sent every time round unless a flag remembers it. Ask what stops the robot sending again.
Stretch: Two-way: the base sends 'go' with A, and a robot that has stopped waits for 'go' before it carries on (a mode variable from lesson 6).
Support: Give the base side complete; students add the robot's alert with the alerted variable.
Next: the challenge unit. Showcase (performance) and Patrol and alert (assistance) put the course together. Real-world links: pipeline and warehouse inspection robots, wildlife cameras that send an alert, smoke alarms that report to a phone.