Roomba
Roomba.h
1 // Roomba.h
2 //
3 ///
4 /// \mainpage Roomba library for Arduino
5 ///
6 /// This is the Arduino Roomba library.
7 /// It provides an object-oriented interface for talking to iRobot Roomba and Create robots
8 /// via a serial port.
9 /// The Roomba is the original device from iRobot. It has a serial port DIN socket on the side.
10 /// The Create is a more full-featured robot platform for hobbyists. It has both the DIN socket and a DB25
11 /// connector called the CArgo Bay Connector
12 ///
13 /// The Create understands a superset of the Roomba commands. This library supports both devices. Where
14 /// comands are only available on one or the other platform it is noted.
15 ///
16 /// The version of the package that this documentation refers to can be downloaded
17 /// from http://www.airspayce.com/mikem/arduino/Roomba/Roomba-1.3.zip
18 /// You can find the latest version at http://www.airspayce.com/mikem/arduino/Roomba
19 ///
20 /// Tested on Arduino Duemilanove, Diecimila and Mega with arduino-0018 on OpenSuSE 11.1 and avr-libc-1.6.1-1.15,
21 /// cross-avr-binutils-2.19-9.1, cross-avr-gcc-4.1.3_20080612-26.5.
22 ///
23 /// A number of example programs are included that work with the iRobot Create:
24 /// \li TestSuite Runs on a Mega and exercises a number of the functions, checking for correct operation
25 /// \li RoombaTest1 Runs in any Arduino, checks that sensors can be read from Create using the stream() command
26 /// \li RoombaRCRx Demo program that shows how to control a Create using the RCRx Arduino library,
27 /// an Arduino WiFi shield such as BlackWidow and the RCTx
28 /// iPhone app. Control a Create from your iPhone!
29 ///
30 /// A video domonstating this library (along with the http://www.airspayce.com/mikem/arduino/RCKit library)
31 /// being used to control a Create from an iPhone or iPad can be found at http://www.youtube.com/watch?v=Qv-5ZOb5WW4
32 ///
33 /// \par Installation
34 /// Install in the usual way: unzip the distribution zip file to the libraries
35 /// sub-folder of your sketchbook.
36 ///
37 /// This software is Copyright (C) 2010 Mike McCauley. Use is subject to license
38 /// conditions. The main licensing options available are GPL V2 or Commercial:
39 ///
40 /// \par Open Source Licensing GPL V2
41 /// This is the appropriate option if you want to share the source code of your
42 /// application with everyone you distribute it to, and you also want to give them
43 /// the right to share who uses it. If you wish to use this software under Open
44 /// Source Licensing, you must contribute all your source code to the open source
45 /// community in accordance with the GPL Version 2 when your application is
46 /// distributed. See http://www.gnu.org/copyleft/gpl.html
47 ///
48 /// \par Commercial Licensing
49 /// This is the appropriate option if you are creating proprietary applications
50 /// and you are not prepared to distribute and share the source code of your
51 /// application. Contact info@airspayce.com for details.
52 ///
53 /// \par Revision History
54 /// \version 1.0 Initial release
55 /// \version 1.1 Updated docs, added Youtube video
56 /// \version 1.2 Compiles under Arduino 1.0
57 /// \version 1.3 Updated author and distribution location details to airspayce.com
58 ///
59 /// \author Mike McCauley (mikem@airspayce.com)
60 // Copyright (C) 2010 Mike McCauley
61 // $Id: Roomba.h,v 1.1 2010/09/27 21:58:32 mikem Exp mikem $
62 
63 #ifndef Roomba_h
64 #define Roomba_h
65 
66 #if (ARDUINO < 100)
67 #include "WProgram.h"
68 #else
69 #include <Arduino.h>
70 #endif
71 
72 /// Masks for LEDs in leds()
73 #define ROOMBA_MASK_LED_NONE 0
74 #define ROOMBA_MASK_LED_PLAY 0x2
75 #define ROOMBA_MASK_LED_ADVANCE 0x8
76 
77 /// Masks for digitalOut()
78 #define ROOMBA_MASK_DIGITAL_OUT_0 0x1
79 #define ROOMBA_MASK_DIGITAL_OUT_1 0x2
80 #define ROOMBA_MASK_DIGITAL_OUT_2 0x4
81 
82 /// Masks for drivers()
83 #define ROOMBA_MASK_DRIVER_0 0x1
84 #define ROOMBA_MASK_DRIVER_1 0x2
85 #define ROOMBA_MASK_DRIVER_2 0x4
86 /// Roomba only:
87 #define ROOMBA_MASK_SIDE_BRUSH 0x1
88 #define ROOMBA_MASK_VACUUM 0x2
89 #define ROOMBA_MASK_MAIN_BRUSH 0x4
90 
91 /// Masks for bumps and wheedrops sensor packet id 7
92 #define ROOMBA_MASK_BUMP_RIGHT 0x1
93 #define ROOMBA_MASK_BUMP_LEFT 0x2
94 #define ROOMBA_MASK_WHEELDROP_RIGHT 0x4
95 #define ROOMBA_MASK_WHEELDROP_LEFT 0x8
96 #define ROOMBA_MASK_WHEELDROP_CASTER 0x10
97 
98 /// Masks for driver overcurrents Packet ID 13
99 #define ROOMBA_MASK_LD1 0x1
100 #define ROOMBA_MASK_LD0 0x2
101 #define ROOMBA_MASK_LD2 0x4
102 #define ROOMBA_MASK_RIGHT_WHEEL 0x8
103 #define ROOMBA_MASK_LEFT_WHEEL 0x10
104 // Roomba, use ROOMBA_MASK_SIDE_BRUSH, ROOMBA_MASK_VACUUM, ROOMBA_MASK_MAIN_BRUSH
105 
106 /// Masks for buttons sensor packet ID 18
107 /// Create
108 #define ROOMBA_MASK_BUTTON_PLAY 0x1
109 #define ROOMBA_MASK_BUTTON_ADVANCE 0x4
110 /// Roomba
111 #define ROOMBA_MASK_BUTTON_MAX 0x1
112 #define ROOMBA_MASK_BUTTON_CLEAN 0x2
113 #define ROOMBA_MASK_BUTTON_SPOT 0x4
114 #define ROOMBA_MASK_BUTTON_POWER 0x8
115 
116 /// Masks for digital inputs sensor packet ID 32
117 #define ROOMBA_MASK_DIGITAL_IN_0 0x1
118 #define ROOMBA_MASK_DIGITAL_IN_1 0x2
119 #define ROOMBA_MASK_DIGITAL_IN_2 0x4
120 #define ROOMBA_MASK_DIGITAL_IN_3 0x8
121 #define ROOMBA_MASK_DIGITAL_IN_DEVICE_DETECT 0x10
122 
123 /// Masks for charging sources sensor packet ID 34
124 #define ROOMBA_MASK_INTERNAL_CHARGER 0x1
125 #define ROOMBA_MASK_HOME_BASE 0x2
126 
127 /// \def ROOMBA_READ_TIMEOUT
128 /// Read timeout in milliseconds.
129 /// If we have to wait more than this to read a char when we are expecting one, then something is wrong.
130 #define ROOMBA_READ_TIMEOUT 200
131 
132 // You may be able to set this so you can use Roomba with NewSoftSerial
133 // instead of HardwareSerial
134 //#define HardwareSerial NewSoftSerial
135 
136 /////////////////////////////////////////////////////////////////////
137 /// \class Roomba Roomba.h <Roomba.h>
138 /// \brief Support for iRobot Roomba and Create platforms via serial port using the iRobot Open Interface (OI)
139 /// protocol.
140 ///
141 /// The iRobot Roomba and Create platforms support a serial port through which you can control and
142 /// interrogate the device. The protocol implemented here conforms to the Open Interface protocol described in the
143 /// iRobot Open Interface Command Reference. Not all commands are supported on both platforms. Differences are
144 /// noted in the API
145 ///
146 /// The Roomba and Create is equipped with a min-din serial port socket, while the Create
147 /// is also equipped with a 25-pin D connector called the Cargo Bay Connector. The
148 /// pins on the Cargo Bay Connector include the serial port, battery, digital inputs and
149 /// outputs, and an analog input.
150 ///
151 /// In order to communicate with a Roomba, you must create an instance of the Roomba class and then call its
152 /// instance methods to send commmands and receive sensor messages. You can also request continuous
153 /// streams of sensor data to be sent by the Roomba. The Roomba also emits messages on its
154 /// serial port from time to time as described below.
155 ///
156 /// \par Electrical Considerations
157 ///
158 /// The serial port output TXD from the Roomba/Create is too weak to drive the RX serial port input
159 /// of an Arduino properly.
160 /// This is because of the USB-Serial converter on the Arduino: it also tries to drive the RX serial port input
161 /// via a pullup resistor,
162 /// but the Roomba does not have enough drive to pull the RX down below about 2.5 volts, which is insufficient
163 /// to be reliably detected as a TTL serial input of 0.
164 ///
165 /// \note Note that this problem does not affect the Serial1 Serial2 or Serial3 ports on the Mega: these ports do not
166 /// have other circuitry connected to them and the Roomba can drive the serial port inputs of these ports
167 /// without a problem. Its only the RX Serial port (ie the first Serial port) that is affected by this problem.
168 ///
169 /// What this means is that if you intend to connect a Roomba to the standard (first) RX/TX serial port on an Arduino
170 /// you \a MUST have additional circuitry to help drive RX on the Arduino low enough.
171 /// We use a simple PNP emitter follower. Almost any small signal low power PNP will do.
172 /// See the <a href="Create-Arduino.pdf">example circuit diagram</a>. This will ensure the RX serial
173 /// port input on the Arduino is pulled down to about 0.6V for reliable comms.
174 ///
175 /// \par Other Roomba messages
176 ///
177 /// When iRobot Create powers up and after a reset, it sends a message like this on its serial port:
178 /// \code
179 /// bl-start
180 /// 2006-09-12-1137-L
181 /// RDK by iRobot!
182 /// MC9S12E128
183 /// 2006-11-20-1731-L
184 /// battery-current-quiescent-raw 524 battery-current-zero 510
185 ///
186 /// 2006-11-20-1731-L
187 /// \endcode
188 ///
189 /// While charging it will send a message like this each second:
190 /// \code
191 /// bat: min 3 sec 21 mV 15558 mA 1491 deg-C 24
192 /// \endcode
193 ///
194 /// To enter the factory test menu for the IRobot Create, hold down the (>) and (>>|)
195 /// buttons then press and hold the Power button until the assending and descending tones play and then stop.
196 /// You wil see some messages emitted on teh serial port.
197 /// Press the right-right arrow button to cycle through the tests.
198 ///
199 class Roomba
200 {
201 public:
202  /// \enum Baud
203  /// Demo types to pass to Roomba::baud()
204  typedef enum
205  {
206  Baud300 = 0,
207  Baud600 = 1,
208  Baud1200 = 2,
209  Baud2400 = 3,
210  Baud4800 = 4,
211  Baud9600 = 5,
212  Baud14400 = 6,
213  Baud19200 = 7,
214  Baud28800 = 8,
215  Baud38400 = 9,
216  Baud57600 = 10,
217  Baud115200 = 11,
218  } Baud;
219 
220  /// \enum Demo
221  /// Demo types to pass to Roomba::demo()
222  typedef enum
223  {
224  DemoAbort = -1,
225  DemoCover = 0,
226  DemoCoverAndDock = 1,
227  DemoSpotCover = 2,
228  DemoMouse = 3,
229  DemoDriveFigureEight = 4,
230  DemoWimp = 5,
231  DemoHome = 6,
232  DemoTag = 7,
233  DemoPachelbel = 8,
234  DemoBanjo = 9,
235  } Demo;
236 
237  /// \enum Drive
238  /// Special values for radius in Roomba::drive()
239  typedef enum
240  {
241  DriveStraight = 0x8000,
242  DriveInPlaceClockwise = 0xFFFF,
243  DriveInPlaceCounterClockwise = 0x0001,
244  } Drive;
245 
246  /// \enum StreamCommand
247  /// Values to pass to Roomba::streamCommand()
248  typedef enum
249  {
250  StreamCommandPause = 0,
251  StreamCommandResume = 1,
252  } StreamCommand;
253 
254  /// \enum EventType
255  /// Values to pass to Roomba::waitEvent()
256  typedef enum
257  {
258  EventTypeWheelDrop = 1,
259  EventTypeFronWheelDrop = 2,
260  EventTypeLeftWheelDrop = 3,
261  EventTypeRightWheelDrop = 4,
262  EventTypeBump = 5,
263  EventTypeLeftBump = 6,
264  EventTypeRightBump = 7,
265  EventTypeVirtualWall = 8,
266  EventTypeWall = 9,
267  EventTypeCliff = 10,
268  EventTypeLeftCliff = 11,
269  EventTypeFrontLeftCliff = 12,
270  EventTypeFrontRightCliff = 13,
271  EventTypeRightCliff = 14,
272  EventTypeHomeBase = 15,
273  EventTypeAdvanceButton = 16,
274  EventTypePlayButton = 17,
275  EventTypeDigitalInput0 = 18,
276  EventTypeDigitalInput1 = 19,
277  EventTypeDigitalInput2 = 20,
278  EventTypeDigitalInput3 = 21,
279  EventTypeModePassive = 22,
280  } EventType;
281 
282  /// \enum IRCommand
283  /// Values for sensor packet ID 27
284  typedef enum
285  {
286  // Remote control:
287  IRCommandLeft = 129,
288  IRCommandForward = 130,
289  IRCommandRight = 131,
290  IRCommandSpot = 132,
291  IRCommandMax = 133,
292  IRCommandSmall = 134,
293  IRCommandMedium = 135,
294  IRCommandLargeClean = 136,
295  IRCommandPause = 137,
296  IRCommandPower = 138,
297  IRCommandArcForwardLeft = 139,
298  IRCommandArcForwardRight = 140,
299  IRCommandDriveStop = 141,
300  // Scheduling Remote:
301  IRCommandSendAll = 142,
302  IRCommandSeekDock = 143,
303  // Home Base:
304  IRCommandReserved1 = 240,
305  IRCommandRedBuoy = 248,
306  IRCommandGreenBuoy = 244,
307  IRCommandForceField = 242,
308  IRCommandRedGreenBuoy = 252,
309  IRCommandRedBuoyForceField = 250,
310  IRCommandGreenBuoyForceField = 246,
311  IRCommandRedGreenBuoyForceField = 254,
312  } IRCommand;
313 
314  /// \enum ChargeState
315  /// Values for sensor packet ID 21
316  typedef enum
317  {
318  ChargeStateNotCharging = 0,
319  ChargeStateReconditioningCharging = 1,
320  ChargeStateFullChanrging = 2,
321  ChargeStateTrickleCharging = 3,
322  ChargeStateWaiting = 4,
323  ChargeStateFault = 5,
324  } ChargeState;
325 
326  /// \enum Mode
327  /// Values for sensor packet ID 35
328  typedef enum
329  {
330  ModeOff = 0,
331  ModePassive = 1,
332  ModeSafe = 2,
333  ModeFull = 3,
334  } Mode;
335 
336  /// \enum Sensor
337  /// Values for sensor packet IDs to pass to getSensors() and getSensorsList()
338  typedef enum
339  {
340  Sensors7to26 = 0,
341  Sensors7to16 = 1,
342  Sensors17to20 = 2,
343  Sensors21to26 = 3,
344  Sensors27to34 = 4,
345  Sensors35to42 = 5,
346  Sensors7to42 = 6,
347  SensorBumpsAndWheelDrops = 7,
348  SensorWall = 8,
349  SensorCliffLeft = 9,
350  SensorCliffFrontLeft = 10,
351  SensorCliffFrontRight = 11,
352  SensorCliffRight = 12,
353  SensorVirtualWall = 13,
354  SensorOvercurrents = 14,
355 // SensorUnused1 = 15,
356 // SensorUnused2 = 16,
357  SensorIRByte = 17,
358  SensorButtons = 18,
359  SensorDistance = 19,
360  SensorAngle = 20,
361  SensorChargingState = 21,
362  SensorVoltage = 22,
363  SensorCurrent = 23,
364  SensorBatteryTemperature = 24,
365  SensorBatteryCharge = 25,
366  SensorBatteryCapacity = 26,
367  SensorWallSignal = 27,
368  SensoCliffLeftSignal = 28,
369  SensoCliffFrontLeftSignal = 29,
370  SensoCliffFrontRightSignal = 30,
371  SensoCliffRightSignal = 31,
372  SensorUserDigitalInputs = 32,
373  SensorUserAnalogInput = 33,
374  SensorChargingSourcesAvailable = 34,
375  SensorOIMode = 35,
376  SensorSongNumber = 36,
377  SensorSongPlaying = 37,
378  SensorNumberOfStreamPackets = 38,
379  SensorVelocity = 39,
380  SensorRadius = 40,
381  SensorRightVelocity = 41,
382  SensorLeftVelocity = 42,
383  } Sensor;
384 
385  /// Constructor. You can have multiple simultaneous Roomba if that makes sense.
386  /// \param[in] serial POinter to the HardwareSerial port to use to communicate with the Roomba.
387  /// Defaults to &Serial
388  /// \param[in] baud the baud rate to use on the serial port. Defaults to 57600, the default for the Roomba.
389  Roomba(HardwareSerial* serial = &Serial, Baud baud = Baud57600);
390 
391  /// Resets the Roomba.
392  /// It will emit its startup message
393  /// Caution, this may take several seconds to complete
394  void reset();
395 
396  /// Starts the Open Interface and sets the mode to Passive.
397  /// You must send this before sending any other commands.
398  /// Initialises the serial port to the baud rate given in the constructor
399  void start();
400 
401  /// Converts the specified baud code into a baud rate in bits per second
402  /// \param[in] baud Baud code, one of Roomba::Baud
403  /// \return baud rate in bits per second
404  uint32_t baudCodeToBaudRate(Baud baud);
405 
406  /// Changes the baud rate
407  /// Baud is on of the Roomba::Baud enums
408  void baud(Baud baud);
409 
410  /// Sets the OI to Safe mode.
411  /// In Safe mode, the cliff and wheel drop detectors work to prevent Roomba driving off a cliff
412  void safeMode();
413 
414  /// Sets the OI to Full mode.
415  /// In Full mode, the cliff and wheel drop detectors do not stop the motors: you are responsible
416  // for full control of the Roomba
417  void fullMode();
418 
419  /// Puts a Roomba in sleep mode.
420  /// Roomba only, no equivalent for Create.
421  void power();
422 
423  /// Causes roomba to immediately
424  /// seek the docking station.
425  /// No equivalent for Create.
426  void dock();
427 
428  /// Starts the requirested built-in demo
429  /// \param[in] demo The demo number. One of Roomba::Demo
430  void demo(Demo demo);
431 
432  /// Starts the Cover demo
433  /// Changes mode to Passive
434  void cover();
435 
436  /// Starts the Cover and Dock demo
437  /// Changes mode to Passive
438  void coverAndDock();
439 
440  /// Starts the Spot Cover demo
441  /// Changes mode to Passive
442  void spot();
443 
444  /// Starts the Roomba driving with a specified wheel velocity and radius of turn
445  /// \param[in] velocity Speed in mm/s (-500 to 500 mm/s)
446  /// \param[in] radius Radius of the turn in mm. (-2000 to 2000 mm).
447  /// Any of the special values in enum Roomba::Drive may be used instead of a radius value
448  void drive(int16_t velocity, int16_t radius);
449 
450  /// Starts the Roomba driving with a specified velocity for each wheel
451  /// Create only. No equivalent on Roomba.
452  /// \param[in] leftVelocity Left wheel velocity in mm/s (-500 to 500 mm/s)
453  /// \param[in] rightVelocity Right wheel velocity in mm/s (-500 to 500 mm/s)
454  void driveDirect(int16_t leftVelocity, int16_t rightVelocity);
455 
456  /// Controls the LEDs on the Create
457  /// \param[in] leds Bitmask specifying which LEDs to activate. ORed combination of ROOMBA_MASK_LED_*
458  /// \param[in] powerColour The colour of the Power LED. 0 to 255. 0 = green, 255 = red,
459  /// intermediate values are intermediate colours
460  /// \param[in] powerIntensity Power LED intensity. 0 to 255. 0 = off, 255 = full intensity
461  void leds(uint8_t leds, uint8_t powerColour, uint8_t powerIntensity);
462 
463  /// Sets the digital output pins on the Cargo Bay Connector of the Create
464  /// Create only. No equivalent on Roomba.
465  /// \param[in] out Mask specifiying which outputs to enable. ORed value ROOMBA_MASK_DIGITAL_OUT_*
466  void digitalOut(uint8_t out);
467 
468  /// Sets the duty cycle for PWM outputs on the low side drivers. These can be use for PWM driving of
469  /// motors, lights etc.
470  /// Create only. No equivalent on Roomba.
471  /// \param[in] dutyCycle0 Duty cycle for low side driver 0. 0 to 128.
472  /// \param[in] dutyCycle1 Duty cycle for low side driver 1. 0 to 128.
473  /// \param[in] dutyCycle2 Duty cycle for low side driver 2. 0 to 128.
474  void pwmDrivers(uint8_t dutyCycle0, uint8_t dutyCycle1, uint8_t dutyCycle2);
475 
476  /// Sets the low side drivers on or off. On the Romba, these control the 3 motors.
477  /// \param[in] out Bitmask of putputs to enable. ORed value ROOMBA_MASK_DRIVER_*
478  void drivers(uint8_t out);
479 
480  /// Sends the requested byte out of the low side driver 1 (pin 23 on the Cargo Bay Connector).
481  /// low side driver 1 can be used to drive an IR transmitter to send commands to other Roombas and Creates.
482  /// Create only. No equivalent on Roomba.
483  /// \param[in] data Data byte to transmit
484  void sendIR(uint8_t data);
485 
486  /// Defines a song which can later be played with playSong()
487  /// \param[in] songNumber Song number for this song. 0 to 15
488  /// \param[in] notes Array of note/duration pairs. See Open Interface manual for details. 2 bytes per note,
489  /// first byte is the note and the second is the duration
490  /// \param[in] len Length of notes array in bytes, so this will be twice the number of notes in the song
491  void song(uint8_t songNumber, const uint8_t* notes, int len);
492 
493  /// Plays a song that has previously been defined by song()
494  /// \param[in] songNumber The song number to play. 0 to 15
495  void playSong(uint8_t songNumber);
496 
497  /// Requests that a stream of sensor data packets be sent by the Roomba.
498  /// See the Open Interface manual for details on the resutting data.
499  /// The packets will be sent every 15ms.
500  /// You can use pollSensors() to receive sensor data streams.
501  /// Create only. No equivalent on Roomba.
502  /// See the Open Interface maual for more details and limitations.
503  /// \param[in] packetIDs Array specifying sensor packet IDs from Roomba::Sensor to be sent.
504  /// \param[in] len Number of IDs in packetIDs
505  void stream(const uint8_t* packetIDs, int len);
506 
507  /// Pause or resume a stream of sensor data packets previously requested by stream()
508  /// Create only. No equivalent on Roomba.
509  /// \param[in] command One of Roomba::StreamCommand
510  void streamCommand(StreamCommand command);
511 
512  /// Defines a command script which can later be executed with playScript(). You can clear the script by calling
513  /// script(NULL, 0);
514  /// Create only. No equivalent on Roomba.
515  /// \param[in] script Array containing a sequence of Roomba OI commands.
516  /// \param[in] len Length of the script in bytes.
517  void script(const uint8_t* script, uint8_t len);
518 
519  /// Executes a previously defined script,
520  /// the last one specified by script()
521  /// Create only. No equivalent on Roomba.
522  void playScript();
523 
524  /// Tells the Roomba to wait for a specified time.
525  /// This command is intended for use in scripting only.
526  /// Create only. No equivalent on Roomba.
527  /// \param[in] ticks The number of ticks to wait. Each tick is 15ms
528  void wait(uint8_t ticks);
529 
530  /// Causes Roomba to wait until it has travelled the distance specified.
531  /// Roomba will not react to any inputs until the wait has completed.
532  /// Note that this does not cause the host arduino to wait, it only sends the wait comman to the Roomba
533  /// This command is intended for use in scripting only.
534  /// Create only. No equivalent on Roomba.
535  /// \param[in] mm Distance to wait for in mm
536  void waitDistance(int16_t mm);
537 
538  /// Causes Roomba to wait until it has rotated through the specified angle.
539  /// Roomba will not react to any inputs until the wait has completed.
540  /// Note that this does not cause the host arduino to wait, it only sends the wait comman to the Roomba
541  /// This command is intended for use in scripting only.
542  /// Create only. No equivalent on Roomba.
543  /// \param[in] degrees Angle to wait for in degrees
544  void waitAngle(int16_t degrees);
545 
546  /// Cause the Create to wait for a specified event.
547  /// Roomba will not react to any inputs until the wait has completed.
548  /// Note that this does not cause the host arduino to wait, it only sends the wait comman to the Roomba
549  /// Create only. No equivalent on Roomba.
550  /// \param[in] type Event type to wait for. One of Roomba::EventType
551  void waitEvent(EventType type);
552 
553  /// Low level funciton to read len bytes of data from the Roomba
554  /// Blocks untill all len bytes are read or a read timeout occurs.
555  /// \param[out] dest Destination where the read data is stored. Must have at least len bytes available.
556  /// \param[in] len Number of bytes to read
557  /// \return true if all len bytes were successfully read. Returns false in the case of a timeout
558  /// on reading any byte.
559  bool getData(uint8_t* dest, uint8_t len);
560 
561  /// Reads the sensor data for the specified sensor packet ID. Note that different sensor packets have
562  /// different lengths, and it is the callers responsibilty to make sure len agrees with the expected
563  /// length of the sensor data. See the Open Interface manual for details on sensor packet lengths.
564  /// Roomba.h defines various enums and defines for decoding sensor data.
565  /// Blocks untill all len bytes are read or a read timeout occurs.
566  /// \param[in] packetID The ID of the sensor packet to read from Roomba::Sensor
567  /// \param[out] dest Destination where the read data is stored. Must have at least len bytes available.
568  /// \param[in] len Number of sensor data bytes to read
569  /// \return true if all len bytes were successfully read. Returns false in the case of a timeout
570  /// on reading any byte.
571  bool getSensors(uint8_t packetID, uint8_t* dest, uint8_t len);
572 
573  /// Reads the sensor data for the specified set of sensor packet IDs. Note that different sensor packets have
574  /// different lengths, and it is the callers responsibilty to make sure len agrees with the expected
575  /// length of the sensor data. See the Open Interface manual for details on sensor packet lengths.
576  /// Blocks until all len bytes are read or a read timeout occurs.
577  /// Create only. No equivalent on Roomba.
578  /// \param[in] packetIDs Array of IDs from Roomba::Sensor of the sensor packets to read
579  /// \param[in] numPacketIDs number of IDs in the packetIDs array
580  /// \param[out] dest Destination where the read data is stored. Must have at least len bytes available.
581  /// \param[in] len Number of sensor data bytes to read and store to dest.
582  /// \return true if all len bytes were successfully read. Returns false in the case of a timeout
583  /// on reading any byte.
584  bool getSensorsList(uint8_t* packetIDs, uint8_t numPacketIDs, uint8_t* dest, uint8_t len);
585 
586  /// Polls the serial input for data belonging to a sensor data stream previously requested with stream().
587  /// As sensor data is read it is appended to dest until at most len bytes are stored there.
588  /// When a complete sensor stream has been read with a correct checksum, returns true.
589  /// See the Open Interface manual for details on how the sensor data will be encoded in dest.
590  /// Discards characters that are not part of a stream, such as the messages the Roomba
591  /// sends at startup and while charging.
592  /// Create only. No equivalent on Roomba.
593  /// \param[out] dest Destination where the read data is stored. Must have at least len bytes available.
594  /// \param[in] len Max number of sensor data bytes to store to dest
595  /// \return true when a complete stream has been read, and the checksum is correct. The sensor data
596  /// (at most len bytes) will have been stored into dest, ready for the caller to decode.
597  bool pollSensors(uint8_t* dest, uint8_t len);
598 
599  /// Reads a the contents of the script most recently specified by a call to script().
600  /// Create only. No equivalent on Roomba.
601  /// \param[out] dest Destination where the read data is stored. Must have at least len bytes available.
602  /// \param[in] len The maximum number of bytes to place in dest. If the script is actually longer than len
603  /// only len bytes will be written
604  /// \return The actual number of bytes in the script, even if this is more than len. By calling
605  /// getScript(NULL, 0), you can determine how many bytes would be required to store the script.
606  uint8_t getScript(uint8_t* dest, uint8_t len);
607 
608 private:
609  /// \enum PollState
610  /// Values for _pollState
611  typedef enum
612  {
613  PollStateIdle = 0,
614  PollStateWaitCount = 1,
615  PollStateWaitBytes = 2,
616  PollStateWaitChecksum = 3,
617  } PollState;
618 
619  /// The baud rate to use for the serial port
620  uint32_t _baud;
621 
622  /// The serial port to use to talk to the Roomba
623  HardwareSerial* _serial;
624 
625  /// Variables for keeping track of polling of data streams
626  uint8_t _pollState; /// Current state of polling, one of Roomba::PollState
627  uint8_t _pollSize; /// Expected size of the data stream in bytes
628  uint8_t _pollCount; /// Num of bytes read so far
629  uint8_t _pollChecksum; /// Running checksum counter of data bytes + count
630 
631 };
632 
633 #endif