Solid green and no loop() work after wifi router reboot. Second reconnect trouble

Firmware 0.4.7
Using manual mode:

SYSTEM_THREAD(ENABLED);
SYSTEM_MODE(MANUAL);
STARTUP(WiFi.selectAntenna(ANT_INTERNAL));

in loop() one time in 30 sec I check connection:

if (!WiFi.ready())
{
WiFi.off();
delay(1000);
WiFi.on();
WiFi.connect();
waitFor(WiFi.ready, 2000);
}

If i reboot wifi router - all my photon(three) hangout with solid green light.
They don’t responce for button (digitalRead), so I think loop() didn’t work and this is firmware core trouble.
Anyone can check this sitation with reboot router and photon in manual mode?

Nope, mine don’t.

Mine go
Green breathing
AP off
White
Green blinking (with occasional magenta flash when waitFor() fails)
AP on
Green rapid blink
Green breathing.

Which is the expected behaviour (IMHO)


Full test code

SYSTEM_THREAD(ENABLED);
SYSTEM_MODE(MANUAL);
//STARTUP(WiFi.selectAntenna(ANT_INTERNAL));  // default and persisted when called earlier

const uint32_t RETRY = 15000;
uint32_t ms;

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

void loop()
{
    if (millis() - ms > RETRY && !WiFi.ready())
    {
        WiFi.off();
        delay(1000);
        WiFi.on();
        WiFi.connect();
        waitFor(WiFi.ready, 2000);
        ms = millis();
    }
    digitalWrite(D7, (millis() >> 2) & 0x88);
}
2 Likes

Thank you! I drill deep in my sketch and make some seral debug.
First off all - I don’t need to do Wifi.off \ on \ connect.
After router go reboot, photon start green blinking - wifi search. And then router get online - fast blinking and reconect automaticaly, but it make in two tryouts.

void loop() {

    currentMillis = millis();
    if (currentMillis - previous_conected >= 30000 || previous_conected > currentMillis)
    {
        previous_conected = currentMillis;
        Serial.println("begin");
        if (!WiFi.ready())
        {
            Serial.println("WiFi reconect_start");
            WiFi.off();
            delay(1000);
            WiFi.on();
            WiFi.connect();
            waitFor(WiFi.ready, 2000);
            Serial.println("WiFi reconect_end");
        }
        if (!client.isConnected() & WiFi.ready())
        {
            Serial.println("Wifi_ready, but not MQTT now");
            /*if (client.connect("water_count"))
            { 
                Serial.println("client.connect");
                client.subscribe("home/water_count/spark/set");
                publish_message("home/water_count/spark", Particle.connected() ? "ON" : "OFF", true);
                client.subscribe("home/water_count/+/set");
            } */
        }
        publish_message("home/water_count/rssi", WiFi.RSSI(), true);
        Serial.println("Publish PSSI");
    }
    client.loop(); 
    if(currentMillis % 2000 == 0) { Serial.print(WiFi.ready()); Serial.print(" | ");   Serial.println(currentMillis);}
}

Trouble in MQTT commented code "client.connect(“water_count”) … " , but error not in MQTT lib, but in firmware core.
This is seral output, if I call client.connect(“water_count”):

0 | 94000
0 | 96000
0 | 98000
0 | 100000
0 | 102000 // reboot ended
1 | 104000
1 | 106000
1 | 108000
1 | 110000
1 | 112000
1 | 114000
1 | 116000
1 | 118000
1 | 120000
begin
Wifi_ready, but not mqtt not
client.connect
Publish PSSI
1 | 122000
1 | 124000
1 | 126000
1 | 128000
1 | 130000
1 | 132000
1 | 134000
1 | 136000
// hangout - solid green or led off

OK. After I comented “client.connect” code, that I see:

0 | 668000 // router reboot start
0 | 670000
0 | 672000
0 | 674000
0 | 676000
0 | 678000
0 | 680000
0 | 682000
0 | 684000
0 | 686000
0 | 688000
0 | 690000
begin
WiFi reconect_start
WiFi reconect_end
Publish PSSI
0 | 696000
0 | 698000
0 | 700000 // router reboot end
1 | 702000
1 | 704000
1 | 706000
1 | 708000
1 | 710000
1 | 712000
1 | 714000
1 | 716000
1 | 718000
1 | 720000
begin
Wifi_ready, but not mqtt not
Publish PSSI
1 | 722000
1 | 724000
1 | 726000
1 | 728000
1 | 730000
1 | 732000
0 | 734000 // FAST green blink - reconnect!!!
0 | 736000 // FAST green blink - reconnect!!!
1 | 738000
1 | 740000

So - I hangout if I call “client.connect” between first “dummy connection” and second “true connection”.
Have you see this second reconnection in 30 second on you photon on router reboot?

There is no second reconnection after router reboot sometimes.
Is any debug mode in core OS? How I can research - why my photon make second reconnect in this 30-35 second?
Now I make hack in sketch - wait for 1 min after first automatic photon reconnect, but this is bad practice

Without seeing the whole code things are always a bit complicated (especially when you call functions without shown implementation)

But I’d do a few things different

void loop() {
    currentMillis = millis();
    if (currentMillis - previous_conected >= 30000 || previous_conected > currentMillis)
    {
        previous_conected = currentMillis;
        Serial.println("begin");
        if (!WiFi.ready())
        {
            Serial.println("WiFi reconect_start");
            WiFi.off();
            delay(1000);
            WiFi.on();
            WiFi.connect();
            if (!waitFor(WiFi.ready, 2000)) { // check if this was successful already
              Serial.println("WiFi reconect failed");
            } else {
              if (!client.isConnected()) { // since reconnect worked WiFi.ready() == true anyway
                Serial.println("Wifi_ready, but not MQTT now");
/*
                if (client.connect("water_count"))
                { 
                    Serial.println("client.connect");
                    client.subscribe("home/water_count/spark/set");
                    // how would `Particle.connected()` ever be true ????
                    publish_message("home/water_count/spark", Particle.connected() ? "ON" : "OFF", true);
                    client.subscribe("home/water_count/+/set");
                }
*/
            }
        }
        publish_message("home/water_count/rssi", WiFi.RSSI(), true); // <-- not shown!
        Serial.println("Publish PSSI");
    }
    client.loop(); // <-- does this make sense if !WiFi.ready() or !client.isConnected() ???

    // you won't necessarily see every millis()
    if(currentMillis % 2000 == 0) { Serial.print(WiFi.ready()); Serial.print(" | ");   Serial.println(currentMillis);}
}

You also check Particle.connected() but no Particle.connect() or Particle.process() (especially this is required in MANUAL whenever you want cloud features).

1 Like

Sorry, dont want to paste big amount of code,
I don’t use particle.cloud function (only for dev and flash). So “client” is:

byte server[] = { 192,168,1,23};
MQTT client(server, 1883, callback);

This server in my local network.

publish_message("home/water_count/rssi", WiFi.RSSI(), true); // <-- not shown!

check MQTT connection and publicate mesage to mqtt broker

 client.loop(); // <-- does this make sense if !WiFi.ready() or !client.isConnected() ???

check MQTT connection and make background work for MQTT send\recieve

I fix my other home node - light and ventilation control - and make video with this second reconnect. This reconnection main troublemaker.

My resulting code (after my hack with wifi_uptime control):

// This #include statement was automatically added by the Particle IDE.
#include "MQTT/MQTT.h"


#define DEBUG 0
SYSTEM_THREAD(ENABLED);
SYSTEM_MODE(MANUAL);
STARTUP(WiFi.selectAntenna(ANT_INTERNAL));

unsigned long currentMillis = 0;

void callback(char* topic, byte* payload, unsigned int length);

byte server[] = { 192,168,1,23};
MQTT client(server, 1883, callback);

unsigned long previous_conected = 100000; //финт ушами 
unsigned long previous_wifi_uptime = 100000; //финт ушами 
unsigned long wifi_uptime = 0;

bool publish_message(const char* t, const char* p, bool retain) 
{
    return client.publish(t, (uint8_t*)p, sizeof(p), retain);
}

bool publish_message(const char* t, int p, bool retain) 
{   
    char buf5[12];
    int n = sprintf(buf5,"%d",p);
    return client.publish(t, (uint8_t*)buf5, n, retain);
}

// recieve message
void callback(char* topic, byte* payload, unsigned int length) {
    char p[length + 1];
    memcpy(p, payload, length);
    p[length] = NULL;
    String message(p);
    String t(topic);
    if (t.equals("home/water_count/spark/set"))
    {
        cloud_tink(message.equalsIgnoreCase("ON"));
    }
}

void setup() {
#if DEBUG == 1    
    Serial.begin(9600); Serial.println("Serial Start");
#endif
    WiFi.on();
    WiFi.connect();
    if (waitFor(WiFi.ready, 5000)) 
    {
        mqtt_connect();
    }
}

void loop() {
    
    currentMillis = millis();
    // проверяем наличие сети и подключения к MQTT брокеру
    if (currentMillis - previous_conected >= 30000 || previous_conected > currentMillis)
    {
        previous_conected = currentMillis;
        if (!client.isConnected() & wifi_uptime > 60)
        {
            mqtt_connect();
        }
        publish_message("home/water_count/rssi", WiFi.RSSI(), true);
    }
    if (currentMillis - previous_wifi_uptime >= 1000 || previous_wifi_uptime > currentMillis)
    {
        previous_wifi_uptime = currentMillis;
        WiFi.ready() ? wifi_uptime++ : wifi_uptime = 0;
    }
    client.loop();
}

void mqtt_connect()
{
    if (client.connect("water_count"))
    { //подпись на spark и публикуем послднее состояние
        client.subscribe("home/water_count/spark/set");
        publish_message("home/water_count/spark", Particle.connected() ? "ON" : "OFF", true);
        client.subscribe("home/water_count/+/set");
    }
}

void cloud_tink(bool command)
{
    if (command)
    {
        Particle.connect();
        if (waitFor(Particle.connected, 10000)) 
            {client.publish("home/water_count/spark", "ON");}
        else
            {Particle.disconnect(); client.publish("home/water_count/spark", "OFF");}
    }
    else
    {
        Particle.disconnect();
        client.publish("home/water_count/spark", "OFF");
    }
}

ScruffR, I’m use your code

const uint32_t RETRY = 15000;
uint32_t ms;

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

void loop()
{
    if (millis() - ms > RETRY && !WiFi.ready())
    {
        WiFi.off();
        delay(1000);
        WiFi.on();
        WiFi.connect();
        waitFor(WiFi.ready, 2000);
        ms = millis();
    }
    digitalWrite(D7, (millis() >> 2) & 0x88);
}

upload it to photon and made video. https://youtu.be/xaTEe-20Qh8
00.05 sec - I turn off 2,4G transmitter on router
00.27 sec - particle lost wifi connection
00.35 sec - I turn on 2,4G transmitter on router
00.51 sec - particle first reconnection
01.24-01.30 sec - particle second reconnection.
Why?

Temporary connection losses are not uncommon and can have multiple reasons. They can happen anytime and your code has to be resilient to such things happening.

Does this always happen with my code, or was this just a one-of?

Allways.

Yes, that why I was made check client.connect() && wifi.ready()) before call client.connect().
I think first connnection have some trouble. If I open tcp connect between connections - it hangout on second atempt.
If no tcp connect - after 30-35 sec. photon make reconnect correctly.

That’s an interesting phenomenon which I can’t explain. It even happens in single threaded mode and is independent of the time between reconnect attempts.


See if @mdma has an idea :confused:

Solid green and no loop() work after wifi router reboot. Second reconnect trouble

Solid green used to mean the device was continually attempting to connect to the router and being rejected. This was fixed to continue blinking a long time ago (0.4.3, iirc.)

So you got second reconnect too? Greate! Fuuufff, I’m not alone :smiley:
@mdma I make another video - with android AP. https://youtu.be/bRcRYDjdloo
00.08 sec - I turn off AndroidAP
00.09 sec - particle lost wifi connection (very quike)
00.21 sec - I turn on AndroidAP
00.25 sec - particle first reconnection
00.57 sec - particle second reconnection.

And @mdma - forget about solid green (it can be solid or no led color - it depend on time, then photon hangout).
Help with this second reconnect please. If we fix it - my solid green will fix automatic. Is any debug mode in core OS, then it write debug info in com port?

That I see - second reconnection ocсur in 30-32 second on both wifi access point. Have you some watchdog in CoreOS with this timeout?

Check on 0.4.9 - same issue. Router reboot, first connection, 30-32 second and reconnect.