ApplicationWatchdog creating failure

I have a number of devices in the field that seem to lose connectivity and stay disconnected until they get reset. As such, I would like to implement a watchdog timer that basically checks if the device has been connected in the last hour and, if not, reboots the device.

The problem that I’m running into is that when I implement this on the Argon, it seems to reboot every 60 - 90 seconds, and I’m not sure why. IT seems to work just fine on the Boron.

Relevant code below.


//Declare WatchDog
ApplicationWatchdog *wd;

bool hasSetKeepAlive = false;  // set whether the KeepAlive is still running for particle.Keepalive workaround

/
void setup() {
    
    wd = new ApplicationWatchdog(3600000, System.reset(RESET_NO_WAIT), 1536);
  
    // initialize methods
    Serial.println("Initializing objects");
    RegisterList::initialize(); 
    CloudFunctions::initialize();
    g_status = "booting";
    g_meterPtr = &meter;
    meter.enableTXpin(D7);
    meter.begin(BAUD_RATE);
    // connect particle to cloud
    Serial.println("connect to the cloud");
    Particle.keepAlive(CELL_KEEP_ALIVE);
    Particle.connect();
    // setup serial connection for local debugging
    
    Serial.println("Begin delay");
    // wait until connection is open
    while(!Particle.connected()) {
        delay(100);
    }
  

void loop() {
    // sync clock with the cloud (once per day)
    if (millis() - lastSync > ONE_DAY_MILLIS) {
        Particle.syncTime();
        lastSync = millis();
    }
    // set system clock cloud variable
    g_systemTime = Time.format(Time.now(),"%F %T");
    
	if (Particle.connected()){
		wd -> checkin();
	}
	
	
}

and I’m not sure why. IT seems to work just fine on the Boron.

Possibly when you implement code targeted for a cellular device onto a wifi device?
Have you got SYSTEM_THREAD(ENABLED);?
In loop()
The application watchdog isn’t for lack of internet / cloud connection it is really for catching a hang condition in the application loop.

To track the time disconnected I would use a millis() timer something like this;

if (Particle.connected()) {
  time_disconnected = 0UL;
}
else if (time_disconnected > 0UL && millis() - time_disconnected >= 3600000UL) {
  System.reset();
}
else {
  time_disconnected = millis();  //start of disconnection timer
}
1 Like

oh, I definitely do have SYSTEM_THREAD(ENABLED); I didn’t realize that was cell only.

You need SYSTEM_THREAD(ENABLED); otherwise the Particle. calls will be blocking - nothing to do with cell only.

Oh, well yes. SYSTEM_THREAD(ENABLED); is one of the first things I implement. I had assumed, because it was next to the comment “Possibly when you implement code targeted for a cellular device onto a wifi device?” that the two were related. The code otherwise works just fine on the Argon - there’s no cell specific code that is breaking anything that I’m aware of, other than that the watchdog works on the boron and not the Argon.

I used the boron rather than another counter because I wanted to initialize during setup(), but check in during loop(), but perhaps that’s faulty reasoning.

wd = new ApplicationWatchdog(3600000, System.reset(RESET_NO_WAIT), 1536);

I don’t think this is right. The second parameter should be function pointer, which System.reset is. System.reset(RESET_NO_WAIT) is the result of calling a function, which is not the same.

The easiest solution is to create a function like the example in the docs.