I tried to disable sleep by pulsing the BRC pin low for one second every minute as suggested in the OI, but my Create 2 still goes to sleep after 5 minutes.

My firmware is r3_robot/tags/release-3.2.6:4975 CLEAN

The Create 2 is connected to an Arduino, and the BRC is driven by one of the Arduino pins. I verified on a DMM that the voltage is indeed toggling. I am able to both send and receive serial data between the Arduino and Create2.


  1. Initialize roomba. Connect serial at 115200 baud. Toggle BRC: high for 200 ms, low for 200 ms, then high again. Leave it high.

  2. Ask roomba to stream sensor data in passive mode. Wait 1 second after BRC toggle to give some extra time to wake-up. Then send opcode 7 (reset), wait for reset message to complete by looking for the last few characters, then wait another second for good measure. Next, send opcode 128 (start into passive mode), wait 100 ms to let opcode stick, then ask for stream of data (opcode 148 followed by number of packet IDs and the packet IDs themselves).

  3. Main loop: Echo data from Create2 to the serial-USB output of the Arduino so that I can view the Create2 data. The data sent by the Create2 look valid (good checksum) and are sent in the expected time interval of ~15 ms. The main loop also toggles the BRC low for 1 second every minute.

For the full gory details, the complete Arduino sketch is shown below

const uint8_t brcPin = 2; // Must keep this low to keep robot awake
long last_minute = 0;
long minute = 0;

// Initialize roomba
void roomba_init()
  Serial3.begin(115200); // Default baud rate at power up
  while (!Serial3) {}    // Wait for serial port to connect

  // BRC state change from 1 to 0 = key-wakeup
  // keep BRC low to keep roomba awake
  pinMode(brcPin, OUTPUT);
  Serial.println("BRC HIGH");
  digitalWrite(brcPin, HIGH);
  delay(200);  // 50-500 ms

  Serial.println("BRC LOW");
  digitalWrite(brcPin, LOW);

  Serial.println("BRC HIGH");
  digitalWrite(brcPin, HIGH);
  last_minute = millis()/60000;

  delay(1000);  // give some extra time to wake up after BRC toggle.

  Serial.println("Opcode 7: reset robot");
  Serial3.write(7);      // Reset robot
  // Discard roomba boot message
  // Last part of reset message has "battery-current-zero 257"
  char c = 'x';
  Serial.println("Gimme a z!");
  while (c != 'z') {
    if (Serial3.available() > 0) {c = Serial3.read(); Serial.write(c);}
  Serial.println("Gimme a e!");
  while (c != 'e') {
    if (Serial3.available() > 0) {c = Serial3.read(); Serial.write(c);}
  Serial.println("Gimme a r!");
  while (c != 'r') {
    if (Serial3.available() > 0) {c = Serial3.read(); Serial.write(c);}
  Serial.println("Gimme a o!");
  while (c != 'o') {
    if (Serial3.available() > 0) {c = Serial3.read(); Serial.write(c);}
  // Flush remaining characters: 32 50 53 54 13 10 or " 257\r\n"
  Serial.println("Gimme a newline!");
  while (c != 10) {
    if (Serial3.available() > 0) {c = Serial3.read(); Serial.write(c);}
  delay(1000);  // allow extra time for opcode 7 to stick

  Serial.println("\nOpcode 128: start OI in passive mode");
  Serial3.write(128);   // Start the Open Interface.  Passive mode. 
  delay(100);           // Allow some time for opcode 128 to stick (not sure if this is needed)
  Serial.println("Opcode 148: stream data packets");
  Serial3.write(148);   // Stream data packets (every 15 ms)
  Serial3.write(16);    //   Number of packet IDs
  Serial3.write(8);     //   Packet ID 8 = wall                       1 byte
  Serial3.write(9);     //   Packet ID 9 = cliff left                 1
  Serial3.write(10);    //   Packet ID 10 = cliff front left          1
  Serial3.write(11);    //   Packet ID 11 = cliff front right         1
  Serial3.write(12);    //   Packet ID 12 = cliff right               1
  Serial3.write(13);    //   Packet ID 13 = virtual wall              1
  Serial3.write(27);    //   Packet ID 27 = wall signal               2
  Serial3.write(28);    //   Packet ID 28 = cliff left signal         2
  Serial3.write(29);    //   Packet ID 29 = cliff front left signal   2
  Serial3.write(30);    //   Packet ID 30 = cliff front right signal  2
  Serial3.write(31);    //   Packet ID 31 = cliff right signal        2
  Serial3.write(41);    //   Packet ID 41 = velocity right            2
  Serial3.write(42);    //   Packet ID 42 = velocity left             2
  Serial3.write(43);    //   Packet ID 43 = encoder counts left       2
  Serial3.write(44);    //   Packet ID 44 = encoder counts right      2
  Serial3.write(45);    //   Packet ID 45 = light bumper              1

void setup() {
  // Open serial communications (through USB interface)
  // The serial output of the Create 2 is echoed from Serial3 to Serial
  // so that we can observe the Create 2 serial output on a computer.
  while (!Serial) {}   // Wait for serial port to connect
  Serial.println(F("Starting roomba test...\n"));

  // Roomba serial commmunications
  Serial.println(F("Initializing comm to Roomba\n"));

long low_start_time;
boolean brc_is_low;
void loop() {
  // Read from Serial3 and echo results to Serial
  if (Serial3.available()) {
    uint8_t b = Serial3.read();
    uint8_t checksum = 19;
    if (b==19) { // First byte of reply stream is 19
      Serial.print("\nStart at ");
      Serial.print(b); Serial.print(" ");
      while (Serial3.available() < 43) {}  // Wait for rest of data (buffer is 64 bytes)
      for (int I=0; I<43; I++) {
        b = Serial3.read();
        Serial.print(b); Serial.print(" ");
        checksum += b;
      Serial.print("Chksum ");
      Serial.println(checksum);  // 0 is good
    } else {
      // Probably an ascii message
      Serial.print(b); Serial.print(" ");

  // Pulse BRC low every minute for 1 second
  long now = millis();
  long minute = now/60000;
  if (minute != last_minute) {
    Serial.println("\n\nBRC LOW");
    digitalWrite(brcPin, LOW);

    last_minute = minute;
    low_start_time = now;
    brc_is_low = true;

  // 1 s low pulse width
  if ((now > low_start_time + 1000) && brc_is_low) {
      Serial.println("\n\nBRC HIGH");
      digitalWrite(brcPin, HIGH);
      brc_is_low = false;
  • $\begingroup$ This may be a bug in the robot software or the OI documentation is out of date. Any reason the robot cannot be on a dock or in another OI mode? $\endgroup$
    – Jonathan
    Apr 22 '16 at 20:02
  • $\begingroup$ I think you may have a bad cable. Have you verified that the pin is changing level on the end of the Mini-DIN? If it is not, and you are using an iRobot cable, contact create@irobot.com referencing this post. $\endgroup$
    – Steve
    Jan 10 '17 at 13:30
  • $\begingroup$ At first let me admit, that my knowledge about the irobot create 2 is not very well, because the proprietary manufacturer is not the best company on the planet, the guys are producing malfunction robots and are not very supportive to their customers. Also my computational skills are not high enough to understand your problem, nor to fixing the sourcecode which is probably written in some form of C dialect which is not my language of choice for programming robots. Perhaps the guys in the official irobot store have more helpfull knowledge. On their website is on the right upper corner a button " $\endgroup$ Jun 10 '17 at 15:28
  • $\begingroup$ If this robot is on the dock, this problem is a duplicate of robotics.stackexchange.com/questions/15433/… . If the robot is not on the dock, I recommend @hcl337's answer at robotics.stackexchange.com/questions/12846/… . Please note that I am an iRobot employee, but the postings on this site are my own and don't necessarily represent iRobot's positions, strategies, or opinions. $\endgroup$
    – Steve
    Jul 18 '18 at 13:14

I'm having the exact same issue with a Roomba 635.

I'm also using an Arduino (an esp8266 specifically) and pulse the BRC port low for 100ms every 15 seconds.

I get:

Running sendInfoRoomba()...
ERROR: Incomplete packet recieved 0 bytes.
Pulsing awake pin & sending 128...

The commands I send every 10 seconds are: 128, 149, 3, 21, 25, 26

Yet I get no reply in numerous occasions. The only 'fix' is to press the power button on the top - then everything magically works - until it doesn't again.

EDIT: My bit of code that you may want to hijack :)

  // Get the following sensors:
  // 21 (1 byte reply) - charge state
  // 25 (2 byte reply) - battery charge
  // 26 (2 byte reply) - battery capacity
  unsigned int command[] = { 128, 149, 3, 21, 25, 26 };
  byte numOfCommands = (sizeof(command) / sizeof(command[0]));
  for ( int i = 0; i < numOfCommands; i++ ) {
    Serial.print("TX: "); Serial.println(command[i], DEC);

Note that I have two serials, Serial is the USB adapter to my PC, RoombaSerial is a SoftwareSerial for two pins to the Roomba.

  • 1
    $\begingroup$ I can't work out whether this is an answer with a solution or a question or a "I am having the same issue" post $\endgroup$ Jul 12 '18 at 7:14
  • $\begingroup$ Welcome to Robotics Steven Haigh. On StackExchange answers need to answer the question. StackExchange isn't a discussion forum, it's a place to ask questions and get answers. If you wish to discuss a question or answer you can use Robotics Chat, when you have chat privileges. If you have an idea for how a question can be improved, you can comment when you have comment privileges. Please review How to Ask and tour for more information on how StackExchange works. $\endgroup$
    – Mark Booth
    Jul 12 '18 at 11:23
  • $\begingroup$ Note: Although I would normally delete non-answers, I'm leaving this here as it might provide information which can assist in answering lejiang's question. $\endgroup$
    – Mark Booth
    Jul 12 '18 at 11:28

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.