Introduction: A Heartbeat As a Health Check

We are Cougar Robotics and this is for the Instructables Sponsorship Program. 

Note: Let me begin by stating that this is currently (as of Aug 30, 2013) ruled illegal by the FTC game rules but we are working with the game design committee on a clarification to allow this feature. 

What we we have created is what we call a heartbeat on our robot. It is somewhat common in FTC for a robot to sit on the field, in a competition match, not moving. This makes it no fun for that team and the other teams competing. We have sat dead on the field too many times to not try and fix it, and this year, we did. The way our robot is wired, we have 4 controllers daisy-chained off of a single NXT sensor port. The last controller in that chain is our servo controller. In the period (at least called in robotC) "wait for start" we have that last controller in the chain twitch a servo back and forth, making sure that the robot is still running. 

Step 1: Hardware Required

At least 1 servo controller (hopefully wired as the last controller in the daisy chain of controllers). 
1 servo that can move without leaving the perimeter of the robot (entirely internal to the robot)
robotC
a robot :)

Step 2: Program

we have added the following code to both our autonomous and teleop programs. It simply verifies that the last controller (and then by default all of the ones before it) is receiving new commands from a non-frozen NXT brick and is able to move the servo accordingly, showing that I2C is functioning. 

The first bit "taskLookAlive" is just a task declaration. It can be put anywhere in your programs, as long as you have a task prototype if it is after "taskMain." I should clarify "RINGUNLOCKED" and "RINGLOCKED" are preprocessor macros that are just numbers for servo positions.

task taskLookAlive()
{
for(;;)
  {
  servo[servoRingLock] = RINGUNLOCKED + 10;
  wait1Msec(1000);
  servo[servoRingLock] = RINGUNLOCKED;
  wait1Msec(1000);
  }
}


This bit of program is what goes around the FTC command "waitForStart()" The last thing your robot will do before you know it is ready for the round will be to start this task, and moving the servo. The first thing that will happen after the round starts is that your servo will stop moving and then be able to be used as it regularly would. 

StartTask(taskLookAlive);
waitForStart();     /* wait for start of tele-op phase */
StopTask(taskLookAlive);

Step 3: Expand!

With the current rules outlawing this (and even if they didn't) this might not work for all teams. We have been brainstorming other ways of achieving this same effect, without breaking the new rules. If you have any thoughts, please comment!

Here are some of the things we have come up with
1. flash a lego light powered directly off of an NXT motor port (loses much of the value of checking if I2C is locked up)
2. flash a light powered off of the servo controller
3. use direct I2C commands to ping the various controllers in the chain and use that info to flash a light
4. have a servo hold a weight and if power is cut from that servo, the weight drops
5...