Long post – snacks are suggested…
Hardware development has been suspended for some time while some fundamental software improvements are made. In an earlier post, a plan was shown to use an XBee connected to a PC to control Poolbot in remote mode. This required some serious software changes, but hard work pays off. The following features have now been implemented in the Arduino Mega 2560 R3 software inside Poolbot:
- diagnostic checks of all sensors and electronics (except the motor shield), with timeouts, have been moved into the setup() function
- reporting of diagnostics over hardware serial (usually over USB to a PC in drydock)
- XBee communications with the base station include signal strength reporting and confirmation of successful receipt
- (biggest of all) motor speed and direction are now controlled remotely; no more pre-programmed paths
The great XBee libraries for Arduino from Andrew Rapp enables transmission and reception of simple text string “payloads” (100 bytes each), taking care of the details of checksums and packet assembly between Poolbot and a base station. Each payload can be used to carry commands, data requests, and the like. To do this, Poolbot needed its own custom control protocol, so that the base station could command the motors to do something, or request sensor status, or even change operating state. The format for the protocol was
blatantly ripped off from lovingly constructed in homage to NMEA codes used for the GPS. The format is comma-separated and looks like:
$M<2-character motor ID>,<motor speed percentage>,<direction>
So, to tell the right dive motor to spin backwards at 60% of maximum speed, the command would be:
Using comma separators permits using strtok to token-ize the command string. The compact format also allows Poolbot to communicate without violating the 100-byte XBee data payload limit. “P” is used in the second position to indicate propulsion motors, while “L” would indicate the left motor, and “F” indicates forward. “$MAS” instructs all motors to stop.
In future, sensor status can be reported with a “$Sxx” structure, but other non-motor commands are possible. The only limit to the language is the Mega’s storage. The entire program is about 23 kB in size, which is 2/3 of the maximum supported by an Uno, but still pretty small for a Mega.
On the PC side, lots of options exist for software (including a hardware cheat of connecting an XBee through an Arduino Uno to handle serial communications), but ultimately Python made the most sense. Using Python 3.3 was made possible by Chris Liechti’s excellent set of libraries for serial communication (pySerial) and a similarly excellent library collection for XBee communication by Paul Malmsten.
This means that the PC side hardware can be reduced to this:
This also means that a Linux box, or even a Raspberry Pi, could be used as the Poolbot base station (think battery-operated!) – multiple operating systems are now supported. The Python program is somewhat simple at present, featuring a simple set of pre-programmed commands, but it does respond to user input and reports XBee status and received signal strength.
How does it all look working together? Check out the results on a single 32-bit Microsoft Windows XP laptop, with Poolbot in drydock on COM5 (left side), and the Python input/output from the control XBee on COM4 (right side):
The commands are pretty obvious from the screen shot. Further, the frame ID tracking ensures that commands aren’t accidentally missed. The programs both wait for interaction, so Poolbot can be left on and waiting indefinitely – no more rushing to seal up the ‘bot before the motors click on. And, yes, the correct motors turned off and on when expected.
The hardest part of all of this was, believe it or not, getting strings vs. bytes sorted out correctly in both Python and Arduino’s flavor of C.
Future enhancements will include:
- adding sensor $S reporting to the Poolbot language
- fixing the XBee signal strength (yes, it’s really on the order of -80 dBm, even though the two XBees were only a few feet apart; this is likely due to bad soldering during recent repairs)
- a control GUI…
That last one is the real reason for using Python – the tkinter binding/toolkit allows cross-platform graphical displays and controls. This means that the command language can be abstracted away in favor of buttons, dials, text boxes, and pretty LED-like lights where appropriate. Here’s the first crude attempt:
At the very least, the speed adjustments shown will allow motor calibration without permanently adding encoders to each motor.
Three languages, multi-OS support, and a new GUI – not bad for five days’ work.