← Teacher guide

Tripwire

An optional challenge for students who finish early. Two robots work as a team; one stands still as a tripwire and, armed with a true/false variable, cues the patrolling robot once per pass; the patrol robot does a trick through its mode, then carries on.

Robotics challenges · Final challenge: Showcase and Patrol · about 50 minutes · Open the student lesson

Classroom resources

Load these into Waypoints Prepare: choose Load URL and paste the copied address, or download the file and import it. In Prepare, the worksheet's Teacher edition shows the answers; the student copy hides them.

Students will be able to

Timing

Predict, Run, Investigate 12 min · Milestone 1 12 min · Milestone 2 13 min · Milestone 3 13 min

Before class

Optional: the high ceiling of the course, not needed for Challenge complete. It is based on a common sensor pattern: one device notices, another acts. The tripwire is a robot that has been switched (A+B) to watch instead of drive; its distance sensor sees the other robot (the simulator treats robots as obstacles). Students drag the tripwire robot beside the line, facing it.

Two ideas from earlier come back: fire once (armed, like alerted in lesson 9) and handlers set the mode, forever does the job (lessons 6 and 11). The trick is a wiggle so the robot finishes facing along the line and can find it again; a full spin may leave it off the line.

Real ultrasonic sensors give false readings near zero, so a real tripwire often checks a range (for example 5 to 20 cm).

Running the lesson

  1. Predict and Run: placing the tripwire is fiddly. Show it once on the projector.
  2. Investigate: Ivy's tripwire is lesson 9's repeat-alert slip; the second question is the mode rule from Patrol and alert.
  3. Milestone 1: arm with A, fire once, disarm.
  4. Milestone 2: the trick lives in forever, chosen by mode.
  5. Milestone 3: re-arming after a pause makes it work lap after lap.

The hard part (on purpose)

Firing once per pass with arm and disarm, and the trick in forever. Ask when the tripwire is armed and where the trick's moves are.

When students get stuck

What you will seeA question to askThe fix
The tripwire never fires.Is it armed? Is it facing the line, close enough?Press A on the tripwire; drag it nearer and point it at the line.
The trick is cut short or never shows.Where are the trick's moves: in the handler or in forever?Handler: set mode to trick. forever: if mode = trick, do it, then set mode to patrol.
After the trick the robot stops for good.Which way is it facing after the trick?Make the trick end facing the same way (a wiggle), or drag it back onto the line.

Answers to the checks

  1. Predict: The second robot is the tripwire, beside the line and facing it. What does the tripwire's micro:bit show as the first robot passes?
    A surprised face while the patrol robot is closer than 20 cm, then the target again once it has passed. The tripwire checks again every time round.
  2. Ivy's tripwire: Ivy's tripwire sends 'trick' whenever something is closer than 20 cm. Her patrol robot starts its trick again and again as it passes. Why?
    The robot is in front of the tripwire for many times round forever, so 'trick' is sent many times
    forever runs many times while the robot is passing, so the cue is sent many times. Like alerted in lesson 9, an armed variable lets the tripwire fire once, then wait.
  3. Who moves the motors?: When the patrol robot hears 'trick', why should the handler only set mode to trick, instead of doing the moves itself?
    forever is calling followLine again and again, which would undo the trick's moves straight away
    Handlers and forever run side by side. forever keeps setting the motors for line following, so moves made in a handler are overwritten. Setting the mode lets forever do the trick itself, then go back to patrolling.

Solutions

One possible solution for each task. Other correct programs are fine.

Milestone 1: arm and fire

The program as blocks
Show as code
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 = "tripwire"
    robot.motorStop()
    basic.showIcon(IconNames.Target)
})
input.onButtonPressed(Button.A, function () {
    if (role == "tripwire") {
        armed = true
        basic.showIcon(IconNames.Yes)
    }
})
let armed = false
let role = ""
robot.elecfreaksCuteBot.start()
radio.setGroup(1)
role = "robot"
basic.forever(function () {
    if (role == "tripwire") {
        if (armed && robot.obstacleDistance() < 20) {
            armed = false
            radio.sendString("trick")
            basic.showIcon(IconNames.No)
        }
    } else {
        followLine()
    }
})

Milestone 2: the trick

The program as blocks
Show as code
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 = "tripwire"
    robot.motorStop()
    basic.showIcon(IconNames.Target)
})
input.onButtonPressed(Button.A, function () {
    if (role == "tripwire") {
        armed = true
        basic.showIcon(IconNames.Yes)
    }
})
radio.onReceivedString(function (receivedString) {
    if (role == "robot" && receivedString == "trick") {
        mode = "trick"
    }
})
let armed = false
let mode = ""
let role = ""
robot.elecfreaksCuteBot.start()
radio.setGroup(1)
role = "robot"
mode = "patrol"
basic.forever(function () {
    if (role == "tripwire") {
        if (armed && robot.obstacleDistance() < 20) {
            armed = false
            radio.sendString("trick")
            basic.showIcon(IconNames.No)
        }
    } else {
        if (mode == "trick") {
            robot.setColor(0xff00ff)
            robot.motorTank(50, -50, 300)
            robot.motorTank(-50, 50, 300)
            robot.motorTank(50, -50, 300)
            robot.motorTank(-50, 50, 300)
            robot.motorStop()
            robot.setColor(0x000000)
            mode = "patrol"
        } else {
            followLine()
        }
    }
})

Milestone 3: a self-resetting tripwire

The program as blocks
Show as code
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 = "tripwire"
    robot.motorStop()
    basic.showIcon(IconNames.Target)
})
input.onButtonPressed(Button.A, function () {
    if (role == "tripwire") {
        armed = true
        basic.showIcon(IconNames.Yes)
    }
})
radio.onReceivedString(function (receivedString) {
    if (role == "robot" && receivedString == "trick") {
        mode = "trick"
    }
})
let passes = 0
let armed = false
let mode = ""
let role = ""
robot.elecfreaksCuteBot.start()
radio.setGroup(1)
role = "robot"
mode = "patrol"
basic.forever(function () {
    if (role == "tripwire") {
        if (armed && robot.obstacleDistance() < 20) {
            armed = false
            radio.sendString("trick")
            passes += 1
            basic.showNumber(passes)
            basic.pause(5000)
            armed = true
            basic.showIcon(IconNames.Yes)
        }
    } else {
        if (mode == "trick") {
            robot.setColor(0xff00ff)
            music.play(music.tonePlayable(988, music.beat(BeatFraction.Half)), music.PlaybackMode.InBackground)
            robot.motorTank(50, -50, 300)
            robot.motorTank(-50, 50, 300)
            robot.motorTank(50, -50, 300)
            robot.motorTank(-50, 50, 300)
            robot.motorStop()
            robot.setColor(0x000000)
            mode = "patrol"
        } else {
            followLine()
        }
    }
})

Stretch and support

Stretch: Two tripwires at different places on the track, each sending a different word, and a different trick for each.

Support: Give Milestone 1 as a worked example to read; students build Milestones 2 and 3.

Exit ticket

Why does the tripwire need the armed variable?

The robot is in front of the sensor for many times round forever. Without armed the cue would be sent again and again; armed lets it fire once per pass.

What each step is for

Where it leads

Real-world links: conveyor-belt sensors, shop door chimes, lap timers at races, automatic doors.