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.
Pseudo-code:
Initialize roomba. Connect serial at 115200 baud. Toggle BRC: high for 200 ms, low for 200 ms, then high again. Leave it high.
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).
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);
delay(200);
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.
Serial.begin(115200);
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"));
roomba_init();
}
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.println(millis());
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.write(b);
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");
Serial.println(millis());
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");
Serial.println(millis());
digitalWrite(brcPin, HIGH);
brc_is_low = false;
}
}