Using the new Arduino IDE for ESP8266 and found bugs, report them here

Moderator: igrr

User avatar
By Daledj
#91902 I have discovered that WiFi will not connect in a specific circumstance using core platform 3.0.1. This may also occur in prior versions, not sure.

This occurs all the time on a LOLIN D1 mini Pro 2.0.0 board.

The circumstance is as follows: If a sketch is coded to connect to WiFi and uses deepsleep and only connects to WiFi on some invocations of the sketch, after connecting once and then sleeping and waking for a session that does not connect, no future connections are possible until the board is powered off and on again.

I have a sketch that makes water level measurements with a battery powered device, but only wants to report the measurements occasionally, not on every wakeup. So the sketch does not use WiFi on sessions where only measurements are taken (to save battery life) and recorded locally on and SD card. After one successful session and then one session without using WiFi, no additional WiFi connections are successful.

To demonstrate this, I have made a slight modification to the supplied example provided with 3.0.1 called WiFIShutDown. I modified the sketch to bring up a WiFi connection only on about half of the sessions (using ESP.random()). After the first successful connection, no future connections succeed.

Note: If you replace the ESP.deepsleep() with a delay() and ESP.restart(), the problem goes away, so this has something to do with the WiFi internal state across deepsleep().

The code for this follows.
Code: Select all// Demonstrate the use of WiFi.shutdown() and WiFi.resumeFromShutdown()
// Released to public domain

// Modified to demonstrate bug in core 3.0.1 causing WiFi to fail.

// Current on WEMOS D1 mini (including: LDO, usbserial chip):
// ~85mA during normal operations
// ~30mA during wifi shutdown
//  ~5mA during deepsleep

#ifndef STASSID
#define STASSID "SSID"
#define STAPSK "PASSWORD"
#endif

#ifndef RTC_USER_DATA_SLOT_WIFI_STATE
#define RTC_USER_DATA_SLOT_WIFI_STATE 33u // Data stored in first 32 blocks overwritten by OTA updates
#endif

#include <ESP8266WiFi.h>
#include <include/WiFiState.h> // WiFiState structure details

WiFiState state; // Size of this is 152 bytes

const char* ssid = STASSID;
const char* password = STAPSK;

void setup() {
  Serial.begin(74880);
  //Serial.setDebugOutput(true);  // If you need debug output
  Serial.println("Trying to resume WiFi connection...");

  // May be necessary after deepSleep. Otherwise you may get "error: pll_cal exceeds 2ms!!!" when trying to connect
  delay(1);

  // ---
  // Here you can do whatever you need to do that doesn't need a WiFi connection.
  // ---

  ESP.rtcUserMemoryRead(RTC_USER_DATA_SLOT_WIFI_STATE, reinterpret_cast<uint32_t *>(&state), sizeof(state));
  unsigned long start = millis();
  if (ESP.random() & 01) { // Modification to demonstrate bug where WiFi fails after first successful connection.

    if (!WiFi.resumeFromShutdown(state)
        || (WiFi.waitForConnectResult(10000) != WL_CONNECTED)) {
      Serial.println("Cannot resume WiFi connection, connecting via begin...");
      WiFi.persistent(false);

      if (!WiFi.mode(WIFI_STA)
          || !WiFi.begin(ssid, password)
          || (WiFi.waitForConnectResult(10000) != WL_CONNECTED)) {
        WiFi.mode(WIFI_OFF);
        Serial.println("Cannot connect!");
        Serial.flush();
        ESP.deepSleep(10e6, RF_DISABLED); // 10 seconds
        return;
      }
    }

    unsigned long duration = millis() - start;
    Serial.printf("Duration: %f", duration * 0.001);
    Serial.println();

    // ---
    // Here you can do whatever you need to do that needs a WiFi connection.
    // ---

    WiFi.shutdown(state);
  } else {
    Serial.println("Skipped WiFi this loop");
  }
  ESP.rtcUserMemoryWrite(RTC_USER_DATA_SLOT_WIFI_STATE, reinterpret_cast<uint32_t *>(&state), sizeof(state));

  // ---
  // Here you can do whatever you need to do that doesn't need a WiFi connection anymore.
  // ---
  delay(2000);
  Serial.println("Done.");
  Serial.flush();
  ESP.deepSleep(10e6, RF_DISABLED);  // 10 seconds
}

void loop() {
  // Nothing to do here.
}