It’s a little confusing getting an Electron to go into deep sleep, using the 130 µA that it should. These six annotated code examples should hopefully clear things up.
All tests were run on 0.6.0 on a Electron G350.
AUTOMATIC, no system thread
#include "Particle.h"
void setup() {
}
void loop() {
// Results in 133 uA power consumption
// Modem is turned off, full cellular resync after restart (blinking green, blinking cyan, fast blinking cyan), 5-6K of data usage
System.sleep(SLEEP_MODE_DEEP, 30);
// This part not reached; sleep mode deep starts over again after setup()
}
SLEEP_MODE_SOFTPOWEROFF
#include "Particle.h"
void setup() {
}
void loop() {
// Resulted in 91.5 uA power consumption
// SLEEP_MODE_SOFTPOWEROFF turns off the fuel gauge in addition to normal SLEEP_MODE_DEEP
// Modem is turned off, full cellular resync after restart (blinking green, blinking cyan, fast blinking cyan), 5-6K of data usage
System.sleep(SLEEP_MODE_SOFTPOWEROFF, 30);
// This part not reached; sleep mode deep starts over again after setup()
}
MANUAL, no system thread (failure example)
#include "Particle.h"
// This behaves the same for SEMI_AUTOAMTIC and MANUAL
SYSTEM_MODE(MANUAL);
void setup() {
}
void loop() {
// Note the use of SYSTEM_MODE(MANUAL) or SYSTEM_MODE(SEMI_AUTOMATIC).
// Resulted in 0.70 mA (700 uA) power consumption, with occasional spikes higher
// It should be 130 uA, but it's not because the modem wasn't really powered down
// properly because it was never turned on.
// See the following example for a workaround. Don't do this.
System.sleep(SLEEP_MODE_DEEP, 30);
// This part not reached; sleep mode deep starts over again after setup()
}
MANUAL, no system thread (good example)
#include "Particle.h"
// This behaves the same for SEMI_AUTOMATIC and MANUAL
SYSTEM_MODE(MANUAL);
void setup() {
}
void loop() {
// 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();
// Resulted in 132 uA power consumption, as it should
System.sleep(SLEEP_MODE_DEEP, 30);
// This part not reached; sleep mode deep starts over again after setup()
}
MANUAL, system thread (failure example)
#include "Particle.h"
// This behaves the same for SEMI_AUTOMATIC and MANUAL
SYSTEM_MODE(MANUAL);
// Unlike the previous example, this enables system thread
SYSTEM_THREAD(ENABLED);
void setup() {
}
void loop() {
// 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();
// Resulted in numbers all over the place, 60 mA, sometimes more, sometimes less.
// The problem is that in system threaded mode, Cellular.on() is asynchronous so it doesn't
// finish starting up before sleeping, so SLEEP_MODE_DEEP fails to really put the modem
// into sleep mode.
// See the following example for a workaround. Don't do this.
System.sleep(SLEEP_MODE_DEEP, 30);
// This part not reached; sleep mode deep starts over again after setup()
}
MANUAL, system thread (good example)
#include "Particle.h"
// This behaves the same for SEMI_AUTOMATIC and MANUAL
SYSTEM_MODE(MANUAL);
SYSTEM_THREAD(ENABLED);
void setup() {
}
void loop() {
// 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();
// This workaround appears to be necessary when using SYSTEM_THREAD(ENABLED).
// The reason is that .on() and .off() are asynchronous in system threaded mode
// and if the calls don't complete, sleep mode is not properly entered.
delay(2000);
// The Cellular.off() requirement is probably a bug. I think it's because when
// going to sleep in system threaded mode, it's not waiting for the modem to actually
// go to sleep. As of 0.6.0 it's necessary, otherwise you drop in a weird mode that
// ends up using 2.8 to 60 mA instead of 132 uA.
Cellular.off();
delay(1000);
// Resulted in 132 uA power consumption, as it should
System.sleep(SLEEP_MODE_DEEP, 30);
// This part not reached; sleep mode deep starts over again after setup()
}