Page 136 - Hacking Roomba
P. 136
Chapter 6 — Reading the Roomba Sensors 117
buffer, is the staging area for incoming data. There is no guarantee that you’ll receive all
26 bytes of sensor data at once, so what is received is buffered up. To keep track of progress, the
bufferLast variable is a count of how many bytes received so far.
The data received does not contain start- or end-markers; so you have to assume that every 26
bytes is a whole sensor packet. This presents some interesting synchronization problems if the
SENSORS command is used a lot and you need a guaranteed response time. Just trust that things
are okay. If you were building a robot for industrial use, this would be entirely unacceptable, but
for hacking it’s okay and rarely messes up.
In the serialEvent method itself, first make sure the event is the right type (DATA_AVAILABLE)
and then loop while data is available() and read data from the input into buffer. If it
gets 26 bytes, reset the counter and copy the finished data into sensor_bytes. Finally, report
that there’s data with sensorsValid and update the internal state of the RoombaComm
object with computeSensors(). The computeSensors() method encapsulates any process-
ing of a newly received sensor packet. Right now, computeSensors() does nothing. If you
wanted to add functionality to RoombaComm that acts on sensor data, the place to add it would
be computeSensors().
So as far as the code goes, it’s straightforward. What is difficult to deal with is the multi-
threaded nature of this setup. The serialEvent() method may be called at any time, like
when your code may be in the middle of driving the Roomba or updating a user interface.
You mitigate this problem with the buffer[] holding area and communicating through the
sensorsValid flag. When you want to update your sensors info, set sensorsValid=false,
send the SENSORS command to the Roomba, and then watch for sensorsValid to become
true again.
Making Serial Events Invisible
By decoupling the sending of the SENSORS command and when sensor_bytes gets updated,
you can have your code go about doing other things like dealing with a user interface. This
makes the code more responsive to the user. But, if you don’t mind sitting and waiting, you can
do what updateSensors() does in RoombaCommSerial, as in Listing 6-2:
Listing 6-2: RoombaCommSerial.updateSensors()
public boolean updateSensors() {
sensorsValid = false;
sensors();
for(int i=0; i < 20; i++) {
if( sensorsValid ) {
break;
}
pause(50);
}
return sensorsValid;
}