3
$\begingroup$

Over the past few weeks, I have been attempting to interface the iRobot Create 2 with an Arduino Uno. As of yet, I have been unable to read sensor values back to the Arduino. I will describe by hardware setup and my Arduino code, then ask several questions; hopefully, answers to these questions will be helpful for future work with the Create 2.

Hardware: The iRobot Create 2 is connected to the Arduino Uno according to the suggestions given by iRobot. Instead of the diodes, a DC buck converter is used, and the transistor is not used because a software serial port is used instead of the UART port.

Software: The following is the code that I am implementing on the Arduino. The overall function is to stop spinning the robot once the angle of the robot exceeds some threshold. A software serial port is used, which runs at the default Create 2 Baud rate.

#include <SoftwareSerial.h>
int rxPin=3;
int txPin=4;
int ddPin=5; //device detect
int sensorbytes[2]; //array to store encoder counts
int angle;
const float pi=3.1415926;
#define left_encoder (sensorbytes[0])
#define right_encoder (sensorbytes[1])
SoftwareSerial Roomba(rxPin,txPin);

void setup() {
  pinMode(3, INPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(ledPin, OUTPUT);
  Roomba.begin(19200);

  // wake up the robot
  digitalWrite(ddPin, HIGH);
  delay(100);
  digitalWrite(ddPin, LOW);
  delay(500);
  digitalWrite(ddPin, HIGH);
  delay(2000);

  Roomba.write(byte(128));  //Start
  Roomba.write(byte(131));  //Safe mode
  updateSensors();

  // Spin slowly
  Roomba.write(byte(145));
  Roomba.write(byte(0x00));
  Roomba.write(byte(0x0B));
  Roomba.write(byte(0xFF));
  Roomba.write(byte(0xF5));  
}

void loop() {
    updateSensors();
    // stop if angle is greater than 360 degrees
    if(abs(angle)>2*pi){
      Roomba.write(173);
      delay(100);
    }
}

void updateSensors() {
  // call for the left and right encoder counts
  Roomba.write(byte(148));
  Roomba.write(byte(2));
  Roomba.write(byte(43));
  Roomba.write(byte(44));
  delay(100);

  // load encoder counts into an array
  int i = 0;
  while(Roomba.available()) {
    int c = Roomba.read();
    sensorbytes[i] = c;
    i++;
  }
  angle=((right_encoder*72*pi/508.8)-(left_encoder*72*pi/508.8))/235;
}

Questions:

  • Am I loading the sensor values into the array correctly? This same code works when a bump and run program is implemented, but that requires knowing only one bit rather than two bytes.
  • How many bytes can be read over the serial connection at a time? A previous post (Help sending serial command to Roomba) highlights that one byte can be sent at a time. Does this imply that the reverse is true? If so, would a solution be to use a char array to read the values instead and then to append two chars to form an signed int?
  • Is serial communication synchronization a problem? I am assuming that synchronization is not a problem, but is it possible for the bytes to be split on the nibble boundaries? This would present a problem because there is not a nibble datatype.
$\endgroup$
3
$\begingroup$

As it turns out, I was not loading the sensor values into the array properly. It seems that data is transmitted one byte at a time, so the sensorbytes array needed to be an array of 4 elements rather than two. Once this was corrected, the correct encoder counts could be determined by joining the upper and lower bytes of the encoder counts from each wheel using the following scheme:

// highbyte is shifted left eight bits, lowbyte is added to highbyte    
// encoder_count=highbyte<<8+lowbyte
left_encoder=sensorbytes[0]<<8+sensorbytes[1];

This scheme made sure that the resulting left_encoder was a signed int rather than an unsigned int had the word() function been used. The revised updateSensors() code can be found in this post: iRobot Create 2: Encoder Counts.

Serial communication synchronization was not a problem. I suspect that this sort of thing is handled behind the scenes and does not need to be programmed at the high level that I am working on.

$\endgroup$
2
$\begingroup$

NBCKLY, have you been able to connect and send commands to the Create 2 with your Arduino?

Did you put the Create into 19200 Baud mode as referenced in page 4 of the OI Specifications1?

Method 1: While powering off Roomba, continue to hold down the Clean/Power button after the light has turned off. After about 10 seconds, Roomba plays a tune of descending pitches. Roomba will communicate at 19200 baud until the processor loses battery power or the baud rate is explicitly changed by way of the OI.

Method 2: Use the Baud Rate Change pin (pin 5 on the Mini-DIN connector) to change Roomba’s baud rate. After turning on Roomba, wait 2 seconds and then pulse the Baud Rate Change low three times. Each pulse should last between 50 and 500 milliseconds. Roomba will communicate at 19200 baud until the processor loses battery power or the baud rate is explicitly changed by way of the OI.


1 iRobot® Create® 2 Open Interface (OI) Specification

$\endgroup$
  • $\begingroup$ It seems that a common concern is interfacing the Arduino with the Create 2 is the Baud rate. Using the software serial port (not the labeled RX/TX pins, which use UART), the Arduino is able to communicate at 115200 Baud. I am able to both send and receive information satisfactorily at this rate. While I cannot attest to the exact reliability of using the Arduino at this Baud because I have not performed rigorous testing, I suspect that the error is low enough for implementation of certain forms of control. $\endgroup$ – JSycamore May 13 '15 at 20:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.