Electron SLEEP_MODE_DEEP tips and examples

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.

}
5 Likes