[GH-ISSUE #1490] ESP32 cannot connect to WiFi: wm:[1] No Credentials are Saved, skipping connect #1270

Closed
opened 2026-02-28 01:29:21 +03:00 by kerem · 2 comments
Owner

Originally created by @Erriez on GitHub (Sep 12, 2022).
Original GitHub issue: https://github.com/tzapu/WiFiManager/issues/1490

Basic Infos

Hardware

WiFimanager Branch/Release: master hash 7bdcfd

Esp8266/Esp32: ESP32
Hardware: ESP32 Devkit v1
Core Version: 2.04

Problem description

The debug output shows sometimes No Credentials are Saved, skipping connect on ESP32 and cannot connect to WiFi:

WiFi connect...
SSID: ⸮⸮?
*wm:[1] AutoConnect 
*wm:[1] No Credentials are Saved, skipping connect 
*wm:[2] enableConfigPortal: FALSE, skipping  
Failed. Retry in 10s...

Root cause

Reproducible on ESP32 only.
Changing hostname requires a WiFi reset as described in Espressif documentation:

https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/network/esp_netif.html?highlight=hostname#_CPPv422esp_netif_set_hostnameP11esp_netif_tPKc

esp_err_t esp_netif_set_hostname(esp_netif_t *esp_netif, const char *hostname)

Set the hostname of an interface.
The configured hostname overrides the default configuration value CONFIG_LWIP_LOCAL_HOSTNAME. Please note 
that when the hostname is altered after interface started/connected the changes would only be reflected once the
interface restarts/reconnects

This if statement is incorrect: github.com/tzapu/WiFiManager@7bdcfd501e/WiFiManager.cpp (L285)
should be if (_hostname != ""), otherwise the WiFi is always forced to WIFI_OFF.

When WiFi mode is not in WIFI_MODE_STA, the following code in WiFiManager.cpp functions esp_wifi_get_config() returns garbage (not null terminated string) to determine saved WiFi credentials by reading SSID. In this case the message No Credentials are Saved, skipping connect is printed and cannot connect to WiFi:

wifi_config_t conf;
int err = esp_wifi_get_config(WIFI_IF_STA, &conf);

Settings in IDE

Module: NodeMCU-32S

Additional libraries:

Sketch testcase

#include <EEPROM.h>
#include <WiFiManager.h>        // https://github.com/tzapu/WiFiManager master 7bdcfd

#define LED_PIN             LED_BUILTIN

#define WM_TITLE            "WiFiManager"
#define WM_AP_NAME          "apname"
#define WM_AP_PASSWORD      "changeme"
#define WM_CONNECT_TIMEOUT  20
#define WM_AUTO_CP          false
#define WM_DEBUG            true

#define EEPROM_SIZE                     512
#define DOUBLE_RESET_TIME_SEC           2
#define DOUBLE_RESET_EEPROM_ADDRESS     0x0100
#define DOUBLE_RESET_DETECT_FLAG_SET    0xD0D01234
#define DOUBLE_RESET_DETECT_FLAG_CLEAR  0xD0D04321

bool saveConfig = false;
bool saveParams = false;
bool doubleResetCheck = true;


bool isDoubleReset()
{
    uint32_t value;

    EEPROM.get(DOUBLE_RESET_EEPROM_ADDRESS, value);

    Serial.print(F("Read double reset flag: "));
    if (value == DOUBLE_RESET_DETECT_FLAG_SET) {
        Serial.println(F("SET"));
        return true;
    } else if (value == DOUBLE_RESET_DETECT_FLAG_CLEAR) {
        Serial.println(F("CLEAR"));
        return false;
    } else {
        Serial.println(F("INVALID"));
        return false;
    }
}

void doubleResetWrite(uint32_t value)
{
    uint32_t oldValue;
    
    EEPROM.get(DOUBLE_RESET_EEPROM_ADDRESS, oldValue);

    if (oldValue != value) {
        Serial.print(F("Write double reset flag: "));
        if (value == DOUBLE_RESET_DETECT_FLAG_SET) {
            Serial.println(F("SET"));
        } else if (value == DOUBLE_RESET_DETECT_FLAG_CLEAR) {
            Serial.println(F("CLEAR"));
            doubleResetCheck = false;
        } else {
            Serial.println(F("INVALID"));
            return;
        }

        EEPROM.put(DOUBLE_RESET_EEPROM_ADDRESS, value);
        EEPROM.commit();
    }
}

void doubleResetLoop()
{
    if (doubleResetCheck && (millis() > (DOUBLE_RESET_TIME_SEC * 1000))) {
        // Clear flag
        doubleResetWrite(DOUBLE_RESET_DETECT_FLAG_CLEAR);
    }
}

void espRestart()
{
    Serial.println(F("Restarting..."));
    delay(2000);
    ESP.restart();
    delay(5000);
}

void saveConfigCallback () 
{
    Serial.println("saveConfigCallback()");
    saveConfig = true;
}

void saveParamsCallback()
{
    Serial.println(F("saveParamsCallback()"));

    // Save parameters when exiting config portal
    saveParams = true;
}

void startWiFiConfigPortal()
{
    WiFiManager wm;

    // Start WiFi config portal
    Serial.println(F("Starting config portal (AP)..."));

    // Set debug
    wm.setDebugOutput(WM_DEBUG);

    // Set title config protal
    wm.setTitle(WM_TITLE);

    // Set config save callback
    //wm.setSaveConfigCallback(saveConfigCallback);

    // Set param save callback
    wm.setSaveParamsCallback(saveParamsCallback);

    // Always save parameters, even when WiFi connect failed
    wm.setBreakAfterConfig(true);

    // Automatically connect using saved credentials,
    // if connection fails, it starts an access point with the specified name ( "AutoConnectAP"),
    // if empty will auto generate SSID, if password is blank it will be anonymous AP (wm.autoConnect())
    // then goes into a blocking loop awaiting configuration and will return success result

    // Ignore false return value when aborting config portal
    (void)wm.startConfigPortal(WM_AP_NAME, WM_AP_PASSWORD);
}

void wifiConnect()
{
    WiFiManager wm;

    // Connect to WiFi
    Serial.println(F("WiFi connect..."));

    // Set debug output
    wm.setDebugOutput(WM_DEBUG);

    // Disable auto start config portal on WiFi connect failure
    wm.setEnableConfigPortal(WM_AUTO_CP);
  
    // Set connect timeout
    wm.setConnectTimeout(WM_CONNECT_TIMEOUT);

    //wm.setHostname("test1st");

//    // Make sure the ESP32 is in STA mode
//    unsigned long tLast = millis();
//    if (WiFi.getMode() != WIFI_MODE_STA) {
//        WiFi.mode(WIFI_STA);
//
//        while (WiFi.getMode() != WIFI_MODE_STA) {
//            delay(1);
//        }
//    }
//
//    Serial.print(F("Changing to STA mode: "));
//    Serial.print(millis() - tLast);
//    Serial.println(F("ms"));

    wifiPrintStatus();

//    // Connect to WiFi access point
//    while (!wm.autoConnect()) {
//        Serial.println(F("Failed. Retry in 10s..."));
//        delay(10000);
//        Serial.print(F("WiFi connect..."));
//    }

    //wm.setHostname("test2nd");

    // Connect to WiFi access point
    while (!wm.autoConnect()) {
        Serial.println(F("Failed. Retry in 10s..."));
        delay(10000);
        Serial.print(F("WiFi connect..."));
    }

    // WiFi connected
    Serial.println(F("Connected"));
}

void wifiConnect2()
{
    Serial.println(F("Connecting to WiFi"));
    WiFi.mode(WIFI_STA);
    WiFi.persistent(true);
    WiFi.begin();
    while (WiFi.status() != WL_CONNECTED) {
        delay(100);
    }
    Serial.println(WiFi.localIP());
}

void wifiDisconnect()
{
    WiFi.mode(WIFI_OFF);
}

void wifiPrintStatus()
{
    Serial.print(F("WiFi mode: "));
    switch (WiFi.getMode()) {
        case WIFI_MODE_STA:
            Serial.println(F("STA"));
            break;
        case WIFI_MODE_AP:
            Serial.println(F("AP"));
            break;
        case WIFI_MODE_APSTA:
            Serial.println(F("APSTA"));
            break;
        default:
            Serial.println(F("ERROR"));
    }

    Serial.print(F("WiFi status: ")); 
    if (WiFi.status() == WL_CONNECTED) {
        Serial.println(F("WiFi connected"));
        Serial.print(F("Local IP: ")); 
        Serial.println(WiFi.localIP());
    } else {
        Serial.println(F("WiFi not connected"));
    }

    wifi_config_t conf;
    Serial.print(F("esp_wifi_get_config(): "));
    Serial.println(esp_wifi_get_config(WIFI_IF_STA, &conf));
    Serial.print(F("SSID: "));
    Serial.println(String(reinterpret_cast<const char*>(conf.sta.ssid)));
}

void setup() 
{
    // Initialize LED
    pinMode(LED_PIN, OUTPUT);
    digitalWrite(LED_PIN, HIGH);

    // Initialize serial
    Serial.begin(115200); 
    Serial.println(F("\nErriez double reset example"));

    // Initialize EEPROM
    if (!EEPROM.begin(EEPROM_SIZE)) {
        Serial.println("EEPROM init error");
        espRestart();
    }

    // Detect double reset
    if (isDoubleReset()) {
        // Clear double reset flag
        doubleResetWrite(DOUBLE_RESET_DETECT_FLAG_CLEAR);
    
        // Start AP config
        startWiFiConfigPortal();

        // Restart ESP
        espRestart();
    }

    // Set double reset flag
    doubleResetWrite(DOUBLE_RESET_DETECT_FLAG_SET);

    // Connect to WiFi
    wifiConnect();

    digitalWrite(LED_PIN, LOW);
}

void loop() 
{
    doubleResetLoop();

    wifiPrintStatus();

    digitalWrite(LED_PIN, HIGH);
    delay(2000);
    digitalWrite(LED_PIN, LOW);
    delay(2000);

    wifiDisconnect();
}
Originally created by @Erriez on GitHub (Sep 12, 2022). Original GitHub issue: https://github.com/tzapu/WiFiManager/issues/1490 ### Basic Infos #### Hardware WiFimanager Branch/Release: `master` hash `7bdcfd` Esp8266/Esp32: ESP32 Hardware: ESP32 Devkit v1 Core Version: 2.04 ### Problem description The debug output shows sometimes `No Credentials are Saved, skipping connect ` on ESP32 and cannot connect to WiFi: ``` WiFi connect... SSID: ⸮⸮? *wm:[1] AutoConnect *wm:[1] No Credentials are Saved, skipping connect *wm:[2] enableConfigPortal: FALSE, skipping Failed. Retry in 10s... ``` ### Root cause Reproducible on ESP32 only. Changing hostname requires a WiFi reset as described in Espressif documentation: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/network/esp_netif.html?highlight=hostname#_CPPv422esp_netif_set_hostnameP11esp_netif_tPKc ``` esp_err_t esp_netif_set_hostname(esp_netif_t *esp_netif, const char *hostname) Set the hostname of an interface. The configured hostname overrides the default configuration value CONFIG_LWIP_LOCAL_HOSTNAME. Please note that when the hostname is altered after interface started/connected the changes would only be reflected once the interface restarts/reconnects ``` This if statement is incorrect: https://github.com/tzapu/WiFiManager/blob/7bdcfd501eb18d6c48be37f8608de775e44a90ae/WiFiManager.cpp#L285 should be `if (_hostname != "")`, otherwise the WiFi is always forced to `WIFI_OFF`. When WiFi mode is not in `WIFI_MODE_STA`, the following code in `WiFiManager.cpp` functions `esp_wifi_get_config()` returns garbage (not null terminated string) to determine saved WiFi credentials by reading SSID. In this case the message `No Credentials are Saved, skipping connect` is printed and cannot connect to WiFi: ```c++ wifi_config_t conf; int err = esp_wifi_get_config(WIFI_IF_STA, &conf); ``` ### Settings in IDE Module: NodeMCU-32S Additional libraries: ### Sketch testcase ```cpp #include <EEPROM.h> #include <WiFiManager.h> // https://github.com/tzapu/WiFiManager master 7bdcfd #define LED_PIN LED_BUILTIN #define WM_TITLE "WiFiManager" #define WM_AP_NAME "apname" #define WM_AP_PASSWORD "changeme" #define WM_CONNECT_TIMEOUT 20 #define WM_AUTO_CP false #define WM_DEBUG true #define EEPROM_SIZE 512 #define DOUBLE_RESET_TIME_SEC 2 #define DOUBLE_RESET_EEPROM_ADDRESS 0x0100 #define DOUBLE_RESET_DETECT_FLAG_SET 0xD0D01234 #define DOUBLE_RESET_DETECT_FLAG_CLEAR 0xD0D04321 bool saveConfig = false; bool saveParams = false; bool doubleResetCheck = true; bool isDoubleReset() { uint32_t value; EEPROM.get(DOUBLE_RESET_EEPROM_ADDRESS, value); Serial.print(F("Read double reset flag: ")); if (value == DOUBLE_RESET_DETECT_FLAG_SET) { Serial.println(F("SET")); return true; } else if (value == DOUBLE_RESET_DETECT_FLAG_CLEAR) { Serial.println(F("CLEAR")); return false; } else { Serial.println(F("INVALID")); return false; } } void doubleResetWrite(uint32_t value) { uint32_t oldValue; EEPROM.get(DOUBLE_RESET_EEPROM_ADDRESS, oldValue); if (oldValue != value) { Serial.print(F("Write double reset flag: ")); if (value == DOUBLE_RESET_DETECT_FLAG_SET) { Serial.println(F("SET")); } else if (value == DOUBLE_RESET_DETECT_FLAG_CLEAR) { Serial.println(F("CLEAR")); doubleResetCheck = false; } else { Serial.println(F("INVALID")); return; } EEPROM.put(DOUBLE_RESET_EEPROM_ADDRESS, value); EEPROM.commit(); } } void doubleResetLoop() { if (doubleResetCheck && (millis() > (DOUBLE_RESET_TIME_SEC * 1000))) { // Clear flag doubleResetWrite(DOUBLE_RESET_DETECT_FLAG_CLEAR); } } void espRestart() { Serial.println(F("Restarting...")); delay(2000); ESP.restart(); delay(5000); } void saveConfigCallback () { Serial.println("saveConfigCallback()"); saveConfig = true; } void saveParamsCallback() { Serial.println(F("saveParamsCallback()")); // Save parameters when exiting config portal saveParams = true; } void startWiFiConfigPortal() { WiFiManager wm; // Start WiFi config portal Serial.println(F("Starting config portal (AP)...")); // Set debug wm.setDebugOutput(WM_DEBUG); // Set title config protal wm.setTitle(WM_TITLE); // Set config save callback //wm.setSaveConfigCallback(saveConfigCallback); // Set param save callback wm.setSaveParamsCallback(saveParamsCallback); // Always save parameters, even when WiFi connect failed wm.setBreakAfterConfig(true); // Automatically connect using saved credentials, // if connection fails, it starts an access point with the specified name ( "AutoConnectAP"), // if empty will auto generate SSID, if password is blank it will be anonymous AP (wm.autoConnect()) // then goes into a blocking loop awaiting configuration and will return success result // Ignore false return value when aborting config portal (void)wm.startConfigPortal(WM_AP_NAME, WM_AP_PASSWORD); } void wifiConnect() { WiFiManager wm; // Connect to WiFi Serial.println(F("WiFi connect...")); // Set debug output wm.setDebugOutput(WM_DEBUG); // Disable auto start config portal on WiFi connect failure wm.setEnableConfigPortal(WM_AUTO_CP); // Set connect timeout wm.setConnectTimeout(WM_CONNECT_TIMEOUT); //wm.setHostname("test1st"); // // Make sure the ESP32 is in STA mode // unsigned long tLast = millis(); // if (WiFi.getMode() != WIFI_MODE_STA) { // WiFi.mode(WIFI_STA); // // while (WiFi.getMode() != WIFI_MODE_STA) { // delay(1); // } // } // // Serial.print(F("Changing to STA mode: ")); // Serial.print(millis() - tLast); // Serial.println(F("ms")); wifiPrintStatus(); // // Connect to WiFi access point // while (!wm.autoConnect()) { // Serial.println(F("Failed. Retry in 10s...")); // delay(10000); // Serial.print(F("WiFi connect...")); // } //wm.setHostname("test2nd"); // Connect to WiFi access point while (!wm.autoConnect()) { Serial.println(F("Failed. Retry in 10s...")); delay(10000); Serial.print(F("WiFi connect...")); } // WiFi connected Serial.println(F("Connected")); } void wifiConnect2() { Serial.println(F("Connecting to WiFi")); WiFi.mode(WIFI_STA); WiFi.persistent(true); WiFi.begin(); while (WiFi.status() != WL_CONNECTED) { delay(100); } Serial.println(WiFi.localIP()); } void wifiDisconnect() { WiFi.mode(WIFI_OFF); } void wifiPrintStatus() { Serial.print(F("WiFi mode: ")); switch (WiFi.getMode()) { case WIFI_MODE_STA: Serial.println(F("STA")); break; case WIFI_MODE_AP: Serial.println(F("AP")); break; case WIFI_MODE_APSTA: Serial.println(F("APSTA")); break; default: Serial.println(F("ERROR")); } Serial.print(F("WiFi status: ")); if (WiFi.status() == WL_CONNECTED) { Serial.println(F("WiFi connected")); Serial.print(F("Local IP: ")); Serial.println(WiFi.localIP()); } else { Serial.println(F("WiFi not connected")); } wifi_config_t conf; Serial.print(F("esp_wifi_get_config(): ")); Serial.println(esp_wifi_get_config(WIFI_IF_STA, &conf)); Serial.print(F("SSID: ")); Serial.println(String(reinterpret_cast<const char*>(conf.sta.ssid))); } void setup() { // Initialize LED pinMode(LED_PIN, OUTPUT); digitalWrite(LED_PIN, HIGH); // Initialize serial Serial.begin(115200); Serial.println(F("\nErriez double reset example")); // Initialize EEPROM if (!EEPROM.begin(EEPROM_SIZE)) { Serial.println("EEPROM init error"); espRestart(); } // Detect double reset if (isDoubleReset()) { // Clear double reset flag doubleResetWrite(DOUBLE_RESET_DETECT_FLAG_CLEAR); // Start AP config startWiFiConfigPortal(); // Restart ESP espRestart(); } // Set double reset flag doubleResetWrite(DOUBLE_RESET_DETECT_FLAG_SET); // Connect to WiFi wifiConnect(); digitalWrite(LED_PIN, LOW); } void loop() { doubleResetLoop(); wifiPrintStatus(); digitalWrite(LED_PIN, HIGH); delay(2000); digitalWrite(LED_PIN, LOW); delay(2000); wifiDisconnect(); } ```
kerem 2026-02-28 01:29:21 +03:00
  • closed this issue
  • added the
    bug
    label
Author
Owner

@Erriez commented on GitHub (Sep 12, 2022):

Pull request #1491 is a proposal for a fix with minimum changes.

<!-- gh-comment-id:1243683153 --> @Erriez commented on GitHub (Sep 12, 2022): Pull request #1491 is a proposal for a fix with minimum changes.
Author
Owner

@tablatronix commented on GitHub (Sep 12, 2022):

Thanks!

<!-- gh-comment-id:1244037194 --> @tablatronix commented on GitHub (Sep 12, 2022): Thanks!
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/WiFiManager#1270
No description provided.