WiFiManager
WiFiManager copied to clipboard
OTA update forgets wifi credentials
Basic Infos
Hardware
WiFimanager Branch/Release: Master
Esp8266/Esp32: Esp8266
Hardware: ESP-07S
Core Version: 3.0.2
Description
After an OTA update, the wifi credentials are forgotten. This is odd as I've seen searching through the web that many users have complained about the opposite, and wanted to actually erase wifi creds after an update. Maybe there's a way to store and load the credentials from SPIFFS?
Settings in IDE
Module: Generic ESP8266 module
Additional libraries:
Sketch
#include <ESP8266WiFi.h>
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <ESP8266HTTPClient.h>
#include <WiFiManager.h> //https://github.com/tzapu/WiFiManager
#include <ArduinoJson.h>
#define HTTP_OTA
#ifdef HTTP_OTA
#include <ESP8266httpUpdate.h>
#define HTTP_OTA_ADDRESS "dummy_address" // Address of OTA update server
#define HTTP_OTA_PATH "path" // Path to update firmware
#define HTTP_OTA_PORT port_number // Port of update server
// Name of firmware
#define HTTP_OTA_VERSION String(__FILE__).substring(String(__FILE__).lastIndexOf('/')+1) + ".generic"
#endif
void setup() {
/* usual WiFiManager setup here */
WiFi.mode(WIFI_STA); // explicitly set mode, esp defaults to STA+AP
// put your setup code here, to run once:
Serial.begin(115200);
// WiFi.mode(WiFi_STA); // it is a good practice to make sure your code sets wifi mode how you want it.
//WiFiManager, Local intialization. Once its business is done, there is no need to keep it around
WiFiManager wm;
//reset settings - wipe credentials for testing
//wm.resetSettings();
// 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
bool res;
// res = wm.autoConnect(); // auto generated AP name from chipid
// res = wm.autoConnect("AutoConnectAP"); // anonymous ap
res = wm.autoConnect("AutoConnectAP","password"); // password protected ap
if(!res) {
Serial.println("Failed to connect");
// ESP.restart();
}
else {
//if you get here you have connected to the WiFi
Serial.println("connected...yeey :)");
}
}
int updateOTACheckTimer = 28;
void loop() {
updateOTACheckTimer++;
if(updateOTACheckTimer > 30){
updateOTACheckTimer = 0;
doOTAUpdate();
}
}
void doOTAUpdate(){
#ifdef HTTP_OTA
WiFiClient client;
// Check server for firmware updates
Serial.print("Checking for firmware updates from server http://");
Serial.print(HTTP_OTA_ADDRESS);
Serial.print(":");
Serial.print(HTTP_OTA_PORT);
Serial.println(HTTP_OTA_PATH);
switch(ESPhttpUpdate.update(client, HTTP_OTA_ADDRESS, HTTP_OTA_PORT, HTTP_OTA_PATH, HTTP_OTA_VERSION)) {
case HTTP_UPDATE_FAILED:
Serial.printf("HTTP update failed: Error (%d): %s\n", ESPhttpUpdate.getLastError(), ESPhttpUpdate.getLastErrorString().c_str());
break;
case HTTP_UPDATE_NO_UPDATES:
Serial.println(F("No updates"));
break;
case HTTP_UPDATE_OK:
Serial.println(F("Update OK"));
break;
}
#endif
}
Debug Messages
...
11:42:37.471 -> connected...yeey :)
11:42:37.506 -> *WM: [3] unloading
11:42:45.716 -> Checking for firmware updates from server dummyserver.com
11:43:00.504 -> H!⸮⸮⸮⸮@H⸮⸮⸮f⸮⸮Serial Online
11:43:09.888 -> *WM: [1] AutoConnect
11:43:09.888 -> *WM: [1] No Credentials are Saved, skipping connect
11:43:09.957 -> *WM: [2] Starting Config Portal
11:43:09.994 -> *WM: [2] AccessPoint set password is VALID
11:43:10.027 -> *WM: [1] password
11:43:10.062 -> *WM: [3] WIFI station disconnect
11:43:10.096 -> *WM: [3] WiFi station enable
11:43:10.129 -> *WM: [2] Disabling STA
11:43:10.162 -> *WM: [2] Enabling AP
11:43:10.200 -> *WM: [1] StartAP with SSID: AutoConnectAP
11:43:11.488 -> *WM: [1] SoftAP Configuration
11:43:11.526 -> *WM: [1] --------------------
11:43:11.562 -> *WM: [1] ssid: AutoConnectAP
11:43:11.596 -> *WM: [1] password: password
...
I've managed to have something working by writing and loading from the SPIFFS:
char userSSID[32] = "null";
char userwifiPasswd[32];
void setupSpiffs(){
//clean FS, for testing
// SPIFFS.format();
//read configuration from FS json
Serial.println("mounting FS...");
if (SPIFFS.begin()) {
Serial.println("mounted file system");
if (SPIFFS.exists("/config.json")) {
//file exists, reading and loading
Serial.println("reading config file");
File configFile = SPIFFS.open("/config.json", "r");
if (configFile) {
Serial.println("opened config file");
size_t size = configFile.size();
// Allocate a buffer to store contents of the file.
std::unique_ptr<char[]> buf(new char[size]);
configFile.readBytes(buf.get(), size);
DynamicJsonDocument jsonDoc(512);
auto deserializeError = deserializeJson(jsonDoc, buf.get());
serializeJsonPretty(jsonDoc, Serial);
if (!deserializeError && jsonDoc.containsKey("wifi_ssid") && jsonDoc.containsKey("wifi_pass")) {
Serial.println("\nparsed json");
strcpy(userSSID, jsonDoc["wifi_ssid"]);
strcpy(userwifiPasswd, jsonDoc["wifi_pass"]);
} else {
if(deserializeError) Serial.println("deserializeError");
Serial.println("failed to load json config");
}
}
}
} else {
Serial.println("failed to mount FS");
}
//end read
}
void setup(){
Serial.begin(115200);
setupSpiffs();
if((strcmp(userSSID, "null")) != 0){
Serial.println("Loading stored WiFi credentials...");
WiFi.begin(userSSID, userwifiPasswd);
}
else{
<same setup() as before here but add the following lines:>
//save the custom parameters to FS
if (shouldSaveConfig) {
Serial.println("saving config");
DynamicJsonDocument doc(512);
doc["wifi_ssid"] = WiFi.SSID();
doc["wifi_pass"] = WiFi.psk();
File configFile = SPIFFS.open("/config.json", "w");
if (!configFile) {
Serial.println("failed to open config file for writing");
}
serializeJsonPretty(doc, Serial);
serializeJson(doc, configFile);
configFile.close();
//end save
}
}
void loop(){
...
}
Maybe there could be a feature in WiFiManager so that you could load/store wifi credentials to the SPIFFS?
I have seen this happen on some esps and some libs, no idea what causes it probably bad memory guards in ota or cross versions. This really should not happen anymore as the sdk has not changed
I've noticed this issue on my sketch (ESP8266 based), it's really annoying. Will be great to get it fixed.