johnboiles / esp-roomba-mqtt

ESP8266 MQTT Roomba controller (Useful for hooking up old Roombas to Home Assistant)
200 stars 60 forks source link

Deep sleep #3

Open AndiTheBest opened 6 years ago

AndiTheBest commented 6 years ago

Hi,

any updates from preventing the roomba going to deep sleep, so the serial comm doesn't get disabled? Same problem here :/

Apocrathia commented 6 years ago

I've gotten the following code from Thinking Cleaner. Since their product is now EOL, they have been willing to share their source code.

void RoombaWakeOnDock(void) {
    ROOMBA_WAKE_LO();      // hardware wake pin on SCI conn
    DelayMs(50);
    ROOMBA_WAKE_HI();      // hardware wake pin on SCI conn
    DelayMs(80);
    RingBufferWrite(&txBuffer, OPCODE_CLEAN);    // write the CLEAN command code to the SCI port
    RingBufferWrite(&txBuffer, 0x10);
}

Unfortunately, I don't have a 650 to test this with. I hope this helps.

quazzie commented 6 years ago

@Apocrathia got any more information ? I tried sending this sequence every 50 seconds to keep the 650 awake but it starts the cleaning cycle. I tried with both OPCODE_CLEAN = 136 and 135.

AndiTheBest commented 6 years ago

I did it the following way:

When Roomba is in dock:

  pinMode(roomba_reset,OUTPUT);
  digitalWrite(roomba_reset,LOW); // start roomba
  delay(200);
  pinMode(roomba_reset,INPUT);
  delay(200);
  ROOSER.write(128); //start command
  delay(10);
  ROOSER.write(135); //CLEAN
  delay(150);
  ROOSER.write(143);//DOCK

When its not in dock and not cleaning:

  ROOSER.write(131);//SAFE MODE
  delay(300);
  ROOSER.write(130);//PASSIVE MODE

But its not working perfectly. The Roomba doesnt go to sleep mode and wastes much power when not in dock. And when the battery got drained, the Arduino is not able to establish a connection until I unplug and replug it. The delays are important what i remember when implementing this. When you send the commands too fast, it won't recognize them i think.

And every few weeks it happens that the Roomba starts cleaning in the middle of the night. I think the "ROOSER.write(143);//DOCK" command was not received then.

quazzie commented 6 years ago

Thanks @AndiTheBest Seems to work :)

legomind commented 6 years ago

Just wanted to say that the current wakeup code works great for the 860

johnboiles commented 6 years ago

Great investigation @Apocrathia. I had also tried to reach out to Thinking Cleaner in the past but wasn't able to get ahold of them. I'm glad you were able to!

I'll give this a shot on my 650

johnboiles commented 6 years ago

@Apocrathia did they share their whole source code or just this one bit?

Apocrathia commented 6 years ago

@johnboiles That was the only snippet that they gave to me when I asked. I simply emailed their thinkingcleanersales@thinkingbits.nl address and asked if they would be willing to share how they accomplished it, as their product is EOL and they can no longer benefit from keeping the source code closed. I'm sure someone could convince them to release the rest of it.

johnboiles commented 6 years ago

@AndiTheBest when you're changing pinMode(roomba_reset,INPUT); is that to make the pin high impedence?

johnboiles commented 6 years ago

@Apocrathia's code from Thinking Cleaner definitely causes my Roomba to start cleaning. I'm also super curious what RingBufferWrite(&txBuffer, 0x10) is supposed to do. There's not anything in the docs about that command I don't think.

@AndiTheBest's code is working fine so far for me (only about 15 mins of testing at this point though). @AndiTheBest would you mind putting your full code on GitHub or submitting pull requests? You must have made some other changes to track the state of the roomba so that you can switch wakeup methods

johnboiles commented 6 years ago

I went ahead and pushed up @AndiTheBest's fix to master. Might be good for some non-650 people to try it since it changes things a bit. You might want to comment out #define ROOMBA_650_SLEEP_FIX 1 in the config.h file though

AndiTheBest commented 6 years ago

Sorry, i don't use the code of this project, as i've implemented my project on my own, using an Arduino Pro Micro with a HC-12 wireless transceiver. Just here for exchanging experience ;) I've set the Pin to Input instead of Output-High as the Roomba internally already has an Pullup. This is not necessary.

Just for infomation again: Every few weeks/months, the Roomba starts cleaning in the middle of the night, as i think it doesnt get the "DOCK" command after the "CLEAN" command (single serial communication fail). This is something that still needs to get prevented, but i didn't had time to play with my roomba the last few months :/

johnboiles commented 6 years ago

It would still be interesting to see your code if you wouldn’t mind sharing! Maybe some other ideas we could learn!

johnboiles commented 6 years ago

@AndiTheBest's fix has been working reliably for me for a week or so. I still occasionally have an issue where i need to send the turn_on command multiple times to get the roomba to start, but it's possible I need to wait more after pulsing the BRC pin to send commands.

johnboiles commented 5 years ago

I got my first middle-of-the night roomba wake up last night and it sucked. I’m going to put some more effor into figuring out a better solution.

bastian987 commented 5 years ago

Is there any update? I am super curious to get this running, but keeping the Roomba awake all the time and risking midnight cleaning does not sound perfect.

My main use-case would be to stop the Roomba from cleaning if somebody is at home. One alternative approach I was thinking about: I could use the schedule of the Roomba to initiate cleaning. If I could detect the start quickly enough, I could immediately send a stop command if someone is home. Any comments whether this could be feasible?

bastian987 commented 5 years ago

I‘m now thinking about two other workarounds:

johnboiles commented 5 years ago

I disabled the 650 wakeup workaround (because I want to make sure not to get woken up again).

diff --git a/src/config.h b/src/config.h
index 9c26860..8c0b18f 100644
--- a/src/config.h
+++ b/src/config.h
@@ -2,10 +2,10 @@

 #define HOSTNAME "roomba" // e.g. roomba.local
 #define BRC_PIN 14
-#define ROOMBA_650_SLEEP_FIX 1
+//#define ROOMBA_650_SLEEP_FIX 1

 #define ADC_VOLTAGE_DIVIDER 44.551316985
//#define ENABLE_ADC_SLEEP

 #define MQTT_SERVER "10.0.0.2"
 #define MQTT_USER "homeassistant"
diff --git a/src/main.cpp b/src/main.cpp
index 586783c..048d615 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -449,8 +449,7 @@ void loop() {
       if (roombaState.docked) {
         wakeOnDock();
       } else {
-        // wakeOffDock();
-        wakeup();
+        wakeOffDock();
       }
     } else {
       wakeup();

And it actually still sorta seems to work. I just have to issue the turn_on command twice for the vacuum to come on. I'm wondering if moving to streaming values made it wakeup a little more easily somehow?

johnboiles commented 5 years ago

But I'm confident that with some experimentation, whatever is causing it to still wake up after issuing the turn_on command twice, could be adapted into a full-blown fix.

KTibow commented 4 years ago

You can solve multiple problems by using this:

roomba.write(135); // Clean
delay(10);
roomba.write(131); // Safe mode (stops cleaning job)
delay(50);
roomba.write(131); // Make sure roomba got safe mode command (prevents cleaning in the middle of the night
delay(50);
roomba.write(130); // Go back into normal mode
delay(50);
roomba.write(130); // Make sure roomba goes back into normal mode (so you don't have to pick roomba up in order to escape safe mode)

Namely, this code works off the dock and on the dock. The only downside is that it stops the roomba from cleaning, but so would the proposed solution for waking up the roomba off the dock:

  ROOSER.write(131);//SAFE MODE
  delay(300);
  ROOSER.write(130);//PASSIVE MODE

I've been using this solution for my code with checking to see whether the roomba is cleaning (is the brush spinning or the right wheel moving), and it works great.

KTibow commented 4 years ago

Update: Midnight cleaning problems, or in my case, mid-day. Anybody here have an idea to stop it from cleaning?

KTibow commented 4 years ago

I ended up doing something like

safeMode()
safeMode()
if (oiMode != safeMode) {
log("Midnight cleaning detected!")
closeConnection()
delay(1000)
openConnection()
safeMode()
safeMode()
passiveMode()
passiveMode()
closeConnection()
openConnection()
}
passiveMode()
passiveMode()

The weird thing is, when it starts cleaning, I can still issue the stop command and it'll stop. Might the past contributors want to help?