[FIXED][WORKAROUND] Problem with WiFi.setCredentials() and WiFi.hasCredentials(): setting credentials is not permanent after reboot

Hi,
I’m operating my Spark.Core in semi-auto mode.
on the first run I do clear and set my wifi credentials … spark.core does connect to my AP and everything works fine.

but on the next runs after a power off / power each call I make (during setup) to WiFi.hasCredentials() will return false, so my code keeps setting credentials every time … which I would like to avoid (credentials did not change and I want to speed up the connection time)

of course everything works … my app works … but I really would like to avoid setting credentials all the time (also to avoid burning the c3300 flash)

basically my pseudo code at setup does:

WiFi.on()
WiFi.disconnect()

while( !(WiFi.hasCredentials()) )
{
  // log message here!
  Wifi.setCredentials();
  delay(1000);
}

WiFi.connect();

etc. etc.

shouldn’t hasCredentials() return TRUE after the first time … even after a power reset (off/on) ?

NOTE: the while loop will execute only once each time at setup, aftert he first call to setCredentials all the calls to hasCredentials will return TRUE. What is not clear to me is why (at boot) the hasCredentials call does not return TRUE since the previous time I did store my credentials already… :frowning:

thanks for your help

Please paste code in the forum with this format:

``` <-- insert this

//paste code here

``` <-- insert this

Isn’t it WiFi and not wifi?

it should be like:

if (!WiFi.hasCredentials(){
    WiFi.setCredentials();
}

yes that is the actual code line … sorry I did a quick pseude code.

Can you tell me your actual steps so that i can try?

  • how did you clear the credentials?
  • what security type etc

I will try it out

1 Like

I did clear credentials “manually” by using the mode+rst button (until the blinking white sequence)

here is my setup snippet, I use WPA2 and my AP has no password (it’s a test setup).

each time I reset (or power cycle) I see one call to the setCredentials() even if the previous run was clearly successful.

    /* wifi: initialization */
    WiFi.on();
    delay(1000);
 
    while(!(WiFi.hasCredentials()))
    {
        Serial1.println("setting WiFi credentials");
        WiFi.setCredentials(WIFI_SSID, WIFI_PWD);
    }

    /* WIFI connection outer loop (N retry) */
    while(!(WiFi.ready()))
    {
        WiFi.off();
        delay(500);

        WiFi.on();
        delay(500);

        WiFi.connect();

        retry_cnt=60; //30s
        while((retry_cnt>0) && (WiFi.connecting()) )
        {
            Serial1.println("WiFi: connecting...");
            delay(1000);
            Spark.process();
            retry_cnt--;
        }

        Spark.process();    
    }
    
    /* Prints out the local IP over Serial */
    Serial1.println(WiFi.localIP());
    Serial1.println(WiFi.subnetMask());
    Serial1.println(WiFi.gatewayIP());

don;t forget to set the semi-auto mode at the beginning of your app (and define your SSID and PWD)

SYSTEM_MODE(SEMI_AUTOMATIC);
2 Likes

Wouldn’t this erase the user firmware and load the default factory tinker firmware since you performed a factory wipe reset?

yup … and it does erase also your wifi password afaik … full reset.

sorry I was not clear: I do that only ONE time (out of the box), then upload my fw which will save credentials on the first run. Any run after that (reset button, or power cycle) should not need to set credentials anymore

Yep. There’s a simpler way to erase credentials - start the device, then hold the MODE button for 10 seconds to perform a WiFi Network Reset.

What you performed was a Factory Reset which will have erased your own firmware, so you’ll need to reflash your app and try again.

thanks mdma.

but the problem is not resetting my device … the problem is the fact that hasCredentials does NOT return true after the first run. power cycle your device (or press rst) and any call to hasCredentials will return false, even if (in the previous run) I did setCredentials and I did connect to my wifi AP (and the app did work indeed)

I just want to avoid setting credentials all the time…
:slight_smile:

I believe this is a bug in v0.3.4 which we hope to have fixed in the upcoming 0.4.x release.

Some things to try:

  • call WiFi.on() before WiFi.hasCredentials()
  • how about using EEPROM to store a value after you set credentials so you know not to try to set them again?

EDIT: I now see the code you gave above, you’re already calling WiFi.on(). Great! :smile:

I do call WiFi.on() and also wait 1s after that (I was thinking the C3300 does need some boot time…)

indeed the EEPROM flag is what I’m doing as a workaround :slight_smile: but I wanted to understand why it did not work as expected.

good to know it is a bug … I’ll go with the eeprom flag then…

thanks!

Does look like a bug in the implementation after testing :wink:

added an EEPROM flag to signal stored credentials and runs like a champ! much faster setup/connection time.

one OT question: is there a plan to add an api to set the WiFi output power so that for 24/7 devices we can mitigate the heat? even with an heatsink … pulling all that current … the wifi shield is quite warm … and if your AP is not too far you might not need to run full power.

thanks!