3

I'm trying to build a sensor that should update an MQTT broker only if something changes. So every few seconds it's supposed to wake up just enough to check a few inputs, compare them with the last time it woke up, and only if there has been a change should it connect to the broker and write the updates. I don't expect many updates per day, but if I sleep more than 10 seconds, I might miss them.

I'm using WiFi.forceSleepBegin() and WiFi.forceSleepWake(), mainly based on these articles. But there is this tempting option of ESP.deepSleep(n, WAKE_RF_DISABLED)

The API that I found only mentions this:

If you implement deep sleep with WAKE_RF_DISABLED and require WiFi functionality on wake up, you will need to implement an additional WAKE_RF_DEFAULT before WiFi functionality is available.

Do I read this correct if I understand that I would need to make another deepSleep just to wake up again with WiFi back active? Or is there an easier way to boot up the WiFi after such a sleep?

Thank you

2 Answers 2

3
WiFi.forceSleepBegin();
delay(1);
WiFi.forceSleepWake();
delay(1);

Source: GitHub

That also works, I tested it December 2020. Thanks to Erik Bakke for finding it. It's a bit more clean than another Deep Sleep boot with the modem enabled. Igrr and I both struggled to find a way to wake the modem, and Erik mixed the magic sauce. Hopefully it still works today with the changes to the core WiFi files.

1
  • This is not really an answer...
    – Coder9390
    Commented Jul 23, 2021 at 0:43
2

Yes, you understood correctly; after using ESP.deepSleep(n, WAKE_RF_DISABLED) to disable WiFi, the most reliable method to re-enable it is to call ESP.deepSleep(1, WAKE_RF_DEFAULT). Then connect to WiFi on the next wake (which should be in 1 second). Apparently, WAKE_RFCAL and WAKE_NO_RFCAL also result in WiFi working.

A cheap way to approach this, is to normally sleep with WAKE_RF_DISABLED but when your WiFi connection fails, sleep with WAKE_RF_DEFAULT to make the next connection more likely to be successful.

If you want a more elegant, but slightly more complex solution, you can use the RTC memory to store the known WiFi state when you sleep; so when you sleep with WAKE_RF_DISABLED, you'll know that you'll have to reset with WAKE_RF_DEFAULT before trying to connect. And, when you wake again, you'll know the WiFi has been enabled.

As mentioned in another answer, after using WAKE_RF_DISABLED, you could call WiFi.forceSleepBegin() and then immediately call WiFi.forceSleepWake() to try to bring the WiFi back up without resetting. While I have actually found this to work, sadly it seems to be unreliable. Seems like it might work while on USB power, but when changing to another power source, it stops working. I'm not sure why. When using that approach, sometimes the MCU will consume only 40 mA when it's supposed to consume 70 mA with WiFi on, so this suggests to me that the WiFi doesn't properly initialize.

All that being said, I would suggest that using WAKE_RF_DISABLED is quite extreme. Like in your original solution, I have found that you can avoid using WAKE_RF_DISABLED altogether if you call WiFi.forceSleepBegin() immediately when the device starts (i.e. at the top of your setup() function), and then WiFi.forceSleepWake() when you want to use WiFi. When the device starts, there is only perhaps 50-100ms when the device is using 70mA before WiFi is turned off. This is probably acceptable for most low power designs.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.