Controlling Roomba 550 series w/ Arduino

r551

I had my Roomba 551 for a long time (over 5 years). This model was only sold in Costco, but it’s basically a 550 model, slightly repackaged.  It was a somewhat lousy vacuum cleaner, as it would require preparing room for it by blocking access to shaggy carpet where it would get stuck and removing all cat toys on which it would usually choke. So it’s been collecting dust for a a while (passively). At some point few years ago before I learned about Arduino I’ve got a “Hacking Roomba” book and tried to … well hack my roomba. I wanted to turn it into a mobile camera. I bought a RooStick which was DIN8 to USB interface (no longer sold) which allowed to connect roomba to computer. I even built my own roomba interface cable from old keyboard cable. However it got me nowhere at the time.

Recently having some success with Arduino, I wanted to build a moving camera platform to watch over my cats while I’m on vacation. Plan was to use Roomba as mobile platform and power supply. Since it can supply over 16 volts, I should be able to power WiFi IP cam, Arduino and small wireless router.  Router would be used to control Arduino via internet. Because I already had ethernet shield and didn’t want to spend lots of money for WiFi shield I found this really cheap and small router TL-WR703n. With custom OpenWRT firmware it can serve as a bridge, but also because it has USB port I can connect WebCam to it (althought since I’ll be using motorized IP cam, it’s not really required).

But firs thing I need to do is to learn how to control Roomba with Arduino.

For this I followed many guides posted online as well as by author of “Hacking Roomba” author, and got absolutely nowhere.

Roomba would not move or do anything. I rechecked my cable, sketch, used recommended SoftwareSerial library, etc. with no luck.   Then eventually I found the problem.  Everyone lied to me. Well not exactly 🙂   All the online examples probably worked for people who wrote them, but unfortunately my Roomba was different.  Thing is that Roomba Open Interface standard changed significantly.

1. Baud rate is now 115200 by default and not 57600
2. There’s no more DD pin. Instead this pin (#5) is now used to change baud rate. No more need to “wakup up” Roomba!
3. Command 130 (Control) is no longer needed (but still supported). Instead command 131 (Safe Mode) does same thing.

As soon as I realized this I made changes to the sketch, and it worked!

Here’s simple “Hello World” program that will make Roomba Got forward, stop then go backward a little.  Note you must connect Roomba’s RX pin to Arduino pin 4, and TX to Arduino Pin 3, or change pin definition in the code. Also connect Roomba’s ground to Arduino ground. You can power Arduino from USB or from Roomba.

#include <SoftwareSerial.h>

int rxPin = 3;
int txPin = 4;
int ledPin = 13;

SoftwareSerial Roomba(rxPin,txPin);

#define bumpright (sensorbytes[0] & 0x01)
#define bumpleft  (sensorbytes[0] & 0x02)

void setup() {
  pinMode(ledPin, OUTPUT);   // sets the pins as output
  Serial.begin(115200);
  Roomba.begin(115200);  
  digitalWrite(ledPin, HIGH); // say we're alive
  Serial.println ("Sending start command...");
  delay (1000);
   // set up ROI to receive commands  
  Roomba.write(128);  // START
  delay(150);
  Serial.println ("Sending Safe Mode command...");
  delay (1000);
  Roomba.write(131);  // CONTROL
  delay(150);
  digitalWrite(ledPin, LOW);  // say we've finished setup
  Serial.println ("Ready to go!");
  delay (5000);
}

void loop() {
  digitalWrite(ledPin, HIGH); // say we're starting loop
  Serial.println ("Go Forward");
  goForward();
  delay (500);
  Serial.println ("Halt!");
  halt();
  Serial.println ("Go Backwards");
  delay (500);
  goBackward();
  delay (500);
  Serial.println ("Halt!");
  halt();
  while(1) { } // Stop program
}

void goForward() {
  Roomba.write(137);   // DRIVE
  Roomba.write((byte)0x00);   // 0x00c8 == 200
  Roomba.write(0xc8);
  Roomba.write(0x80);
  Roomba.write((byte)0x00);
}
void goBackward() {
  Roomba.write(137);   // DRIVE
  Roomba.write(0xff);   // 0xff38 == -200
  Roomba.write(0x38);
  Roomba.write(0x80);
  Roomba.write((byte)0x00);
}

void halt(){
 byte j = 0x00;
 Roomba.write(137);   
 Roomba.write(j);   
 Roomba.write(j);
 Roomba.write(j);
 Roomba.write(j);
}