Dear all,
We are developing a device based on Electron that is supposed to work in wake/sleep cycles. Wake-up for just short jobs up to 2 min (registers in cellular network and particle, publishes identification data about cellular tower and falls asleep for days to save energy. We chose to use System.sleep(SLEEP_MODE_DEEP, TIME_VARIABLE) as the most appropriate power saving mode (keeps the battery gauge and consumes very small current).
Below is a simplified firmware we have for now but I am seeking for feedback on what you think could be done better, if any. The firmware works ok in my office.
#pragma PARTICLE_NO_PREPROCESSOR
#include "Particle.h"
SYSTEM_MODE(AUTOMATIC);
SYSTEM_THREAD(ENABLED);
char cellular_data[200] = "";
int cb(int type, const char* buf, int len, char* cellular_data);
//This function to use instead delay() to avoid blocking code - period in milliseconds
void mydelay(int period);
//This function to start deep sleep mode
void sleepInMinutes(void);
void setup() {
mydelay(60000);
//need to wait for 60 sec to allow enough time for cellular and particle connect if possible
}
void loop() {
if ((RESP_OK == Cellular.command(cb, cellular_data, 10000, "AT+CGED=3\r\n"))
&& (strcmp(cellular_data, "") != 0)) {
Serial.printlnf("Cellular info: %s\r\n", cellular_data);
} else {
Serial.printlnf("Cellular info not found");
}
if (strlen(cellular_data) > 0) {
Particle.publish("cellData", cellular_data, PRIVATE);
//To obey publish limit
mydelay(1000);
//Reset string to not publish the same one again
cellular_data[0] = '\0';
}
sleepInMinutes();
}
int cb(int type, const char* buf, int len, char* cellular_data) {
if ((type == TYPE_PLUS) && cellular_data) {
if(sscanf(buf, "\r\n+CGED: %[^\r]\r\n", cellular_data) == 1)
/*nothing*/;
}
return WAIT;
}
void sleepInMinutes(void) {
Particle.publish("Sleep", "Go To Deep Sleep For 3 minutes", PRIVATE);
Particle.disconnect();
mydelay(5000);
Cellular.disconnect();
Cellular.off();
//sleep for 20 minutes for testing only, will be days
System.sleep(SLEEP_MODE_DEEP, 180);
}
void mydelay(int period) {
int time_now = millis();
//using millis() instead of delay() to avoid blocking code & delay 1 second before deep sleep
while(millis() < time_now + period){
//wait delay ms
}
}
My alternative code would be to do explicitly
void loop() {
Cellular.on();
if(Cellular.ready()){Cellular.connect();};
Particle.connect();
//the rest of the loop() code as above
}
but my developer says that it is redundant because after System.sleep() it goes to setup() where the above jobs get implicitly done by setup() and, additionally, we allow up to 60 sec for completion of these jobs by mydelay() for doing exactly cellular.on() and then cellular.connect() and particle.connect(). Maybe it could be done better to avoid some not so obvious glitches or the above code is fine as is. Thank you
Regards
Dmitry