WiFi.connect() results in hard fault when WiFi is not available or has no internet connection [SOLVED MAYBE?]


#1

Photon ends up in a red flash SOS hard fault restart cycle on WiFi.connect() when the WiFi network is not available (or doesn’t have an internet connection) on device OS 0.7.0+. The expected behavior is that when running in SYSTEM_MODE(SEMI_AUTOMATIC); SYSTEM_THREAD(ENABLED); the user code will continue running when the Photon fails to connect to WiFi or loses WiFi connection.

Below is the simplified code to reproduce the issue. The same happens when the more comprehensive wifi connection management code is used. Below that, a video showing the differences when WiFi is dropped while it was connected. Then, after resetting the devices, how the hard fault occurs for 0.7.0 and 0.8.0-rc11 but not for 0.6.3

EDIT: Issue submitted

EDIT 1/14/2019: The issue occurs in 1.0.0 too, however, if after clearing the wifi credentials and setting up again, WiFi.connect() in the absence of networks available don’t end up hard faulting anymore.

SYSTEM_MODE(SEMI_AUTOMATIC); // same happens in MANUAL
SYSTEM_THREAD(ENABLED);
                                            // INITIALIZE VARIABLES =================================

int LED = D7;                               // LED = onboard LED pin (D7).


                                            // SETUP ================================================

void setup() {
    pinMode (LED, OUTPUT);                  // Set LED pin to OUTPUT mode.

    WiFi.on();                              // Turn on WiFi
    
            digitalWrite(LED, HIGH);        // LED flashing is merely to help locate step whereafter SOS occurs  
            delay(6000);
            digitalWrite(LED, LOW);
            delay(1000);
            
    WiFi.connect();                         // Attempt to connect to available networks assuming 1 set of credentials

   
            digitalWrite(LED, HIGH);        
            delay(4000);
            digitalWrite(LED, LOW);
            delay(1000);
            
    if(waitFor(WiFi.ready, 15000)) { Particle.connect(); }   // If connected to the network, connect to the Particle Cloud
         
            digitalWrite(LED, HIGH);        
            delay(3000);
            digitalWrite(LED, LOW);
            delay(1000);

}


                                            // MAIN PROGRAM LOOP =====================================

void loop() {

digitalWrite(LED, HIGH);        // User code doing stuff
            delay(2000);
            digitalWrite(LED, LOW);
            delay(500);

}

Go into listening mode if no known networks are available
#2

Was there an actual solution for this?

I’m seeing nearly identical behaviour on 1.4.2


#3

Have you tried to clear all the existing wifi credentials and setting up the network(s) again on the Photon? Doing that solved the problem for me. Not sure why that would be but give it a try.


#4

Thanks, but that doesn’t work when you have thousands of them. Was hoping there was a workaround / code fix. Generally so far seems stable with a wifi.connect then a delay then a particle.connect


#5

I see. I might still be seeing the same issue too, but have more troubleshooting to pinpoint if it happens on a wifi connect.

In my sample code above I did use a delay, but you may also find this to be an extra precaution that should help in theory:

 if(waitFor(WiFi.ready, 15000)) { Particle.connect(); }   // If connected to the network, connect to the Particle Cloud

#6

You really shouldn’t have to do that.

It used to wrap all the wifi.* preparation. you call particle connect, it turns on wifi, it connects to wifi, it then connects to cloud when it can. years ago i went through the code and the thing is it’s clear as mud now how particle.connect works.

basically the duct tape holding together the most basic functionality seems to be peeling off.


#7

and the other major problem with wrapping particle.connect with a large delay is losing any particle.variable / particle.functions you’ve registered. it’s like its got Alzheimer’s, you have to make sure the registration happens together as there is no way to ‘re-register’ or check whether registration was successful.


#8

Hmm, where does that come from? I’ve not really heard of this behaviour before.

Registering Particle.variable(), Particle.function() and Particle.subscribe() can happen any time before the connection up to a few seconds after the cloud handshake and waitFor() won’t wait the given time unconditionally but would only wait up to the given amount of milliseconds (although I’d rather go with 30sec for poor WiFi).
For Particle.subscribe() you can also unregister all subscriptions and resubscribe if needed.


#9

Hard experience unfortunately with our chip flashing in China. It may be the great chinese firewall (i can’t even sync repo’s from github), it may be their lacklustre internet connection (chinese stuff is super fast, loading particle.io from a browser is slow) because of the firewall and international internet exchanges that their provider uses, who knows.

The reality is about two years ago we had to put it in a 10 second timer. It could well be the major upgrades to webhook / cloud processing that were undertaken about that time. If you run it in a 10 second timer delay most of the boards flash fine. If you put it in the main routine the cloud functions never register.

reality is rarely aligned with expectation.


#10

PS, it’d be super handy if you could re-register functions. Then I could trigger particle.connect immediately and re-register 5-10 seconds after cloud connects. It’s fairly important to be able to get a board online quickly and reliably, a human is sitting at the desk waiting for it to complete the flashing and validation process.