Workaround for endlessly blinking cyan and flakey cloud connnection

I’m using several P1 Photons and having tough time keeping them connected to the cloud in the automatic mode. After reset they connect just fine, but some time later they start blinking cyan. In some cases they manage to re-connect, other times they get stuck.

I tried many things but so far the most resilient connection I achieved was by switching to the manual mode. Here’s the prototype code I used:

SYSTEM_MODE(MANUAL);
#define RECOVERY_LED D2
#define RECONNECT_TIME 5000

uint32_t n_timer;
uint8_t b_recovery = FALSE;
uint8_t b_startup = TRUE;


void setup() {
    pinMode(RECOVERY_LED, OUTPUT);
}

void loop() {

    if (Spark.connected() == FALSE) {
        // initiate recovery process
        if (!b_recovery) {
            n_timer = millis() + RECONNECT_TIME;
            b_recovery = TRUE;
            digitalWrite(RECOVERY_LED, HIGH);
            Spark.connect();
        }
        // recovery timeout - reboot radio
        else if (millis() >= n_timer) {
            WiFi.off();
            delay(100);
            b_recovery = FALSE;
        }
    }
    // successfull recovery/connection
    else if (b_recovery == TRUE) {
        b_recovery = FALSE;
        digitalWrite(RECOVERY_LED, LOW);
        if (b_startup == TRUE) {
            Spark.publish("Started", String(WiFi.RSSI(), DEC));
            b_startup = FALSE;
        }
        else {
            Spark.publish("Recovered", String(WiFi.RSSI(), DEC));
        }
    }
    Spark.process();
}

Obviously code related to LED and event publishing is not required, but helpful in debugging.

I was considering calling System.reset() after say 5 unsuccessful recovery attempts, but cycling the radio appears to be enough in my case.

Any thoughts, critique or questions regarding this solution are very welcome.

1 Like

@sparkly , I have had the same issue and opted to keep automatic mode and use the following code. I test it by firing up my microwave which seems to force the photons off the cloud. My spark core on the other hand is much more robust and seems to never get pushed off.

#include "application.h"
const uint32_t SOFTDELAY10s   = 10000UL;
uint32_t lastTime;
volatile int lostconnectionTimeUnix = 0;

void setup(){
//Your normal setup code here
}//setup
    
void loop() {
    if (!Spark.connected()) {  //record when photon lost connection
        if(Time.now() > (lostconnectionTimeUnix + 6000)) { //try reconnect if disconnected > 6 secs
           Spark.connect();  
           while(!Spark.connected()) {
            Spark.process();
            }//while(!Spark.connected())
            if(lostconnectionTimeUnix == 0) {lostconnectionTimeUnix = Time.now();}
            lastTime = millis();
            while(millis() - lastTime < SOFTDELAY10s) {Spark.process();}
            }//if(Time.now() > (firstlostconnectionTimeUnix + 6000))
    }//if (!Spark.connected())
    if (Spark.connected()){

//Your normal loop code here

        lostconnectionTimeUnix = 0;
    }//if (Spark.connected())       
}//loop

Thanks for sharing your code and microwave test idea, @bpr

My understanding that calling Spark.connect() upon disconnect is part of the automatic mode and I saw Photons attempting to restore the connection but sometimes they got stuck trying (cyan blink forever). I had to go deeper (reboot the radio) but luckily not all the way down (board reboot).

@sparkly, yes that’s what I was getting - fast cyan forever - in my photons. The microwave brought this about reliably but it also happened randomly without microwave use. I’d come home from work and one or all of my photons would be stuck in fast cyan land. The above code seems to fix it for me. I used the above code in an photon application that also saves the time it lost connection and then publishes the time it reconnects to cloud and with some nodejs I was able to record/save to a file most of the apparent lost connection events. Wish the photon was more robust like the core.
BTW, how are you hooking up your P1s. I got some but haven’t decided how to mount them yet.

@bpr, I’ll give your code a try to see if it can survive my microwave attack.

re. mounting P1’s: I ordered these little fellows:

… and use hacked T-962 Infrared oven with lead free paste.

2 Likes

This might be useful: https://github.com/kennethlimcp/particle-examples/blob/master/wifi-auto-reconnect/wifi-auto-reconnect.ino

2 Likes

@kennethlimcp I think retry_count needs to be reset upon successful connection so it has all 10 attempts each time connection goes down before we yank the radio.

1 Like

Sounds good but it worked well for me :smiley:. It’s like i’m gonna try harder each time wifi fails me. haha! Kidding. PRs welcome :wink:

Actually killing the radio and restarting works best for now, for me.

@sparkly and @kennethlimcp : It’s really hard w/ these intermittent glitches to settle on a best solution, but FWIW my current simplest and seemingly most robust solution is the following (AUTOMATIC mode):

#include "application.h"
const uint32_t SOFTDELAY30s   = 30000UL;
uint32_t lastTime;
volatile int lostconnectionTimeUnix = 0;

void setup(){
//Your normal setup code here
}//setup
    
void loop() {
    if (!Spark.connected()) {  //record when photon lost connection      
        if(Time.now() > (firstlostconnectionTimeUnix + 6000)) { //try reconnect if disconnected > 6 secs
           Spark.connect();  
           while( (!Spark.connected()) && (millis() - lastTime < SOFTDELAY30s) ) {Spark.process(); }//while(!Spark.connected())
           if(firstlostconnectionTimeUnix == 0) {firstlostconnectionTimeUnix = Time.now();}
        }//if(Time.now() > (firstlostconnectionTimeUnix + 6000))      
    }//if (!Spark.connected())

    if (Spark.connected()){
        lostconnectionTimeUnix = 0;

//Your normal loop code here

    }//if (Spark.connected())       
}//loop
1 Like

@sparkly and @kennethlimcp I may have found my solution:

@bpr, Thanks for the idea. I use Asus RT-N53, and it’s entirely possible that with some tweaking on router’s end the situation can be improved. However product with mass market ambitions doesn’t have this as an option.

@sparkly I agree and maybe it points to where the firmware needs tweaking