Electron Watchdog Troubleshoot

Every now and then my electron freezes up and I want to use watchdog to restart the device. However, every time I implement watchdog I lose all my functions, I lose connection to the cloud and my electron stop sending GPS coordenates (I’m using Asset tracker).

What I’m doing wrong?

With a vague description and without seeing code we can only speculate.

Sorry, here it is:

// This #include statement was automatically added by the Particle IDE.
#include <AssetTrackerRK.h>

PRODUCT_ID(6681);

PRODUCT_VERSION(11);

const unsigned int VERSION_NUMBER = 11; //Cambios realizados para que la funcion de la consola responda este numero y asi saber que el electron esta corriendo esta verson de código

int transmittingData = 1;

long lastPublish = 0;

int delaySeconds = 10;

float bikeBatt = analogRead(A0);

AssetTracker t = AssetTracker();

FuelGauge fuel;

STARTUP(cellular_credentials_set("ott.iot.attmex.mx", "", "", NULL));

void setup() {
    
    t.begin();
    
    t.gpsOn();
    
    t.antennaExternal();
    
    Serial.begin(9600);
    
    Particle.function("tmode", transmitMode);
    Particle.function("LiPo", LiPoStatus);
    Particle.function("gps", gpsPublish);
    Particle.function("BikeBattery", bbPublish);
    Particle.function("Version", fVersion);
    
}

void loop() {
   
   t.updateGPS();
   
    if(millis()-lastPublish > delaySeconds*1000){
        
        lastPublish = millis();
        int iBikeBatValue = getBikeBatt();
        
        Serial.println(t.preNMEA());
        
        if(t.gpsFix()){

            if(transmittingData){
                //Al publicar los datos del gps mandar tambien el estado de la bateria
                //Particle.publish("G", t.readLatLon(), 60, PRIVATE);
                char buffer[128];
                snprintf(buffer, sizeof(buffer), ",%d,%d", 0, iBikeBatValue);
                String cadena = String::format("");
                cadena = cadena + t.readLatLon() + buffer + "";
                Particle.publish("AWSTEST", cadena, PRIVATE); //Aqui mandamos el estado de la bateria y la localizacion

            }
            
            Serial.println(t.readLatLon());
            
        }
        
    }
}


int transmitMode(String command){
    transmittingData = atoi(command);
    return 1;
}

int gpsPublish(String command){
    if(t.gpsFix()){ 
        Particle.publish("G", t.readLatLon(), 60, PRIVATE);

        return 1;
    }
    else { return 0; }
}

int LiPoStatus(String command){

    Particle.publish("L", 
          "v:" + String::format("%.2f",fuel.getVCell()) + 
          ",c:" + String::format("%.2f",fuel.getSoC()),
          60, PRIVATE
    );

    if(fuel.getSoC()>10){ return 1;} 

    else { return 0;}
    
}
    
int bbPublish(String command){
    
    Particle.publish("B", String::format("%.2f", bikeBatt), 60, PRIVATE);

}

int fVersion(String c){
    return VERSION_NUMBER;
}


int getBikeBatt() {
    int lecturaA0 = 0;
    double sumaLectura = 0;
    double lectura = 0;
    for ( int i = 0; i < 100; i++ ) {
        lecturaA0 = analogRead(A0);
        sumaLectura += lecturaA0;
    }
    lectura = (sumaLectura / 100);
    
    return lectura;
    
}

Two things I see at first glance. Your variable lastPublish is declared as long… it should be unsigned long. I believe the default declaration would be a signed long and may cause issues. Also, can you move your function declarations to the top of the setup? There was another thread recently about declaring variables and functions as soon as possible in the setup.

I don’t see your implementation of the watchdog in this code.

Also, the use of Strings could lead to stack corruption as @ScruffR is always reminding people, which could lead to lockup after some time.

1 Like

Great! Thanks for the feedback… Where would you recommend I put the watchdog function?

To extend @ninjatill's comment about String

What's that mix-n-match with char[] and String?

                snprintf(buffer, sizeof(buffer), "%s,%d,%d", (const char*)t.readLatLon(), 0, iBikeBatValue);
                Particle.publish("AWSTEST", buffer, PRIVATE); //Aqui mandamos el estado de la bateria y la localizacion

This should do the same thing with less effort and risk for heap fragmentation.
Apart from the superfluous action to "concatenate" to an empty string and append another empty string at the end.
And snprintf() is the way to go with all these other String instances too.

The docs do provide code snippets for that.
https://docs.particle.io/reference/firmware/photon/#application-watchdog

1 Like

Also, you appear to be using a 3rd-party SIM card, but are not setting the keepAlive value. This will almost certainly cause problems.

I’m not sure what the value is for AT&T in Mexico, but for AT&T in the United States it’s 30 seconds. If you don’t set the keepAlive, you’ll be unable to use functions, variables, subscribe, and OTA code flash reliably.

https://docs.particle.io/faq/particle-devices/electron-3rdparty-sims/electron/#about-keep-alive

2 Likes

Thanks! I’ll try it right away!

Well I’m pushing to the cloud my bike info every 10 seconds. Do I still need keepAlive?

No, as long as you are publishing with a period less than the keepAlive you don’t need to set it.

However, if you don’t have a GPS fix you won’t be publishing, so would lose your cloud connection until you got a GPS fix again in that case. There’s really no downside to setting the keepAlive; they are only transmitted if needed, so in your case they would rarely be needed but it’s good to have it set just in case.

3 Likes