A mobile robot with powerful onboard computing, high capacity onboard batteries, and a wired emergency stop button is about as convenient as a car with three wheels. I decided to fix that. I needed a wireless E-Stop button. I've used Torc products in the past, and they're terrific, but their e-stops start at several thousand dollars. I figured I could make a product that works just as well for under $100. Transmitting a single bit quickly and reliably can't be that hard.
All the existing robots in my lab use the same E-Stop system, just a mechanical SPDT switch that plugs into an RJ45 port, so I wanted a remote control that fit that form factor, no modifications needed on the robots. I figured I could get a few arduinos, a few XBees, and do the job with those. I'd never used XBees before, but I figured it couldn't be that difficult. I ended up selecting the Sparkfun Fio v3 boards and regular XBee 2s (not Pro). The Fios have built in XBee receptacles and Li-Ion management, and Sparkfun's boards don't require FTDI cables. I considered using the cheaper, smaller Sparkfun ProMicro for the local board, since that will be powered from a USB cable, but I didn't want to bother with level shifting for the XBee. As for the XBees themselves, I didn't need the extended range of the XBee Pros and I wanted to maximize battery life, so I used the regulars.
For software, I started out by throwing together the simplest, quickest one-way transmission I could. I wrote some code where the arduino loops every 20ms, sending a single character message indicating switch position every loop. This worked great, but I wanted an indication of the switch position on the robot, a receipt/response/verification of some sort. For this, instead of blindly screaming into the aether, I needed to know when my messages were actually being received. Otherwise the XBee's buffers fill up pretty quickly and the system comes screeching to a halt. The Fio v3 has an LED for RSSI (Received Signal Strength Indication), but it's a fed from a PWM so it's not something the arduino can easily read. The CTS pin (Clear To Send) tells you when your buffer is full, but doesn't indicate signal/connection status/strength. After trying a few ideas combining these two pins, I decided to just use the transmitted messages themselves as indication of connection strength. I ended up with some simple code that sends single-character messages in a loop between the remote and the local relay via the XBee's serial ports. Instead of indicating remote button status, the red/green LED on the remote now indicates relay status (okay, not quite, but the control signal being sent to the relay). The time delay between changing the button position and getting feedback from the LED is too quick for me to measure visually, well under a tenth of a second. Great.