Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WiFi config corrupted after multiple restarts #1054

Closed
rafaelmendes opened this issue Nov 19, 2015 · 43 comments
Closed

WiFi config corrupted after multiple restarts #1054

rafaelmendes opened this issue Nov 19, 2015 · 43 comments

Comments

@rafaelmendes
Copy link

Hi guys,

I am using an ESP12E to read a temperature sensor every minute and post the data to a webserver. The module reads the data from the sensor, post it and go into deepsleep for 60 seconds. My code works fine for some time (for some modules days, for other it takes weeks) but then the module starts to reset itself with no apparent reason. The weird part is that the MCU still works fine after that: if I upload a new code with no Wifi function (like blink led) the module works alright. However, if I use ANY Wifi function, the code runs up to the point where the function is called and then the module reboots, printing the following message:

Soft WDT reset

ctx: cont 
sp: 3ffef960 end: 3ffefce0 offset: 01b0

>>>stack>>>
3ffefb10:  00000002 4000410f 3ffefc64 40204555  
3ffefb20:  3fffc718 40004a3c 0000007d 3fff0ef0  
3ffefb30:  3fffc718 401016d0 00000378 40204555  
3ffefb40:  0000007d 4020f223 00000378 0000007f  
3ffefb50:  00001000 4020f2b9 3ffedef4 0000007f  
3ffefb60:  0000007d 0000006c 0007d000 3ffedef4  
3ffefb70:  ffffff00 ffffffff ffffffff ffffffff  
3ffefb80:  ffffffff ffffffff ffffffff 0000007f  
3ffefb90:  4020f6cd 3ffe8a60 00000001 3ffefc00  
3ffefba0:  00000001 3ffefc20 4020f7d3 3ffe8a60  
3ffefbb0:  00000001 3ffefc00 0000006c 3ffedde4  
3ffefbc0:  3ffedfb0 3ffefc61 00000001 4020f80a  
3ffefbd0:  3ffeea4c 3ffe854f 3ffe855c 00000000  
3ffefbe0:  3ffefc20 3ffe84c0 00000000 00000002  
3ffefbf0:  40202dd8 3ffefbfc 3ffeea4c 40202d61  
3ffefc00:  76676f6c 2e776569 2e6d6f63 00007262  
3ffefc10:  00000002 00000000 3ffefc20 402011f1 <
3ffefc20:  6f747461 6f747461 6f747461 3ffe8500  
3ffefc30:  3fff0e80 40106776 3ffefcb0 00000041  
3ffefc40:  3ffeeb34 30333531 3f003533 40204d12  
3ffefc50:  3fff0e20 00000041 3ffefcb0 40204d6a  
3ffefc60:  00000000 3ffe84d0 3ffefcb0 40204d9a  
3ffefc70:  00000004 00000000 00000001 3fffdc20  
3ffefc80:  40202c71 3ffefcb0 3ffee9c8 3ffeecb8  
3ffefc90:  3fffdc20 3ffee9f4 3ffeea4c 402029b3  
3ffefca0:  40203ae4 3ffee9f4 3ffee9f0 4020253d  
3ffefcb0:  00000000 00000000 00000000 402024fd  
3ffefcc0:  00000000 00000000 3ffeecb1 40204329  
3ffefcd0:  00000000 00000000 3ffeecc0 40100114  
<<<stack<<<

 ets Jan  8 2013,rst cause:2, boot mode:(3,6)

load 0x4010f000, len 1264, room 16
tail 0
chksum 0x42
csum 0x42
~ld

The same problem happened to five modules now. I am not sure if it is a hardware problem or a bug in my firmware.

I've been facing this problem for almost 2 months now. I first thought that there was some sort of memory leak causing it so I started to print the free heap available every time the module woke up from deepsleep. Even after the module was "bricked", the heap was still ok.

I ve got no ideas left to solve it, any help will be appreciated.

Thanks,
Rafael

@Links2004
Copy link
Collaborator

the Soft WDT was triggert that mean you have some while / for loop in you code what take to much time without calling delay.
when you post your code i may can give a better hint.

@rafaelmendes
Copy link
Author

Thanks for your reply.

I don't think that is the case since the code runs fine for a few days and then doesnt work anymore.

My code:

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <Wire.h>
#include <ArduinoJson.h>
#include <WString.h>
#include "Sensor.h"
#include "Web.h"

int hwid = 150050;
int LED = 4;

int sleep_time = 50000000;

// Auxiliary variables
String data_package;

// Server Info
char server_domain[] = "myserver.com";
int port = 80;

// OBJECTS
Web web; //initialize an instance of the class
Sensor sen; //initialize an instance of the class

void setup() {  
  Serial.begin(115200);
  // Input Pins Setup:
  pinMode(LED, OUTPUT);
  Wire.begin(14, 12);

  Serial.println("");
  Serial.print("Free heap:"); 
  Serial.println(ESP.getFreeHeap(),DEC);
}

void loop() {
  data_package = sen.getJsonPack();

  web.connectAp();

  if (web.checkApCon()) {
    web.connectServer(server_domain, port);
    delay(100);
    if (web.checkServerCon()) {
      web.post(data_package);
      web.connectSuccAlert();

    } else {
      web.connectServerErrorAlert();
    }

  } else {
    web.connectWifiErrorAlert();
  }

  delay(200);
  ESP.deepSleep(sleep_time, WAKE_RF_DEFAULT);
  delay(1000);

}

The module gets stuck in the connectAp() function (actually, in any other Wifi function that is called, but this happens to be the first one in this code):

void Web::connectAp() {

  int i = 1;
  WiFi.mode(WIFI_STA);

  WiFi.begin(id, pass);

  while ((WiFi.status() != WL_CONNECTED) && (i < 80)) {
    delay(100);
    yield();
    i++;
  }

@mlord
Copy link

mlord commented Nov 20, 2015

Does it behave any better if you take that "web.connectAp();" line out of loop() and instead just do it once at the end of setup() ?

I have similar code here, but not using "web" objects or deepsleep.

@rafaelmendes
Copy link
Author

I tried that, it didnt work :/

So, this is the "timeline" to summarize what the problem is and when it appears

  1. I upload the code above into an ESP12E module
  2. The module works fine for a few days (sometimes for weeks), posting the temperature data to the web server every minute.
  3. After that, the module stops working and starts rebooting and printing the message above.
  4. If I take the SAME module and upload the blink led example, it works fine
  5. if I take the SAME module and upload the WifiClient example, it keeps rebooting and printing the following message:
Connecting to myWifi

Soft WDT reset

ctx: cont
sp: 3ffef780 end: 3ffefb00 offset: 01b0

>>>stack>>>
3ffef930:  00000000 00000000 00000000 00000000
3ffef940:  00000002 4000410f 00000000 00000000  
3ffef950:  3fffc718 40004a3c 000003fd 3fff1018  
3ffef960:  3fffc718 40101e88 00000378 00000000  
3ffef970:  000003fd 4020e643 00000378 000003ff  
3ffef980:  00001000 4020e6d9 3ffedea4 000003ff  
3ffef990:  000003fd 00000041 003fd000 3ffedea4  
3ffef9a0:  ffffff00 ffffffff ffffffff ffffffff  
3ffef9b0:  ffffffff ffffffff ffffffff 000003ff  
3ffef9c0:  4020eaed 3ffe8a10 00000001 3ffefa30  
3ffef9d0:  00000001 3ffefa50 4020ebf3 3ffe8a10  
3ffef9e0:  00000001 3ffefa30 00000041 3ffedd94  
3ffef9f0:  3ffedf60 3ffefa91 00000001 4020ec2a  
3ffefa00:  3ffee984 3ffe8567 3ffe8574 00000000  
3ffefa10:  3ffefa50 00000000 00000000 00000000  
3ffefa20:  40202450 00000000 3ffee984 402023d9  
3ffefa30:  76676f6c 2e776569 2e6d6f63 00007262  
3ffefa40:  00000000 00000000 00000000 00000000  
3ffefa50:  6f747461 6f747461 6f747461 00000000  
3ffefa60:  3ffeeaa4 00000001 3ffe852b 402036fc  
3ffefa70:  3ffeeaa4 0000000d 3ffe8581 3ffeead8  
3ffefa80:  3ffe834c 0000000e 3ffeeaa4 40203295  
3ffefa90:  3ffe8500 00000000 3ffeeaa4 40203295  
3ffefaa0:  00000004 00000000 3ffeeaa4 402037d0  
3ffefab0:  402010ae 0000000a 3ffeeaa4 3ffeead8  
3ffefac0:  3ffe834c 3ffee984 3ffeeaa4 40202098  
3ffefad0:  00000000 00000000 00000000 00000000  
3ffefae0:  3fffdc20 00000000 3ffeead1 402033a6  
3ffefaf0:  00000000 00000000 3ffeeae0 40100114  
<<<stack<<<

 ets Jan  8 2013,rst cause:1, boot mode:(3,0)

load 0x4010f000, len 1264, room 16 
tail 0

chksum 0x42
csum 0x42
~ld

It seems like the MCU is alright, but when I call any Wifi function the code gets stuck in some sort of loop and the wdt resets the MCU. I have a few ideas of what is causing the problem, but I am not sure how to investigate them:

  1. Maybe it is related to the RTC somehow, since it appears only after the module being "on" for a long period. Maybe an overflow or something like that
  2. Hardware related? I mean, the RF part gets corrupted somehow

Thanks for your help

@igrr
Copy link
Member

igrr commented Nov 20, 2015

Could you please upload your sketch and .elf output file so I can analyse the stack trace for you?
Enable verbose compiler output in Arduino preferences to see the path of the output file.

@rafaelmendes
Copy link
Author

You can download the files from:

https://www.dropbox.com/s/sqv405zq991ei6k/firmware_v1_github.zip?dl=0

the serial output for this code is:

Soft WDT reset

ctx: cont 
sp: 3ffefb60 end: 3ffefe20 offset: 01b0

>>>stack>>>
3ffefd10:  3ffefd18 40216ac6 00000001 00000000  
3ffefd20:  00000002 4000410f 00000000 00000002  
3ffefd30:  3fffc718 40004a3c 000003fd 3fff0c30  
3ffefd40:  3fffc718 401016d0 00000378 00000001  
3ffefd50:  000003fd 4021485f 00000378 000003ff  
3ffefd60:  00001000 402148f5 3ffee0c4 000003ff  
3ffefd70:  000003fd 3ffeedf0 003fd000 3ffee0c4  
3ffefd80:  ffffff00 ffffffff ffffffff ffffffff  
3ffefd90:  ffffffff ffffffff ffffffff 000003ff  
3ffefda0:  4021479c 3ffeec1c 00000001 3fffdc20  
3ffefdb0:  00000001 402147ca 00000001 3fffdc20  
3ffefdc0:  40207505 3ffefdf0 3ffeeb98 4020a4b7  
3ffefdd0:  3fffdc20 3ffeebc4 3ffeec1c 40207208  
3ffefde0:  4020831c 3ffeebc4 3ffeebc0 40206e19  
3ffefdf0:  00000000 00000000 00000000 40206dd9  
3ffefe00:  00000000 00000000 3ffeede9 40208c35  
3ffefe10:  00000000 00000000 3ffeee00 40100114  
<<<stack<<<

 ets Jan  8 2013,rst cause:1, boot mode:(3,0)

load 0x4010f000, len 1264, room 16 
tail 0
chksum 0x42
csum 0x42
~ld

Free heap:43632

Let me know if you need anything else. I really appreaciate the help :)

@mlord
Copy link

mlord commented Nov 20, 2015

So, each time this happens, your module is essentially "bricked" w.r.t. Wifi.. no future sketches will work if they use WiFi (as best you can tell)?

So some persistent state is being changed after a while. Either a microseconds counter is overflowing in permanent storage, or a log file or DHCP lease file (or similar) is getting corrupted or running out of space.

Persistent state can be stored in EEPROM, and there are example sketches to examine/modify EEPROM storage. It can also be stored on the flash file system, in the 3M partition as well as the 1M partition. And the RTC has a tiny bit of storage too.

Without knowing much about this specific platform (only just started using it three weeks ago), those are areas I would consider poking around at, especially the flash file system.

@rafaelmendes
Copy link
Author

Interesting, I will take a look at these EEPROM scketches.

Another useful information: At some point, I was trying to "unbrick" the module and decided to upload the nodeMCU firmware (https://github.com/nodemcu/nodemcu-firmware) and give it a try. Interesting fact is that with the LUA-based firmware, the same "bricked" module worked fine when I tried to connect to a Wifi AP, with no reboots. When I switched back to this arduino-based firmware, the problem came back.

I guess that possibly relates to what you are saying about the memory partitions. Perhaps the LUA firmware was not using some corrupted part of memory that was being used by the arduino code.

food for thought...

@igrr
Copy link
Member

igrr commented Nov 20, 2015

Looking at the stack trace, WDT reset happens inside SDK functions. Call chain looks like this:

wifi_set_opmode > system_param_save_with_protect > wifi_param_save_protect_with_check

This is in line with your observation that some persistent corruption happens to the module configuration.
Looks like after a while some garbage gets written to the flash sector used by SDK for parameters storage. It appears that SDK routines are not robust enough to handle these errors, which leads to a crash.

@igrr
Copy link
Member

igrr commented Nov 20, 2015

I see that on each power up you do

WiFi.mode(WIFI_STA);
WiFi.begin(id, pass);

Each time this is done, SDK writes these settings to flash memory. Depending on you wakeup frequency, this might result in some wear to these sectors of flash memory.

I will add some additional checks which will bypass SDK functions in case SSID/psk match the ones already present in Flash. This will reduce the number of flash writes (i.e. it will only be written when SSID/psk actually change).

@mlord
Copy link

mlord commented Nov 20, 2015

I wonder why the code feels that it is necessary to write those parameters to flash at all?
They are, after all, supplied each time the sketch runs, so remembering them is not necessary on its own.

Thanks

@igrr
Copy link
Member

igrr commented Nov 20, 2015

This is Espressif SDK functionality — it stores WiFi configuration parameters to flash each time these parameters change. There is no API in the SDK to disable this feature.

@igrr igrr changed the title Wifi functions forcing ESP12E to reset after some time WiFi config corrupted after multiple restarts Nov 20, 2015
@rafaelmendes
Copy link
Author

So, if I remove these two functions and let the module connect to the Wifi AP using the ssid and password stored in flash the problem will be solved?

@ghost
Copy link

ghost commented Nov 21, 2015

I'm the developer of the ESP Easy sensor project (www.esp8266.nu) and users can also enable deepsleep on the webgui. My sketch also stores it's own wifi config version and sets this at boot time. So if this is true, we will soon face similar "brick" issues. I think I have to warn about this on our forum.

But on the other hand, if we would compare things with AVR, where the guaranteed EEPROM write cycles are at least 100.000, writing a config every minute (so 1440/day) would still work for 100.000/1440 = 69 days before EEPROM starts to wear out. Am I right?

Or is the write cycle life time for these flash chips on ESP a lot lower?

@igrr
Copy link
Member

igrr commented Nov 21, 2015

Flash memory is external to the ESP8266, and ESP-xx module vendor(s) may use different ICs. I have a few modules which started showing flash-related issues after about 100 flash operations. This may very well be due to low quality/defective ICs used. So the actual mileage will vary.

I will push the fix today. Need to do a few more tests.

@ghost
Copy link

ghost commented Nov 21, 2015

I guess the same applies for these commands which are used in our sketch at boot time:
WiFi.softAP(ap_ssid, SecuritySettings.WifiAPKey);
WiFi.mode(WIFI_AP_STA);

@igrr
Copy link
Member

igrr commented Nov 21, 2015

Setting mode after calling WiFi.softAP is actually not a right thing to do.
Anyway, will look at WiFi.softAP as well.

@ghost
Copy link

ghost commented Nov 21, 2015

I think that flash cell wear should be protected at the lowest level possible.

I'm also using sector writes to flash, but maybe I need change the routine to check if the 4k block is actually changed for at least one byte before it's written back to flash. Of course it would be nice it this is already protected at the core level or sdk level. Maybe we need to check this and write wrappers around all flash related stuff to protect the chip.

Risk that a sketch runs into a loop writing same data to the same cell in a high frequency is just to high!

So using this stuff could be dangerous:

if(spi_flash_erase_sector(_sector) == SPI_FLASH_RESULT_OK)
if(spi_flash_write(_sector * SPI_FLASH_SEC_SIZE, reinterpret_cast<uint32_t*>(data), FLASH_EEPROM_SIZE) == SPI_FLASH_RESULT_OK)

I guess I should be safe it it's done like this:

// 'newdata' comes as parameter...

uint8_t* data = new uint8_t[FLASH_EEPROM_SIZE];
spi_flash_read(_sector * SPI_FLASH_SEC_SIZE, reinterpret_cast<uint32_t*>(data), FLASH_EEPROM_SIZE);

boolean changed = false;
for (int x=0; x < FLASH_EEPROM_SIZE; x++)
if data[x] != newdata[x]
changed = true;

if (changed)
if(spi_flash_erase_sector(_sector) == SPI_FLASH_RESULT_OK)
if(spi_flash_write(_sector * SPI_FLASH_SEC_SIZE, reinterpret_cast<uint32_t*>(data), FLASH_EEPROM_SIZE) == SPI_FLASH_RESULT_OK)

But this also consumes some extra MCU processing time...

@igrr
Copy link
Member

igrr commented Nov 21, 2015

Doing this kind of check by default is a pessimization which will become a major performance hit for, e.g., SPIFFS, which does wear levelling internally.

If you want wear levelling, you might just use SPIFFS instead of raw flash interface for your application.

@ghost
Copy link

ghost commented Nov 21, 2015

I'm aware of the performance loss. We started to "avoid" using spiffs because of it's costs in terms of program size and RAM usage. We only needed a single 32k block to store all configuration structs and that's why I decided to use some small dedicated functions. Currently without 'wear leveling' but that would be impossible if you only want to use 32k in total (has to work on 512k ESP models)

Using the EEPROM library (emulated in flash) actually has the same risk that probably most users are unaware off. It they mistakenly update the same data to eeprom in a loop (or due to a bug) the cell would soon be worn out and fail.

Of course we would still have no protection if a bug results into writing different data to the same cell in a loop...

@sticilface
Copy link
Contributor

This is what I use. Its a function that first tries to use stored credentials, so if the ESP has connected before it uses those (nothing is written to flash), then if that fails it tries to use hard coded credentials, then if that fails it creates an AP. From following this thread, if u've connected to the SSID before, it should just reconnect without writing anything. What i've not implemented is a comparison function between what is stored and what is hard coded. should be possible though.

bool Wifistart()
{

    if (WiFi.getMode() == WIFI_AP)
        return false;

    WiFi.begin();

    Serial.print("WiFi init");
    uint8_t i = 0;
    while (WiFi.status() != WL_CONNECTED)
    {

        delay(500);
        i++;
        Serial.print(".");
        if (i == 30)
        {
            Serial.print(F("Auto connect failed..\nTrying stored credentials..."));
            WiFi.begin(_ssid, _pass);
            while (WiFi.status() != WL_CONNECTED)
            {
                delay(500);
                i++;
                Serial.print(".");
                if (i == 60)
                {
                    Serial.print(F("Failed... setting up AP"));
                    WiFi.mode(WIFI_AP_STA);
                    WiFi.softAP(_APssid, _APpass);
                    break;
                }
            }
        };
        if (i > 60)
            break;
    }

    if (WiFi.status() == WL_CONNECTED)
    {
        Serial.println();
        return true;
        Serial.printf("\nconnected: SSID = %s, pass = %s\n", WiFi.SSID().c_str(), WiFi.psk().c_str());
    }

    else
    {
        Debugln();

        return false;
    }
};

@igrr
Copy link
Member

igrr commented Nov 21, 2015

I was looking through the SDK docs and found that we now do have a way to set WiFi configurations without writing anything to flash (wifi_station_set_config_current, wifi_softap_set_config_current).
However changing this behaviour now would probably break a lot of existing changes.

Perhaps adding some parameter new parameter (i.e. bool persistent) is a better way?

@mlord
Copy link

mlord commented Nov 21, 2015

I don't expect it to be a common thing for sketches to change their hardcoded SSID/passwd etc.. Or at least not any of my own sketches. So limiting the damage by getting rid of unnecessary calls to wifi_station_set_config() is good enough for me. But exposing more of the SDK is probably also a Good Thing.

--- esp8266/libraries/ESP8266WiFi/src/ESP8266WiFi.cpp.orig      2015-11-21 10:00:46.860166073 -0500
+++ esp8266/libraries/ESP8266WiFi/src/ESP8266WiFi.cpp   2015-11-21 10:01:05.988228854 -0500
@@ -132,7 +132,13 @@
     }

     ETS_UART_INTR_DISABLE();
-    wifi_station_set_config(&conf);
+    struct station_config old;
+    wifi_station_get_config(&old);
+    if (old.bssid_set != conf.bssid_set
+     || (old.bssid_set && memcmp(old.bssid, conf.bssid, 6))
+     || strcmp((char *)(old.ssid),     (char *)(conf.ssid))
+     || strcmp((char *)(old.password), (char *)(conf.password)))
+       wifi_station_set_config(&conf);
     wifi_station_connect();
     ETS_UART_INTR_ENABLE();

@igrr igrr closed this as completed in 40da463 Nov 21, 2015
@igrr igrr reopened this Nov 21, 2015
@igrr igrr added this to the 2.0.0 milestone Nov 21, 2015
@rafaelmendes
Copy link
Author

I think [https://github.com/esp8266/Arduino/commit/40da463ee631133a16fc8ddde7c82d507060068b] messed with the AP config functions. When I upload the WifiAccessPoint example, I can't change the SSID. The AP is always setup with the same id. I tried to do the same with the git version before [https://github.com/esp8266/Arduino/commit/40da463ee631133a16fc8ddde7c82d507060068b] and it worked fine.

Looking at ESP8266Wifi.cpp, I couldnt figure out what was wrong, maybe you guys can help...

@rafaelmendes
Copy link
Author

I think the problem is in ESP8266WiFiClass::softAP at:

if (!softap_config_equal(conf, conf_current))
{
    DEBUGV("softap config unchanged");
    return;
}

softap_config_equal returns true if conf and conf_current are the same. So, I guess it should be:

if (softap_config_equal(conf, conf_current))
{
    DEBUGV("softap config unchanged");
    return;
}

@igrr
Copy link
Member

igrr commented Nov 25, 2015

@rafaelmendes thanks for spotting this. Fixed in 6be74ec.

@ibaranov-cp
Copy link

On a related note, the ESP no refuses to change away from any custom name. I loaded the example WifiAccessPoint, and now every subsequent AP has the name "ESPap", regardless of what I set.

In other news, computers and cellphones now refuse to connect to the device...

@rafaelmendes
Copy link
Author

Are you using the latest git version? After 6be74ec the problem I was having with the AP id was fixed.

@ibaranov-cp
Copy link

I hand-modified the fix that was mentioned (removing the !) and now seem to get the opposite problem.... Will try a full git pull.

@ibaranov-cp
Copy link

This is probably a separate issue. I am having great difficulty connecting to the network with any laptop I have. Even the cellphone goes through a few cycles of connecting-disconnecting-connecting. Power supply to the ESP module has 22uF caps, and is rated for 600mA, so no issue there. Distance is about 20 cms.

@comino
Copy link
Contributor

comino commented Nov 27, 2015

@ibaranov-cp : I have a similar issue than you with my laptop. Strangely with other laptops of my co-workers and every smarphone I tried it works just fine. 100µF and laboratory supply and old firmware (like 2 months old) works.

@PurpleAir
Copy link
Contributor

Please note that the AP ID issue is still present in the staging version.

@Rob58329
Copy link

Rob58329 commented Jan 29, 2018

(1) I am assuming the the "WiFi.persistent(false)" setting is NOT retained during "ESP.deepSleep", so needs to be re-issued after every wake-from-deepSleep. Is this correct?

(2) I am also assuming the "WiFi.persistent(false)" setting ONLY affects what happens for the calls to "WiFi.begin(ssid,pw)" and "WiFi.softAP(ssid,pw)". Is this correct? – Update: also used by “WiFi.mode(..)” and other commands – see below!

(3) If (2) is correct, then I am assuming that "WiFi.persistent(false)" ONLY needs to be issued before a "WiFi.begin(ssid,pw)" or "WiFi.softAP(ssid,pw)". IE. if not using either of these commands during a wake-period, then it is NOT necessary to re-issue the WiFi.persistent(false)" after wake from "ESP.deepSleep". Is this correct? – Update: Partially INCORRECT – see below!

(4) I am finally assuming that it does not matter if the "WiFi.persistent(false)" is issued either before or after the "WiFi.forceSleepWake()" or "WiFi.mode(WIFI_STA)" commands, as neither of these commands are affected by it. Is this correct? – Update: Partially INCORRECT – see below!

If any of the above assumptions are incorrect, any clarification would be appreciated!

@Pablo2048
Copy link

Waking-up from DeepSleep is equivalent to reset. Anything about .persistent can be found inside ESP8266WiFiGeneric.cpp in ESP8266WiFiGenericClass so you can take a look...

@Rob58329
Copy link

Rob58329 commented Jan 30, 2018

Pablo2048 – many thanks for the pointer!

I must start by stressing that I am no expert in interpreting these .cpp files, but these files seem to say that the [persistent] setting is used to decide if to save stuff in flash by the following processes:

(1) From [ESP8266WiFiGeneric.cpp]:

  • in ESP8266WiFiGenericClass::mode(WiFiMode_t m) - which I assume is used by the “WiFi.mode(WIFI_STA etc)” commands.

(2) From [ESP8266WiFiAP.cpp]:

  • in ESP8266WiFiSTAClass::begin(..) – which I assume is used by the “WiFi.begin(ssid,pw)” command.
  • in ESP8266WiFiSTAClass::disconnect(..) – which I assume is used by the “WiFi.disconnect()” command.

(3) From [ESP8266WiFiAP.cpp]:

  • in ESP8266WiFiAPClass::softAP(..) – which I assume is used by the “WiFi.softAP(ssid,pw)” command.
  • in ESP8266WiFiAPClass::softAPdisconnect(..)

(A) Thus is would seem necessary to set “WiFi.persistent(false)” after every DeepSleep wake, BEFORE any of the “WiFi.mode” or “WiFi.begin” or “WiFi.softAP” or disconnect commands. (But I note that neither “WiFi.forceSleepBegin()” and “WiFi.forceSleepWake()” seem to use the [persistent] setting.)

(B) As “forceSleepBegin” does not do anything if [!mode(WIFI_OFF)], the “WiFi.forceSleepBegin();delay(1);” commands needs to be after “WiFi.mode(WIFI_OFF)”

(C) I note that “forceSleepWake” first does a “Wake ESP8266 up from MODEM_SLEEP_T force sleep”, and then uses the [WIFI_STA] and [_forceSleepLastMode] variables to decide if to do a “wifi_station_connect”. However as neither of these 2 variables are likely to have been retained after a DeepSleep, it would appear not to matter if the “WiFi.forceSleepWake()” command is before or after the “WiFi.mode(WIFI_STA)” command. But I note that most users seem to issue it BEFORE the “WiFi.mode(WIFI_STA)” command, so it is possible that “WiFi.forceSleepWake();delay(1);” is better to put first (perhaps because this ensures it does NOT try a “wifi_station_connect”)!?

(D) I also note that the [persistent] setting is used to save variables into flash by both “(STA)disconnect” and “softAPdisconnect”. This appears to be because the data saved (being of [struct station_config]) includes the [bssid] (aka MAC address of the WiFi-router), which might not have been available when the initial SSID/PW data was saved in “WiFi.begin(..)”. [Interestingly, this would seem to suggest that if you are (manually) connecting & disconnecting from APs frequently, and didn't need the [bssid] saving, you could still save the [ssid/pw] but reduce [flash-save usage] by ~50% just by issuing a "WiFi.persistent(false)” before the “WiFi.disconnect()” command - although in these instances it would probably not even be necessary to save the [ssid/pw] either...!?]

(E) Finally, I note that the ESP8266 does retain some data through a DeepSleep or Reset (eg. the RTC-Memory, and data sufficient for it to identify what the reset-reason was after a Reset/Wake (ie. using “system_get_rst_info”).) However, as it seems most users re-set “WiFi.persistent(false)” after waking from a DeepSleep, this would suggest that the [persistent] setting is NOT retained during DeepSleep (or a Reset).

So, in summary, best option if using DeepSleep seems to be issuing “WiFi.persistent(false)” at top of [setup()], as there is no penalty for doing this here. And then if necessary/required, issuing a “WiFi.persistent(true)” just before any "WiFi.begin(..)" or "WiFi.softAP(..)" commands (and a “WiFi.persistent(false)” after them if you dont want any subsequent “WiFi.disconnect()” commands to save data into flash)!?

If any of the above deductions are incorrect, clarification would be appreciated!

@fcalderan
Copy link

fcalderan commented Jun 13, 2018

I've installed the git version (following the instructions) as pointed out in several duplicate issues, but I still see the wrong SSID. It should be ESP8266 but instead it's ESP_xxxxx

I'm using an ESP8266-12E board with an integrated 128x32 OLED display

What am I doing wrong?

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h> 
#include <Arduino.h>
#include <U8g2lib.h>

#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif


ESP8266WebServer server(80);
IPAddress  apIP(172, 16, 0, 1);
const char *ssid = "ESP8266";
const char *password = "root";

U8G2_SSD1306_128X32_UNIVISION_F_SW_I2C u8g2(U8G2_R0, 5, 4, 16);

void setup(void) {
  u8g2.begin();

  WiFi.persistent(false);

  WiFi.mode(WIFI_AP_STA);
  WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0));   
  WiFi.softAP(ssid, password);
  server.on("/", handleRoot);   

  server.begin();

}

void handleRoot() {
  server.send(200, "text/plain", "Hello world!");   
}

void loop(void) {

  char IPBuffer[16];
  IPAddress ip =  WiFi.softAPIP();
  sprintf(IPBuffer, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);

  u8g2.clearBuffer();          // clear the internal memory
  u8g2.setFont(u8g2_font_t0_15_mf); // choose a suitable font
  u8g2.drawStr(5, 12, "NodeMCU ESP8266"); // write something to the internal memory
  u8g2.drawStr(5, 30, IPBuffer); // write something to the internal memory
  u8g2.sendBuffer();          // transfer internal memory to the display

  server.handleClient();
  delay(1000);
}

Thank you

@Pablo2048
Copy link

Probably bad credentials? See https://www.quora.com/Why-does-WiFi-password-should-have-minimum-of-only-8-characters

@fcalderan
Copy link

That was the problem @Pablo2048 : now it's all working
Thank you so much.

@TByte007
Copy link

TByte007 commented Mar 6, 2019

So just to be clear after so many posts - does WiFi.begin("network-name", "pass-to-network") overwrites the FLASH if the settings are the same with what's on the FLASH or not if "persistent" is true ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests