WiFi.setCredentials slow firmware 0.6.3

I noticed that my setup() function took really long, I called a Wifi.setCredentials (actually multiple). I wanted to make sure my product has certain credentials so if a network of a client doesn't work I can check with my mobile.

Doing three calls cost exactly 5614 milliseconds:

unsigned long startTime = millis();
  WiFi.setCredentials("Low", "");
  WiFi.setCredentials("Nokia", "");
  WiFi.setCredentials("WiFi-K", "");
  unsigned long endTime = millis();
  Serial.print("set credentials time :");
  Serial.println(endTime-startTime);

Any reason why it is so slow?

I could make a check if they already exist with getCredentials, however that might also be already build in if it reacts so slow?

Will my method cause flash wear as well? Because the comment in a mentioned issue is not really clear. Indeed a same Id that connects is used (so that might cause flash wear?).

This issue mentions flash wear:

In general we try not to erase flash if the resulting write will end up with the same data. What's not clear here is what happens when the same SSID is used for a connection that previously connected.

The reason why the calls take so long is probably due to the fact that you are providing a password despite it being empty.
Try the single parameter overload whether this helps.

If not, you may need to use the four parameter overload.
Normally (at least for non-open networks) the WiFi needs to be present for the device to gather the correct values for the omitted parameters and that takes time.

All more recent Device OS versions won’t rewrite the same settings over and over, but if you don’t explicitly state all four parameters, you may have some “unpredictable” variance in the missing ones.

Also if you are “rewriting” multiple hardcoded settings over and over, it might be better to store a “flag” in EEPROM, check that and only do the setup when the flag doesn’t match your expectation. That’s one single check vs. one equality check for each and every set of credentials you want to store.

3 Likes

My password is not empty, I removed them in the code example because I didn’t want to share them. I’ll try to overload them, however that would limit things. These are just offline fallback networks.

So what it make slow is that it tries to find the omitted parameters indeed.

I can try the EEPROM flag. However could there be scenario that the credentials are removed without me knowing? For example when updating firmware/bootloader? Because then the flag wouldn’t be reliable to know if it’s actually set.

Otherwise I might better implement this code. At least I suppose looking up stored credentials won’t start finding the missing parts (from the issue mentioned in my first post):

WiFiAccessPoint ap[5];
  int found = WiFi.getCredentials(ap, 5);
  bool gotMyMacCreds = false;
  for (int i = 0; i < found; i++) {
    if(strstr(ap[i].ssid, "SomeSSID"))
    {
      gotMyMacCreds = true;
      Serial.println("had creds");
    }
  }
  if(!gotMyMacCreds)
  {
    WiFi.setCredentials("SomeSSID", "SomePassword");
    Serial.println("set creds");
  }

I think it might be taking so long because if you use the two-parameter versions of setCredentials the Wi-Fi network must be currently in radio range, because it needs to determine the encryption type.

If you use the 3 or 4 parameter version like this:

WiFi.setCredentials("SSID", "PASSWORD", WPA2, WLAN_CIPHER_AES);

then it can save the network credentials without trying to contact the access point first.

The two parameter SSID and password only version takes longer, and also is probably timing out if the access point isn’t in range at the time.

4 Likes

This is what I already said :wink:

1 Like

Then you should maybe substitute them instead of creating the appearance of an empty pwd :wink:

Nope, firmware reflash nor bootloader reflash would clear the credentials since they are stored in the WiFi module which is not affected by either of them.
However, clearing the credentials by holding SETUP down for 10+ seconds would.

But your WiFi.getCredentials() approach would do the trick.

1 Like

Then you should maybe substitute them instead of creating the appearance of an empty pwd :wink:

Indeed sorry for that.
Little function to check if the credentials are present.

bool hasCredentials(String SSIDName) {

  WiFiAccessPoint ap[5];
  int found = WiFi.getCredentials(ap, 5);

  for (int i = 0; i < found; i++) {
    if(strstr(ap[i].ssid, SSIDName.c_str())) return true;
  }

  return false;
}

// usage in setup
if(!hasCredentials("FlowWifi")) WiFi.setCredentials("FlowWifi", "myPassWord");