khoih-prog / ESP_WiFiManager

This is an ESP32 / ESP8266 WiFi Connection Manager with fallback web configuration portal. Use this library for configuring ESP32 (including ESP32-S2 and ESP32-C3), ESP8266 modules' WiFi, etc. Credentials at runtime. You can also specify static DNS servers, personalized HostName, fixed or random AP WiFi channel. With examples supporting ArduinoJson
MIT License
374 stars 97 forks source link

Freeze on Deep Sleep wakup? #57

Closed bit4man closed 3 years ago

bit4man commented 3 years ago

Describe the bug

I have a simple test sketch testing a setup with a PIR event to wake an ESP8266 (NodeMCU) up after deep-sleep:

#if !( defined(ESP8266) )
   #error This code is intended to run on ESP8266 platform! Please check your Tools->Board setting.
#endif
#include <ESP_WiFiManager.h>              //https://github.com/khoih-prog/ESP_WiFiManager

#define NB_TRYWIFI 10
#define PIR D1
#define _WIFIMGR_LOGLEVEL_    3  // 0-4 where 4 is the highest verbosity level

unsigned long oldmillis;

WiFiClient espClient;

void setup() {
  unsigned long _start = millis();
  Serial.begin(115200);
  while (!Serial); delay(200);

  Serial.println(""); Serial.print("Startup Reason: "); Serial.println(ESP.getResetReason());

  pinMode(PIR, INPUT);
  oldmillis = millis();

  Serial.print(F("\nStarting AutoConnect_ESP8266_minimal on ")); Serial.println(ARDUINO_BOARD); 
  Serial.println(ESP_WIFIMANAGER_VERSION);
  ESP_WiFiManager ESP_wifiManager("AutoConnectAP");
  ESP_wifiManager.setDebugOutput(true);
  ESP_wifiManager.setConfigPortalTimeout(30); // Timeout after 30 seconds
  ESP_wifiManager.setConnectTimeout(10);
  ESP_wifiManager.autoConnect("AutoConnectAP");
  unsigned int _try = 0;

  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(500);
    _try++;
    if (_try >= NB_TRYWIFI) {
      Serial.println("Unable to connect Wifi - going to sleep");
      ESP.deepSleep(0);
    }
  } 
  if (WiFi.status() == WL_CONNECTED) { 
      Serial.print(F("Connected. Local IP: ")); 
      Serial.println(WiFi.localIP());
  } else { 
    Serial.println(ESP_wifiManager.getStatus(WiFi.status())); 
  }

  Serial.print("Time to wakeup: ");
  Serial.print(millis()-_start); 
  Serial.println("ms");
}

void loop() {
  unsigned long m = millis();
  static unsigned long mold = m;
  if (m > mold+500) {
    Serial.print("PIR is: ");
    Serial.println(digitalRead(PIR));
    mold = m;
  }
  if (digitalRead(PIR)==1) oldmillis=m; // Reset - only count when there's no signal
  if (millis() > oldmillis+10000) {
    Serial.println("Going to sleep after 10secs");
    delay(100);
    ESP.deepSleep(0);
  }
}

I can reproduce the problem without the PIR involved by simply connecting RST to D0 with a pullup resistor (10K). I then short the line with a switch pulling RST low, which causes the unit to reset.

When "config()" is resumed, things hang here:

16:08:56.270 -> Startup Reason: Deep-Sleep Wake
16:08:56.270 -> 
16:08:56.270 -> Starting AutoConnect_ESP8266_minimal on ESP8266_NODEMCU
16:08:56.270 -> ESP_WiFiManager v1.5.3

With the timeouts implemented it finally resumes.

Time to wakeup: 115055ms

If I hit the RST button on the NodeMCU, a bit randomly it will resume/connect within 800-1200ms and operate as expected. I've attempted setting the debug mode on the WiFiManager module but I do not see any output on the serial console. Please advice if there's a way I can provide better information.

Steps to Reproduce

Implement the above sketch, add a 10K resistor to RST and connect RST to D0. Have a switch or wire to pull RST to ground on demand.

Expected behavior

A full reconnect using the WiFiManager stored SSID and credentials with no timeout.

Actual behavior

See description.

Information

Please ensure to specify the following:

bit4man commented 3 years ago

I figured out what I did wrong with the DEBUG - moved the define up before the #include - here's the debug information:

17:30:03.174 -> Starting AutoConnect_ESP8266_minimal on ESP8266_NODEMCU
17:30:03.174 -> ESP_WiFiManager v1.5.3
17:30:03.174 -> [WM] RFC925 Hostname = mysleepdemo
17:30:03.207 -> [WM] 
17:30:03.207 -> AutoConnect using previously saved SSID/PW, but keep previous settings
17:30:03.273 -> [WM] Connect to previous WiFi using new IP parameters
17:30:03.273 -> [WM] Waiting WiFi connection with time out
17:30:13.271 -> [WM] Connection timed out
17:30:13.371 -> [WM] Connection result:  WL_DISCONNECTED
17:31:23.384 -> [WM] WiFi.waitForConnectResult Done
17:31:23.384 -> [WM] SET AP
17:31:23.483 -> [WM] Configuring AP SSID = AutoConnectAP
17:31:24.080 -> [WM] AP IP address = 192.168.4.1
17:31:24.080 -> [WM] HTTP server started
17:31:24.080 -> [WM] ESP_WiFiManager::startConfigPortal : Enter loop
17:31:53.555 -> [WM] Waiting WiFi connection with time out
17:31:57.957 -> [WM] Timed out connection result: WL_CONNECTED
17:31:57.957 -> Connected. Local IP: 192.168.18.91
17:31:57.957 -> Time to wakeup: 114974ms
17:31:57.957 -> [WM] freeing allocated params!

I didn't attempt to reconnect etc - just letting it time out. Notice that eventually it does connect to the configuration eventually after going into AP mode. I have a few tests where it jumps the AP mode and goes straight to the connection after the initial timeout.

I'm suspecting that the period between sleep mode and when the WiFi is attempted to be restarted is too short. Is that something that needs to be addressed?

bit4man commented 3 years ago

I can confirm that adding a delay(2000) before initializing ESP WiFiManager makes resuming after deep-sleep work. Not sure what status/feature isn't ready but there probably should be a test in the library?

khoih-prog commented 3 years ago

It's good that you partially figure out what's wrong with your code as this issue has nothing to do with the library.

Please do more research on Deep Sleep, and you can try the reliable SmartFarm_DeepSleep example in my other SmallProjects library.

I'm closing this issue as it's not a bug of this library.

Good Luck,

bit4man commented 3 years ago

Thanks for the link - but I'm not seeing how it uses deepsleep any different from my example. The code seems to be a lot more focused on where/how to save state - and if that's what you want me to learn, then indeed the ESP_WifiManager is not doing it wrong - but I doubt that's what you want me to see. This code basically reads from internal memory (RTC) that's kept stateful during shutdown to remember parameters - my simple setup doesn't have state data outside of what's in WiFi_Manager which does work when powering on "the first time".

So in my opinion this is an issue with how WiFiManager initializes and I only wanted to let you know about it. I have a work-around for now, so I'll move on.