The following code is a snippet from our larger code base for our application. Its been used extensively with 0.6.1 - 0.6.4 firmware on 500+ Electrons. When on 0.6.X, this code results in a deep sleep that will restore connectivity if there is some sort of cellular issue.
On 1.0.1 the code results in a lockup on the call for SLEEP_MODE_DEEP. I’m wondering if anyone can help me parse the issue
#include "application.h"
SYSTEM_MODE(MANUAL);
SYSTEM_THREAD(ENABLED);
STARTUP(System.enableFeature(FEATURE_RETAINED_MEMORY));
SerialLogHandler logHandler(LOG_LEVEL_ALL);
void watchDogOS() {
// It's necessary to turn on the cellular modem in MANUAL or SEMI_AUTOMATIC mode
// before going to sleep. This happens because the modem is put to sleep using AT
// commands, and they don't work when the modem is not on.
Cellular.on();
Log.error("WDRS");
System.sleep(SLEEP_MODE_DEEP, 10);
}
ApplicationWatchdog wd(60000, watchDogOS, 2304);
void cellularOffActuator(uint16_t sleepLength) {
Cellular.off();
Log.error("MODRS%u", sleepLength);
// settings.save();
delay(1000);
if(sleepLength > 0) {
System.sleep(SLEEP_MODE_DEEP, sleepLength);
} else {
System.reset();
}
}
int cellularOff(int type, const char* buf, int len, char* param) {
if(type == TYPE_OK) { cellularOffActuator(1); }
return WAIT;
}
void setup() {
Serial.begin(9600);
while(!Serial.available()) {}
Cellular.on();
delay(500);
if (!Cellular.ready()) {
Cellular.connect();
delay(500);
Particle.process();
waitFor(Cellular.ready, 240000);
if (Cellular.ready()) {
Log.info("Cellular connected");
} else {
Log.error("Cellular could not connect");
}
}
Particle.connect();
waitFor(Particle.connected, 90000);
Log.info("Particle connected");
Log.info("Press any key to continue");
while(!Serial.available()) {}
Log.info("OK starting up");
delay(1000);
}
void loop() {
uint32_t disconnectTimer = millis();
if(Particle.connected()) {
Particle.disconnect();
delay(5000);
while(Particle.connected() && millis() - disconnectTimer < 60000) {}
}
Log.info("Disconnected from Particle");
char response[32] = "";
Cellular.on();
if (RESP_OK == Cellular.command(cellularOff, response, 60000, "AT+CFUN=16\r\n")) {
Log.error("RESSHRT");
} else {
Log.error("ERRMODRES");
cellularOffActuator(1);
}
}
Logs are here: https://www.dropbox.com/s/e53jvg5c6uaqs56/Electron%20Lockup%20Logs%202019-04-04%20-%20All%20Sleep.txt?dl=0
If I replace System.sleep(SLEEP_MODE_DEEP, 10);
with System.reset()
in the Watchdog, the program will reset itself when the watchdog timer expires.
It seems like System.sleep doesn’t work as a reset-type function in v1.0.1 like it did previously?
Why can’t I call System.sleep in this scenario? Do I need to be checking for something before calling System.sleep?
Also, in the logs, the watchdog takes 120 seconds to expire instead of my expected 60 seconds. Why is this? I’ve had this problem for a long time, avoiding trying to get to root cause.