Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"Wake up" fixes for Roomba 500 series #29

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ framework = arduino
lib_deps =
RemoteDebug
PubSubClient
ArduinoJson
ArduinoJson@~5.13.4

upload_port = roomba.local
build_flags = -DLOGGING=1 -DMQTT_MAX_PACKET_SIZE=512
5 changes: 4 additions & 1 deletion src/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@
#define HOSTNAME "roomba" // e.g. roomba.local
#define BRC_PIN 14
#define ROOMBA_650_SLEEP_FIX 1
#ifndef ROOMBA_650_SLEEP_FIX
#define ROOMBA_500 1
#endif

#define ADC_VOLTAGE_DIVIDER 44.551316985
//#define ENABLE_ADC_SLEEP

#define MQTT_SERVER "10.0.0.2"
#define MQTT_USER "homeassistant"
#define MQTT_COMMAND_TOPIC "vacuum/command"
#define MQTT_STATE_TOPIC "vacuum/state"
#define MQTT_STATE_TOPIC "vacuum/state"
75 changes: 66 additions & 9 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,16 +67,40 @@ const PROGMEM char *commandTopic = MQTT_COMMAND_TOPIC;
const PROGMEM char *statusTopic = MQTT_STATE_TOPIC;

void wakeup() {
#ifndef ROOMBA_500
DLOG("Wakeup Roomba\n");
pinMode(BRC_PIN,OUTPUT);
digitalWrite(BRC_PIN,LOW);
delay(200);
pinMode(BRC_PIN,INPUT);
delay(200);
Serial.write(128); // Start
roomba.start();
#else
// test connection to roomba
uint8_t packetLength;
bool result = roomba.pollSensors(roombaPacket, sizeof(roombaPacket), &packetLength);
if (result) {
DLOG("No need to wakeup Roomba\n");
} else {
DLOG("Wakeup Roomba\n");
pinMode(BRC_PIN, OUTPUT);
delay(50);
digitalWrite(BRC_PIN, LOW);
delay(50);
digitalWrite(BRC_PIN, HIGH);
delay(200);
digitalWrite(BRC_PIN, LOW);
delay(50);
pinMode(BRC_PIN, INPUT);
delay(50);
roomba.start();
delay(200);
}
#endif
}

void wakeOnDock() {
#ifndef ROOMBA_500
DLOG("Wakeup Roomba on dock\n");
wakeup();
#ifdef ROOMBA_650_SLEEP_FIX
Expand All @@ -87,6 +111,7 @@ void wakeOnDock() {
delay(150);
Serial.write(143); // Dock
#endif
#endif
}

void wakeOffDock() {
Expand All @@ -96,6 +121,19 @@ void wakeOffDock() {
Serial.write(130); // Passive mode
}

// stop current action
void roombaStop() {
if (roombaState.cleaning) {
DLOG("Stopping\n");
roomba.start();
delay(50);
roomba.safeMode();
delay(50);
roomba.start();
delay(50);
}
}

bool performCommand(const char *cmdchar) {
wakeup();

Expand All @@ -105,6 +143,7 @@ bool performCommand(const char *cmdchar) {
// MQTT protocol commands
if (cmd == "turn_on") {
DLOG("Turning on\n");
roombaStop();
roomba.cover();
roombaState.cleaning = true;
} else if (cmd == "turn_off") {
Expand All @@ -114,22 +153,30 @@ bool performCommand(const char *cmdchar) {
} else if (cmd == "toggle" || cmd == "start_pause") {
DLOG("Toggling\n");
roomba.cover();
roombaState.cleaning = !roombaState.cleaning;
} else if (cmd == "stop") {
#ifdef ROOMBA_500
roombaStop();
roombaState.cleaning = false;
#else
if (roombaState.cleaning) {
DLOG("Stopping\n");
roomba.cover();
} else {
DLOG("Not cleaning, can't stop\n");
}
#endif
} else if (cmd == "clean_spot") {
DLOG("Cleaning Spot\n");
roombaState.cleaning = true;
roombaStop();
roomba.spot();
} else if (cmd == "locate") {
DLOG("Locating\n");
// TODO
} else if (cmd == "return_to_base") {
DLOG("Returning to Base\n");
roombaStop();
roombaState.cleaning = true;
roomba.dock();
} else {
Expand All @@ -153,6 +200,7 @@ void mqttCallback(char *topic, byte *payload, unsigned int length) {
}
}

#ifdef ENABLE_ADC_SLEEP
float readADC(int samples) {
// Basic code to read from the ADC
int adc = 0;
Expand All @@ -165,6 +213,7 @@ float readADC(int samples) {
VLOG("ADC for %d is %.1fmV with %d samples\n", adc, mV, samples);
return mV;
}
#endif

void debugCallback() {
String cmd = Debug.getLastCommand();
Expand Down Expand Up @@ -206,8 +255,10 @@ void debugCallback() {
DLOG("Toggle BRC pin\n");
wakeup();
} else if (cmd == "readadc") {
#ifdef ENABLE_ADC_SLEEP
float adc = readADC(10);
DLOG("ADC voltage is %.1fmV\n", adc);
#endif
} else if (cmd == "streamresume") {
DLOG("Resume streaming\n");
roomba.streamCommand(Roomba::StreamCommandResume);
Expand Down Expand Up @@ -349,7 +400,7 @@ void onOTAStart() {

void setup() {
// High-impedence on the BRC_PIN
pinMode(BRC_PIN,INPUT);
pinMode(BRC_PIN, INPUT);

// Sleep immediately if ENABLE_ADC_SLEEP and the battery is low
sleepIfNecessary();
Expand All @@ -376,7 +427,7 @@ void setup() {
Debug.setCallBackProjectCmds(debugCallback);
Debug.setSerialEnabled(false);
#endif

roomba.start();
delay(100);

Expand Down Expand Up @@ -407,7 +458,7 @@ void sendStatus() {
DLOG("Reporting packet Distance:%dmm ChargingState:%d Voltage:%dmV Current:%dmA Charge:%dmAh Capacity:%dmAh\n", roombaState.distance, roombaState.chargingState, roombaState.voltage, roombaState.current, roombaState.charge, roombaState.capacity);
StaticJsonBuffer<200> jsonBuffer;
JsonObject& root = jsonBuffer.createObject();
root["battery_level"] = (roombaState.charge * 100)/roombaState.capacity;
root["battery_level"] = (roombaState.charge * 100)/ (roombaState.capacity != 0 ? roombaState.capacity : 2696);
root["cleaning"] = roombaState.cleaning;
root["docked"] = roombaState.docked;
root["charging"] = roombaState.chargingState == Roomba::ChargeStateReconditioningCharging
Expand All @@ -421,9 +472,15 @@ void sendStatus() {
mqttClient.publish(statusTopic, jsonStr.c_str());
}

int lastStateMsgTime = 0;
int lastWakeupTime = 0;
int lastConnectTime = 0;
long lastStateMsgTime = 0;
long lastWakeupTime = 0;
long lastConnectTime = 0;
#ifdef ROOMBA_500
// Wake up every 5 hours. Just to update battery level.
long wakeupInterval = 18e7;
#else
long wakeupInterval = 50000;
#endif

void loop() {
// Important callbacks that _must_ happen every cycle
Expand All @@ -444,7 +501,7 @@ void loop() {
reconnect();
}
// Wakeup the roomba at fixed intervals
if (now - lastWakeupTime > 50000) {
if (now - lastWakeupTime > wakeupInterval) {
lastWakeupTime = now;
if (!roombaState.cleaning) {
if (roombaState.docked) {
Expand Down Expand Up @@ -473,4 +530,4 @@ void loop() {

readSensorPacket();
mqttClient.loop();
}
}