}
task heartbeatWatcher () {
while (true) {
if (missedBeats > 1) {
PlaySound (SOUND_DOWN);
stop messageWatcher;
Off(OUT_C);
until (armLock == 0);
Off(OUT_A);
until (Message () == HEARTBEAT_MESSAGE);
PlaySound(SOUND_UP);
missedBeats = 0;
start messageWatcher;
}
missedBeats = missedBeats + 1;
Wait(HEARTBEAT_TIME);
}
}
Don't Break That Arm
The grab and release tasks, as I said, have the ability to interrupt each other. They use a variable, armLock, to avoid potentially dangerous situations. For example, suppose that release is
running. It drives the arm motor in reverse until the arm is up and the limit touch sensor is pressed. Then the motor is run forward to release the touch sensor. Before the touch sensor is released,
however, suppose grab starts up. It stops release and runs the motor forward until the touch sensor is pressed. It's already pressed, so grab starts running the motor in reverse, waiting for the
touch sensor to be released. Since the arm is already at the top of its travel, running the arm motor in reverse creates pressure on the gears and will either break the arm apart or cause the gears to
skip.
Using the armLock variable enables grab and release to complete the press-release cycle of the arm limit switch without being interrupted. Both grab and release wait for armLock to
be 0 before interrupting the other task, like this:
until (armLock == 0);
The grab and release tasks set armLock to 1 before doing the sensitive press-release cycle. This means Minerva should never break her own arm.
Stayin' Alive
The heartbeatWatcher task also deserves some mention. It adds one to the missedBeats variable just as often as it expects the remote to send a heartbeat. Remember that just as
heartbeatWatcher is adding to missedBeats, the messageWatcher task is subtracting from missedBeats every time it hears the heartbeat message. If missedBeats is ever
greater than one, heartbeatWatcher shuts Minerva down. This shutdown is not as straightforward as you might think, however. First, a sound is played (the descending arpeggio). This lets
the human operator know that contact with the remote has been lost. Then heartbeatWatcher shuts down the messageWatcher task and turns off Minerva's drive motor:
PlaySound(SOUND_DOWN);
stop messageWatcher;
Off(OUT_C);
heartbeatWatcher also wants to shut down Minerva's arm motor, but it respects the armLock variable so the arm is not left in an uncertain state:
until (armLock == 0);
Off(OUT_A);
Now heartbeatWatcher waits to regain the heartbeat signal from the remote. If it is regained, heartbeatWatcher plays another sound (the ascending arpeggio), resets missedBeats,
and starts up messageWatcher again:
Page 157
Need help?
Do you have a question about the MINDSTORMS Robots and is the answer not in the manual?
Questions and answers