I set out this weekend to get an Arduino board to control my Roomba. (The Roomba has a great – and generally open – interface, and iRobot deserves significant credit for encouraging creative repurposing/extensions of their products.) I’ve got a few project ideas in mind, but for an initial step just wanted to verify that the Arduino could a) send control commands (“move forward”, “turn right”, etc.) from the Arduino, and b) read sensor data (“something is touching my left bumper”, “I’m about to fall down the stairs”). This post contains my notes, which hopefully will help others doing this sort through some of the issues in a bit less time than that I spent.Â
The Cable
I’ve had the necessary cable (straight-through 8 pin mini-DIN) to connect to the serial control connector on the Roomba quite a while, and I’d already successfully cut a hole in the top of the Roomba’s cover to expose the port. (I used a Dremel, though I suppose you could drill and file if you were careful and patient.)
I cut the cable in half and soldered male header pins to the correct wires to make a 2-pin power/ground connector and a 3-pin connector that had the serial RX/TX line as well as the DD (Device Detect) pin. (There’s no reason the serial and DD lines need to be next to each other, but it made for a simpler connector, and it’s easy to just assign them proximate ports on the Arduino’s digital pin bank.) Tod Kurt, author of Hacking Roomba and part of the impressive ThingM studio, has a basic photoset showing a similar cable. At this point, if you’re looking to do this yourself, you may be wondering which wires in the cable need to go to which pins of the connectors. I have no idea if there’s reliable consistency in the colors used inside of mini-DIN cables, so I’d suggest figuring this out yourself with your specific cable and a continuity detector of some sort. The pin diagram on page 2 of iRobot’s SCI (Serial Command Interface) documentation should be all you need.
Powering the Arduino
The power connector from the Roomba is carrying +16V, which is more than enough to power the Arduino (I’m using the Diecimila and Duemilanove versions of the board). According to the docs, this is within the acceptable input range, but outside of the recommended range. In my early attempts to hook it up, I seem to have fried a Diecimila board by connecting Roomba’s +V line to the ‘Vin’ header on the Arduino (sometimes labeled ‘9V’). I got it working by running the Roomba’s +V line through a 5V voltage regulator and then directly into the ‘5V’ header on the Arduino (note: it’s important to only do this with a regulated supply, since the 5V header bypasses the Arduino’s onboard regulator). This worked fine, even if it does mean that the minimal setup is no longer just an Arduino and a cable. After I fried the Diecimila, I switched to a Duemilanove, though to my knowledge there is no relevant difference in terms of power requirements or tolerance.
OK, It Should Work Now
Based on the research I’d done, I expected that things would more or less just work at this point. For the software side of my proof of concept, I was using Tod Kurt’s RoombaBumpTurn sketch. The sketch sends the Roomba forward, then checks the left and right bump sensors in a loop, turning ‘away’ from the objects it collides with.
I was excited on my first attempt to see the Roomba ‘wake up’ shortly after connecting my cable to the board. Then: nothing. Hmm.
By default, the Roomba’s SCI talks at 57000 bps, and the code was assuming that data rate. I didn’t recall having changed it during previous times hacking around with the Roomba, but just in case I changed the serial speed to 19200 and, sure enough, the Roomba jolted forward shortly after powering up the Arduino. OK, cool, so there was at least basic connectivity.
I didn’t really have a reason to run at the slower serial speed, so I threw a quick one-time change into the setup() function to reset the baud rate back to 57000:
// [re]set baud rate to 57600 sciSerial.print(129, BYTE);Â // BAUD sciSerial.print(10, BYTE);Â Â // 57600 delay(100);
*Now* It Should Work, Really
With basic serial connectivity established, I went on to verify that basic bumping and turning behavior worked as expected. In short, it didn’t. Most of the time letting the Roomba collide with something (or even just manually pressing the sensor) did nothing; perhaps 10% of the time it would cause the Roomba to turn. In order to verify that I really was getting commands to the Roomba, I added a short sequence of actions called from the setup() method:
void dance() { xbSerial.println("top of dance()"); updateSensors(); goForward(); delay(1000); goBackward(); delay(1000); stopMoving(); } ... void stopMoving() { sciSerial.print(137, BYTE); // DRIVE sciSerial.print(0x00,BYTE); // 0x0000 == 0 sciSerial.print(0x00,BYTE); sciSerial.print(0x00,BYTE); sciSerial.print(0x00,BYTE); // 0x0000 }
The Roomba jogged forward, and backward, just as I’d expect. This left me pretty much convinced that sending commands was working fine, and that my problem was in reading sensor values.
At this point I really started to feel the lack of debugging information. While I was pretty sure my problem was in sensor reading, it was certainly time to validate my overall expectations about program flow, as well as inspect return values from the sensor checks, etc. Debugging is always more of a challenge on an embedded platform with no display/keyboard, but my typical answer for this when using the Arduino — “I’ll just println() to the serial port and monitor it over USB” — doesn’t work here, for two reasons. First, the serial port is being used by the connection to the Roomba. As if that weren’t enough (and it is), the Roomba is driving across the floor, and I wouldn’t want to chase after it with my laptop.
Remote Wireless Debugging with XBee
Fortunately, there is a good answer to debugging the code running on the Arduino sitting on top of my Roomba as it scoots away from me: Digi’s XBee modules. I’ve been playing around with these for a different project recently, and at a basic level they provide an easy wireless link with a serial interface. Interfacing with the Arduino is a snap with the XBee adapter kit from the outstanding adafruit industries (sparkfun also has a breakout board I’ve used with success, but it requires a bit more of a surrounding circuit — nothing tricky, but not as easy as adafruit’s).
The attentive reader might now be wondering: I just explained that my serial port was already spoken for, and the XBee module has a serial interface. So how does this really solve my problem? Enter NewSoftSerial, an updated version of the Arduino software serial library, which basically lets you drive a serial interface from any two digital I/O pins on the Arduino. [Yes, I could also use this to debug directly over a serial line, which would be an option if you didn’t have a pair of XBee modules and didn’t mind potentially chasing after your Roomba.] I had a pair of XBee modules already configured to talk to each other (details of that are far outside the current scope). One module got connected to a couple of pins on the Arduino, and the other to my laptop via the trusty FTDI USB TTL-232 cable. On the laptop I then ran a simple serial terminal with ‘screen’ (any terminal program would do), and voila — I can println() from the vacuum cleaning scuttling across the floor and see it on my laptop from across the room (or halfway down the block, for that matter).
With basic visibility established, I was able to dig further into what wasn’t working with regard to sensor readings.  The sensor reading routine in RoombaBumpTurn is pretty straightforward:
void updateSensors() { Serial.print(142, BYTE); Serial.print(1, BYTE); // sensor packet 1, 10 bytes delay(100); // wait for sensors char i = 0; while(Serial.available()) { int c = Serial.read(); if( c==-1 ) { for( int i=0; i<5; i ++ ) { // say we had an error via the LED digitalWrite(ledPin, HIGH); delay(50); digitalWrite(ledPin, LOW); delay(50); } } sensorbytes[i++] = c; } }
After adding some basic println() breadcrumbs (not shown here), it quickly became clear that this function simply wasn’t returning a value that suggested it had correctly read the bump sensors. The clearest indication of this was when I added some code to check the value of i at the end of updateSensors(). The SCI doc is pretty clear — you ask for sensor packet 1, you get 10 bytes back. However, I was consistently getting 2 bytes, or 4 bytes, or 3. Once in a while I’d get 10 bytes, but it was rare.
This is good. This is progress.
Other People’s Problems
I googled for notes from others doing similar things, and found a number of examples. Actually, I found a surprising (but at this point encouraging) number of people having problems reading Roomba sensors from Arduinos. Some of the closest matches were:
- “Roomba SE Receiving Serial Data” on the Robot Reviews forum
A long thread, most of which is exploring a possible hardware inconsistency between the Roomba’s serial signal and Arduino’s serial port. The original poster is also working with the RoombaBumpTurn code, it seems, but near the end of the thread it spontaneously starts working, with no changes having been made (huh?). - “SERIAL COMMUNICATION NOT WORKING!!!” on Robot Reviews
This one starts out with a similar problem description, but concludes that the Arduino Diecimila (the previous generation) works with the Roomba, while Duemilanove (the current) doesn’t. I am certainly not a hardware guy, but from my understanding of the differences between these boards that doesn’t sound likely. - “Software Serial” on the Arduino Forum
A relatively short thread, this starts out referencing the hardware issues speculated on in the first thread, and concludes with the original poster successfully getting sensor readings after switching the Arduino<->Roomba serial connection to use a software serial driver rather than the Arduino hardware.
I also encountered a few posters who noted that they’d had different amounts of success by changing the amount of time the code waits after sending the sensor read command to the Roomba and starting trying to read results. The default in RoombaBumpTurn is 100ms, one person noted that 64ms seemed to work, and I found I’d get more readings (roughly) the lower I set the delay, but I’d also get more phantom readings (i.e. where the Arduino thought a bump sensor had been activated when none had). In any case, regardless of the duration of the delay I never anything close to accurate, and never was able to consistently see 10 bytes of data coming back from the Roomba.
Solved!
The theme of inconsistent serial interfaces between the Roomba and the Arduino was too prevalent to ignore. I was skeptical about it largely because, as I understood the hypothesis, it should have meant that no Roomba-controlling Arduino code connected via the built-in hardware serial interface would work, and there are a number of hints (including, primarily, the RoombaBumpTurn code) that it was working for some people. After more or less running out of other things to try, however, I decided to give it a shot, and switched my hacked-up copy of RoombaBumpTurn around so that it expected the XBee to be connected to the hardware interface and used NewSoftSerial to connect to the Roomba SCI port.
And that did it. Immediately, everything worked.
In Conclusion
I think the good folks in the Robot Reviews forum have nailed the issue, and that the current levels produced by the Roomba are too low to consistently register on the Arduino’s UART. I can’t explain how that is consistent with the “now it works .. I don’t know what I changed” stories I found in a few places, or how anyone has consistently controlled Roombas from the Arduino’s hardware serial port. In addition to using a software serial interface, user kg4wsv on the Arduino forum suggests a pair of back-to-back TTL signal inverters to buffer and bolster the current on the signal coming from the Arduino; I haven’t tried that yet, but it could be a useful alternative if your program was going to use frequently talk over the SCI connection (as software serial is relatively expensive, computationally).
With all of this sorted out, my Roomba is now running the simple bump & turn algorithm (I added a few pauses to make it easier to see exactly what sensor readings the code got).
Thanks for the great post. I am also having problems getting the arduino to work with my roomba via the mini-DIN cable. I have Tod Kurt’s code but can’t figure out why it doesn’t work. The most I have is that the LED flickers so it is plainly going through the loop part. I thought maybe it was the baud rate but either one doesn’t work. By the way, the SCI says that removing the battery will cycle baud rate back to the default although I like your software way of setting it. Is their any chance you could post your code so I could try that. I am getting to the end of my tether here!
Thanks again,
Ronan
Hi Ronan –
Sure, I’ll post the code … it’s just my various incremental changes to Tod Kurt’s, as described in the post, but if it might help, no problem. I’ll put it in the next comment.
Are you using NewSoftSerial? If you’re not, I’d seriously suggest switching to that now, just to get the UART current problems out of the picture (even if this doesn’t solve your problem, it’ll simplify troubleshooting).
Josh
Source code is at: http://www.netfluvia.org/code/HelloRoomba.pde
Wow thanks!
I will try that out as soon as I get a chance. I’m just starting out with Arduino so this helps a lot. Do you think I’ll be able to debug things just using the USB/Serial cable? I haven’t got an XBee module yet…
Thanks again,
Ronan
Yes, I definitely think you can debug without the XBee. Basically, wherever I’m writing to the XBee, you’d just be writing to the serial cable instead. You’ll need to keep your computer and the roomba within a cable’s length of each other, but for debugging purposes that shouldn’t be a problem.
The only difference will be how you wire this up — the code will be the same. So just leave the USB cable hooked up as if you were still downloading code to the arduino, and open up a terminal (or use the serial monitor), and you’ll see the debug messages.
[…] JRH writes- I set out this weekend to get an Arduino board to control my Roomba. (The Roomba has a great – and generally open – interface, and iRobot deserves significant credit for encouraging creative repurposing/extensions of their producs.) I’ve got a few project ideas in mind, but for an initial step just wanted to verify that the Arduino could a) send control commands (”move forward”, “turn right”, etc.) from the Arduino, and b) read sensor data (”something is touching my left bumper”, “I’m about to fall down the stairs”). This post contains my notes, which hopefully will help others doing this sort through some of the issues in a bit less than that I spent. Filed under: Arduino — by adafruit, posted June 21, 2009 at 12:17 pm […]
Hey, did you ever progress this from the simple bump and turn?
Hi Colin –
I haven’t had any more time to spend on this since I go the basics working, so no, not yet. I do intend to, though — next up is trying to use a wii nunchuck via xbee to steer the roomba (with this, from which I have basic readings working).
I think the whole of the SCI API should now be available, though. Since the sensor interface is poll-driven, there will be some practical limit imposed in terms of speed/latency (and I’ve yet to explore what that limit might be).
Josh
Here’s the solution to your problem, Josh:
The FTDI chip is interfering with the signal coming from the roomba when it is connected. You must DISCONNECT the actual ATmega8/168/328 from the F232R on the arduino while receiving sensor data from the Roomba. This will solve your (and MANY others’) problem.
-Reece
Greetings, thanks for the great article.
Though I’m a bit confused. I have a Roomba 4210 and an Arduino Uno. When I connect to the Roomba the board powers on but I get no response from the Roomba, not even wakeup. Is this a result of the serial issue or is my bot not compatible? How can I troubleshoot this? I checked continuity on my interface between the pins on the plug and the solder points on the bottom of the Arduino. Any suggestions would be great.
Thanks for the post. Where can I find more information about how work with XBee boards on arduino? What protocol is used to configure network parameters? When I connect it to a computer does it just appear as a regular serial port? Thanks.
You could just skip the XBee all together and instead get one of those wireless Nunchucks with the adapter that connects to the bottom of the Wiimote. It has the same pin-outs, and I would assume communicated the same data as the wired version.
Yeah, that works too. I prototyped that a few after I did this, and it was really cool to watch the Nunchuck joystick direct the roomba around.
In my case, the ultimate goal is to have the onboard Arduino directing the Roomba and using XBee to move command and control data back to other computer and/or microprocessors in the house.
-Josh
Thanks for this! You inspired me to do the same, just wondering, can you share your setup for the Xbee’s? I’m not familiar with them (just barely started using and Arduino), and don’t know where to start…
Thanks again!
@dadueler (& @BobA) – I can’t find my detailed xbee setup notes anymore, but as I recall there aren’t any big tricks once you’ve got the basic config down. I’d suggest starting with http://www.ladyada.net/make/xbee/point2point.html. As I recall you will need windows to run the Digi config software mentioned here (not strictly necessary, I don’t think, but possibly easier). I was able to successfully run it in a VM. If that doesn’t do it, it should be easy to google for the more xbee setup help. Good luck!
Help, i’m lost. I connected the Roomba 560 via an Arduino bord. If i sent serial bytes from the pc using Max i can start/stop the Roomba. I use the line: serial write (143) to sent the same hex bytes with THE Arduino and than nothing. Using a serial monitor i see the same hex codes passing but only the one sent by the pc works….
Can annyone help?
I Used “Software.Serial” op pin 2 & 3 and Serial.write (143) and that seems to work.
Peter,
could you posssibly post your code so I can see how you are doing it….I too am using software serial, but I get nothing out of my roomba…..
Thanx,
Matt – my code (http://www.netfluvia.org/code/HelloRoomba.pde) does that, as well — see the “OPTION 1” and “OPTION 2” blocks at the top. The difference between the two is just whether software serial is used for the XBee or for the Roomba. I did the former most of the time, but did test with the latter, so this should at least be a decent template for you to follow.
Note that I haven’t yet updated this code to reflect the way software serial works in Arduino 1.0, but that’s trivial. (A quick google should sort you out there, if you don’t know what I’m talking about.)
good luck,
-jrh
Hi
Thanks for the great breakdown.
I am about to order the following setup, does it sound feasible to you?:
An Arduino bluetooth and a RooStick (Roomba to USB Bridge) and sending commands to the roomba over usb and feedback to the computer of bluetooth.
Or am I assuming something wrong? Can I address the serial ports individually (USB, Bluetooth)?.
thank you!
holby
Sorry, of course there is no USB on bluetooth arduino. So communication would be RX/TX pins to roomba, and bluetooth for feedback.
But the question remains, can I address two serial interfaces simultanously?
thanks
I haven’t used the bluetooth arduino myself, but assuming it’s just an arduino with an onboard bluetooth device you can access via serial, and that you connect the arduino via wired serial (between the roomba and arduino), I think your setup should work.
Holby, the Uno has a single Serial Comm. I literally just bought the Mega (10 minutes ago) to get the extra serial ports and accomplish exactly what you are talking about.
“Serial: 0 (RX) and 1 (TX). Used to receive (RX) and transmit (TX) TTL serial data. These pins are connected to the corresponding pins of the Bluegiga WT11 module.”
From http://arduino.cc/en/Main/ArduinoBoardBluetooth
Acutally, i’m highly mistaken. You can use the software serial library to do it, but it takes a good bit of computation. I needed a mega anyways. Ah well!
Thanks for this! You inspired me to do the same, just wondering, can you share your setup for the Xbee’s? I’m not familiar with them (just barely started using and Arduino), and don’t know where to start…
Hi Nadina – Unfortunately I didn’t save my detailed setup notes on the XBee. However, it’s not a horribly complex process. See comment #14 above to get started, and google should give you the rest of what you need pretty easily.
Good luck!
Josh
GREAT post!
however, it is importent to remember that the baud rate is actually differ between Roomba versions.
Here is a comprehansive guide about , and how to configure it for your Roomba.
Controlling the roomba via the SCI port is not terribly difficult, but the whole process never was documented that well initially by iRobot. On top of that, a lot of the “commands” that you send down to control the device are not intuitive. If anyone is just starting to play around with controlling the roomba, I would recommend checking out this link:
http://www.robotappstore.com/Knowledge-Base/1-Introduction-to-Roomba-Programming/15.html
In one of the postings above, it was also mentioned having problems with the baud rate. This covers the settings that each roomba model needs, as they are different.
Hope this helps!
I see you don’t monetize your site, don’t waste your traffic, you can earn additional cash every month.
You can use the best adsense alternative for any type of website (they approve all websites), for more details simply search in gooogle:
boorfe’s tips monetize your website
Moreover, in addition, you need to be enthusiastic soul who’ll play even if they and luck aren’t in your favor.
In addition, the poker rooms will not offer complete hand histories of all poker hands dealt on his or her site for analysis by
outside sources. The best internet poker strategy for your game
is always to learn all you can about the game, using position, when and
how much you should raise, what starting hands are best for your posture,
the chances of hitting your draws then when to fold.