How to tell when resuming from deep sleep

Is there a way to tell via when resuming from deep sleep and not an initial power on state?

I’d like to pause for possible OTA flash on the initial power on and skip this when coming back from deep sleep. Otherwise my fallback was going to be registering the need for a flash with one of my always on devices and have it tell the sleeping device when it next wakes up.

Will your device be completele powered off and not have the battery attached?
If so, you could try if retained variables are already set from a previous go or not (on power up).

Looks like retained variables aren’t available on the Core, according to the compiler. Yes it would have been a full power off, via unplugging the power source.

I wouldn’t think setup() is called when returning from deep sleep. But power-up, yes.

setup() is called after deep sleep, not from the normal sleep though.

that bytes

I see; knowing the target hardware would have helped to no lead you down the wrong path :wink:

It also matters in regards of the sleep state, since the Core doesn’t even have a Stop Mode, so deep sleep and sleep with wake-on-pin cause a re-execution of setup()
On Photon/Electron this only happens after waking from deep sleep.

And “normal sleep” is no sleep at all, just a time-limited WiFi.off() with auto-reconnect.

It’s good information regardless, I have both types so I may swap over and use a Photon for this case. Plus I think the Photon’s don’t run as hot. My original goal for using deep sleep was to minimize the excess heat from impacting my temperature readings; in a lazy software oriented approach :wink:

If you’re going to use a Photon I tested this code and it seems to work quite well.

#include "Particle.h"

STARTUP(System.enableFeature(FEATURE_RETAINED_MEMORY));

const int START_FLAG_COLD_START = 0;
const int START_FLAG_WARM_START = 1;
const int START_FLAG_FROM_SLEEP = 2;

retained int startFlag = START_FLAG_COLD_START;

// On the Photon only: Connect VBAT to GND if not using a coin cell battery. 
// This is necessary otherwise the retained variable
// will not be initialized properly and sometimes it will work and sometimes not.

// Do NOT connect VBAT to GND on an Electron! You will short out the 3.3V regulator!
// Also, this doesn't work properly on the Electron using 0.4.8 because of a problem with
// retained memory.

void setup() {
	Serial.begin(9600);

	// This delay is here so make it easier to see the serial debug at startup
	delay(3000);

	switch(startFlag) {
	default:
	case START_FLAG_COLD_START:
		Serial.println("cold start");
		startFlag = START_FLAG_WARM_START;
		break;
	case START_FLAG_WARM_START:
		Serial.println("warm start");
		break;
	case START_FLAG_FROM_SLEEP:
		Serial.println("from sleep");
		startFlag = START_FLAG_WARM_START;
		break;
	}

}

void loop() {
	// Stay awake for 30 seconds, then sleep for 15 seconds.
	delay(30000);

	// Deep sleep for 15 seconds. When it wakes up, setup() will be run again, but
	// retained variables will be retained, even without a battery!
	startFlag = START_FLAG_FROM_SLEEP;
	System.sleep(SLEEP_MODE_DEEP, 15);
}

/*
 * Disconnect power: cold start
 * Flash code: warm start
 * Reset button: warm start
 * Wake from SLEEP_MODE_DEEP: from sleep
 */

1 Like

Nice, thank you.

1 Like

I am using a system call, the code looks like this:

if(System.resetReason()==RESET_REASON_POWER_DOWN) powerCycled = true;

2 Likes

Thanks, that’s worth an upgrade to 0.6.0 :wink:

More info: https://docs.particle.io/reference/firmware/photon/#reset-reason