diff --git a/platformio.ini b/platformio.ini index e413100..57c2fce 100644 --- a/platformio.ini +++ b/platformio.ini @@ -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 diff --git a/src/config.h b/src/config.h index 9c26860..24b6283 100644 --- a/src/config.h +++ b/src/config.h @@ -3,6 +3,9 @@ #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 @@ -10,4 +13,4 @@ #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" \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index b30b0ff..205420c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -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 @@ -87,6 +111,7 @@ void wakeOnDock() { delay(150); Serial.write(143); // Dock #endif +#endif } void wakeOffDock() { @@ -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(); @@ -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") { @@ -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 { @@ -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; @@ -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(); @@ -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); @@ -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(); @@ -376,7 +427,7 @@ void setup() { Debug.setCallBackProjectCmds(debugCallback); Debug.setSerialEnabled(false); #endif - + roomba.start(); delay(100); @@ -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 @@ -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 @@ -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) { @@ -473,4 +530,4 @@ void loop() { readSensorPacket(); mqttClient.loop(); -} +} \ No newline at end of file