Wifi connect taking a long time

I am using a P1 in semiautomatic mode and system threading enabled.

I am testing the connection behavior when credentials are available but the device is not in the network location.

As expected the device at start up goes into blinking green. The strange behavior that I noticed is when I use different FAKE credentials the blinking green blocks the system code for upto 30 sec using one credential and almost no blocking using different kind.

Procedure:

  1. clear all wifi creds
  2. power reset device
  3. enter new FAKE creds as SSID: lake-wifi, PW: aluminum
  4. power reset, and after I call Wifi.on; WiFi.connect the device blocks sytem code for upto 30 sec
    (RGB: blinking green and flashes white briefly every 35 sec)

When I use different creds as bleow, it does not block

  1. clear all wifi creds
  2. power reset device
  3. enter new FAKE creds as SSID: lake, PW: alum
  4. power reset, and after I call Wifi.on; WiFi.connect the device does not block at all systme code start immediately.
    (RGB: blinking green and flashes white briefly every 2 sec)

I do not have a minimum code for testing yet (My current code is ~7000 lines). I wanted to ask first if some credential take longer to analyze than others when trying to connect to wifi?

I’m hearing two problems:

  1. Bad credentials are blocking your application from running when using System Threading
  2. Bad credentials are causing a delay in connection when you have good credentials entered in addition to the bad ones

For #2 I have confirmed that entering good credentials, then entering up to 4 more sets of bad credentials does lengthen the time it takes before the good credentials will connect. Even after the good credentials connect, pressing RESET appears to cause all bad credentials to be tried again. It appears that they are tried in sequence, in order that they appear in DCT memory. As credentials are entered, the existing ones are moved down in memory.

It would seem like a good idea to always move a set of credentials that connects, to the top of the list… or use an index pointer to set which set of credentials connected last, and try that one first. If you had multiple networks available and multiple good credentials available though, this could be bad for Flash wear.

To prevent this from being an issue, it might be appropriate to have a setting that prevents more than one set of credentials from being stored… then you have to enter only one good set and that’s the only set that is tried. Maybe a user API that can be set in application code and value stored in DCT.

I tested this with a Photon, and in my environment it will cycle through 4 bad sets of credentials pretty quickly… although 2 of them were fake so they may timeout quicker. Total it seems to only take 30 seconds or so to finally connect.

For #1 I’m guessing since you are in SEMI_AUTOMATIC mode you are calling Particle.connect() at some point. Are you also using anything like waitFor(Particle.connected, 60000); which will block?

I have tested with bad credentials and it doesn’t appear to block the application thread… it’s blinking green while my D7 LED is blinking away ok.

SYSTEM_MODE(SEMI_AUTOMATIC);
SYSTEM_THREAD(ENABLED);

void setup()
{
	Particle.connect();
	// waitFor(Particle.connected, 60000); // This blocks until we are connected

	pinMode(D7, OUTPUT);
}

void loop()
{
	digitalWrite(D7, !digitalRead(D7));
	delay(100);
}

@BDub, both creds that i tested were bad ie they were fake and when I tested I only had one credential at a time. It was weird that the 1st cred that I set using SSID: lake-wifi, PW: aluminum took a long time to time out. But when I cleared the cred and entered this fake one: SSID: lake, PW: alum it took less than a sec to time out.

It seemed dependent on the SSID and password combination.

It would hang at the setup when I called the below:

SYSTEM_THREAD(ENABLED);
SYSTEM_MODE(SEMI_AUTOMATIC);

setup() {
  WiFi.on();
  delay(250);
  WiFi.connect();
  hasWiFiCreds = WiFi.hasCredentials();
}

loop(){
if (Particle.connected() == false && WiFi.connecting() == false && WiFi.listening() == false && !powerModeAC){
      WiFi.on();
      delay(250);
      WiFi.connect();
      hasWiFiCreds = WiFi.hasCredentials();
    }
    if(!Particle.connected() && WiFi.ready()){
        Particle.connect();
    }
}

to add some more information, I was able to get the same behavior when the password reached 8 characters in length. Each time I cleared the creds so there was only one entered at a time. The last one showed the delayed behavior.


C:\Users\Steve>particle setup wifi
? Should I scan for nearby Wi-Fi networks? (Y/n) n
? Should I scan for nearby Wi-Fi networks? No
? SSID hom
? SSID hom
? Security Type WPA2
? Cipher Type AES+TKIP
? Wi-Fi Password test
Done! Your device should now restart.

C:\Users\Steve>particle setup wifi
? Should I scan for nearby Wi-Fi networks? (Y/n) n
? Should I scan for nearby Wi-Fi networks? No
? SSID hom
? SSID hom
? Security Type WPA2
? Cipher Type AES+TKIP
? Wi-Fi Password test1
Done! Your device should now restart.

C:\Users\Steve>particle setup wifi
? Should I scan for nearby Wi-Fi networks? (Y/n) n
? Should I scan for nearby Wi-Fi networks? No
? SSID hom
? SSID hom
? Security Type WPA2
? Cipher Type AES+TKIP
? Wi-Fi Password test12
Done! Your device should now restart.

C:\Users\Steve>particle setup wifi
? Should I scan for nearby Wi-Fi networks? (Y/n) n
? Should I scan for nearby Wi-Fi networks? No
? SSID hom
? SSID hom
? Security Type WPA2
? Cipher Type AES+TKIP
? Wi-Fi Password test123
Done! Your device should now restart.

C:\Users\Steve>particle setup wifi
? Should I scan for nearby Wi-Fi networks? (Y/n) n
? Should I scan for nearby Wi-Fi networks? No
? SSID hom
? SSID hom
? Security Type WPA2
? Cipher Type AES+TKIP
? Wi-Fi Password test1234
Done! Your device should now restart.

I can confirm similar 1 sec give up time for passwords shorter than 8 chars behavior on a Photon, but the blocking part does not occur for my application. It does for yours though. Maybe the difference in WiFi.connect() vs Particle.connect()? Very strange, yet repeatable so hopefully that means it will be easy to locate and fix.

The give up time differences do not seem to be a big deal, but odd enough. WPA/WPA2 does not appear to have any minimum password length, even though 8-63 is recommended. I wonder if the password can even be less than 8 chars and connect. I just tried to set one on my iPhone personal Wi-Fi hotspot and it won’t let me… it has to be at least 8 chars. My router also requires 8-63… hmm, maybe this is a requirement but one that most MFG’s of Wi-Fi equipment require for the benefit of security. Less than 8 chars would start to become easier to brute force crack, with enough computers and time. You may have unknowingly found a WICED API requirement that is not publicized… If I could set my password to less than 8 chars I’d love to try it… and then document this requirement.

Back on the blocking behavior, I tried to simply replace Particle.connect() with WiFi.connect() in my app… and that did not do it. So something with one of piece of your code is causing the block… if you have time to narrow it down that would be helpful.

Not your immediate issue, but

One thing you should avoid is to retrigger a Particle.connect() while another attempt hasn't finished.
Since we are missing a Particle.connecting() status, try a one-shot flag with timeout.

Ahh good call. I’ll give that a try

I’ve tried that but I get the same behavior.

I’ve also noticed that if bad cred are stored and WiFi.connecting = true when I call WiFi.listen instead of going into listening mode it 1st trys to WiFi.connect which causes a 30 sec delay or so.

There is an open issue about WiFi.listen() being slower than the SETUP button procedure.
https://github.com/spark/firmware/issues/859
and a possible fix
https://github.com/spark/firmware/pull/864

1 Like