There’s one more useful case: If, for example, you wake up, read a sensor, and go back to sleep, you don’t need to turn the cellular modem on then off again unless it was a cold boot. If the modem was already in sleep it will stay asleep and you’ll still have low power consumption.
In this example, you get two fast sleeps (awake for 2 seconds), and the third time it stays awake long enough to publish.
With this code running on system firmware 0.7.0 I got 160 uA after sleep after cold boot, after sleep after warm boot, and after sleep after publishing.
#include "Particle.h"
#include "cellular_hal.h"
SYSTEM_MODE(SEMI_AUTOMATIC);
SYSTEM_THREAD(ENABLED);
void startup();
STARTUP(startup());
SerialLogHandler logHandler(LOG_LEVEL_TRACE);
const unsigned long SLEEP_PERIOD_SEC = 30;
retained int bootCount = 0;
bool forceModemOff = false;
bool publishEvent = false;
void startup() {
System.enableFeature(FEATURE_RESET_INFO);
System.enableFeature(FEATURE_RETAINED_MEMORY);
}
void setup() {
Serial.begin(9600);
switch(System.resetReason()) {
case RESET_REASON_POWER_MANAGEMENT:
case RESET_REASON_POWER_DOWN:
case RESET_REASON_POWER_BROWNOUT:
// Probably a cold boot
forceModemOff = true;
break;
}
bootCount++;
// Every third boot publish an event
publishEvent = ((bootCount % 3) == 0);
}
bool notConnected() {
return !Particle.connected();
}
void loop() {
if (publishEvent) {
// Publishing an event
Log.info("going to publish an event");
Particle.connect();
if (waitFor(Particle.connected, 90000)) {
// Wait up to 90 seconds to connect to the cloud
char buf[256];
snprintf(buf, sizeof(buf), "bootCount=%d", bootCount);
// Wait for the publish to complete before proceeding
Particle.publish("testBoot", buf, PRIVATE, WITH_ACK);
Log.info("published %s", buf);
}
// Disconnect from the cloud
Particle.disconnect();
waitFor(notConnected, 15000);
// Turn off the modem as well.
Cellular.off();
// Wait a few seconds to makes sure modem is actually off
delay(2000);
}
else {
// Not publishing an event
if (forceModemOff) {
// From a cold boot we need to wake the modem up to put it into deep sleep.
Log.info("forceModemOff - powering up and down modem");
// In order to put the modem in deep sleep mode from a cold boot, you need to power it
// in first. cellular_on from cellular_hal.h is blocking in system threaded mode,
// so it eliminates the delay in the other examples.
cellular_on(NULL);
// cellular_off (in cellular_hal.h) IS blocking in system thread mode, eliminating the need
// for a delay as in the other examples.
cellular_off(NULL);
}
else {
Log.info("only staying awake for 2 seconds");
// Otherwise only stay awake for 2 seconds and go back to sleep.
// This simulates waking up, taking a sensor reading, then going back to sleep.
delay(2000);
}
}
System.sleep(SLEEP_MODE_DEEP, SLEEP_PERIOD_SEC);
// This line not reached; after waking up from SLEEP_MODE_DEEP you start over with
// startup, setup, and loop again as if reset.
}