Electron sleep problems, yet again


@rickkas7 Thanks, The reason for using cellular_off was that I thought it was blocking, whereas Cellular.off was not? and I’m running SYSTEM THREAD enabled.

Oh and by bad state, do you mean anything like this?
Occasionally the modem turns off goes into a limbo state with complete system pulling 40ma with slow pulsing green led and code lockup. I have to rely on external watchdog timer to reset it, at which point it enters proper sleep.


Yes, that would be the bad state. And yes, cellular_off is blocking, which is handy for SYSTEM_THREAD(ENABLED) but the bad state problem makes it not worth it.

I use cellular_on(NULL) as that works great, but still use Cellular.off().


Very interesting! I will try that then, so do you put a delay after Cellular.off? I’m running 0.7.0

Also, do you think shutting down by pulling PWR_UC low is a bad idea? as it seems to work, although only tested with about 50 monitored shutdowns.

And just out of interest is Cellular.off not just an abstraction of cellular_off? then both seem to just send the AT shutdown command no?


I had the delay with 0.6.x but I’m not sure it’s necessary anymore. I haven’t done enough tests with 0.7.0 to be absolutely sure it’s not necessary, but I don’t think it is. But 2 seconds at 40 mA isn’t a lot of power either, so I haven’t removed it.

Pulling PWR_UC low might work, but I’m worried it will go into the state it’s in during cold boot with cellular off (1 mA) instead of SLEEP_MODE_DEEP state (130 uA). I haven’t actually tested it, though, so maybe it’s fine.


Ok thanks again, all I want is a bullet proof way of going into 130ua sleep, 4 months of trying and still not there! I have around 200 prototype devices out in the wild and the number of them not going into sleep properly is killing my product.

So, sorry to go over one more time, but… aside from the possible PWR_UC option, do you think this in your experience is the most robust method to go into 130ua deep sleep. …?

//Do whatever, connect to gsm, send sms, cloud connection etc.
cellular_result_t result = -1;
result = cellular_on(NULL);
if (result) {
        if (serialdebug) Serial.println("ERROR: Failure powering on the modem!");
    } else {
        if (serialdebug) Serial.println("Modem ON!");


Yes, I believe that will go into 130 uA sleep always.

Though the jury is still out on whether the delay(2000) is necessary with 0.7.0 or later, it certainly doesn’t hurt anything (except for a little battery life).

Also, you only need to turn on and off the modem on cold boot. I use a retained variable to know that I’ve already powered on and off the modem and don’t go through that again if I already know the modem is off. It’s 0 on cold boot, and I put a magic value in it after waking up the modem.


Yeah I’m keeping tracking of that with a retained variable, got that from your other post :wink:

Ok i will run through it again, but I’m 99.9% sure that i’ve run with…


on 0.7.0 and got occurrences of this… https://photos.app.goo.gl/qMzGUYeSjNv19X1c2


Yep sorry, just tried it again, and I’m in that current draw again, as per video :frowning:


Going to have to run with the below, not ideal, but seems the most reliable.

void hardShutdownModem(void)
    pinMode(PWR_UC, OUTPUT);
    digitalWrite(PWR_UC, LOW);
    digitalWrite(PWR_UC, HIGH);


In that case, run with

SerialLogHandler logHandler(LOG_LEVEL_TRACE);

and capture the USB serial debug output. I’m curious what the modem is doing in your situation.


ok giving that a quick go now and see if i can capture it in that state


Ok I have it in that state now. Nothing coming in on serial obviously, but i do have complete log from cold boot to this state, have PM’d


any insight?


Is that video just after you run the cellular.off() code?

I remember seeing this also for like 30 seconds or so after calling cellular.off() before the modem actually turned OFF and the 130uA sleep current kicked in.

It’s been awhile since I’ve tested this though.


no afraid not, this is 2hrs after :frowning:


Sounds like the modem is still on and communicating with the tower or something.

What pins are you feeding the 3.8v to from the power supply?


Through the Lipo input


After another week of testing (all of the above methods), still no consistency.

It appears there is no reliable way for the electron to enter deep sleep with 130uA current each and every time. Making it completely unusable.



I had fits with sleep too. What I’ve discovered after a lot of trial and error is that in 0.7.0, you don’t need to go through Particle.disconnect() and Cellular.off() in order to get the device into a proper, 130uA sleep mode. In fact, those seem to cause problems and were giving me buffer overflow errors.

Here’s what I do:

    StopTimers();  // I find that any running timers can cause issues with sleep
        //sleep until top of next minute
       System.sleep(SLEEP_MODE_SOFTPOWEROFF, 60-Time.second());

That’s it. System.sleep(…) handles all the disconnections by itself. I do have to explicitly reconnect when the unit wakes with something like:

bool NetworkConnect()
    int tsecs;
    boolean success;
    tsecs = Time.local();


    while (!Particle.connected() && (Time.local() < (tsecs+90) )) {
        Serial.print("NetworkConnect: waiting to connect...\n");
        delay(10); /*wait*/ 
    if (Particle.connected()){
        Serial.print("NetworkConnect: Connected to Cellular\n");
        success = true;
        gModemOn = true;
    else {
        Serial.print("NetworkConnect: Not connected to Cellular\n");
        success = false;

} //NetworkConnect;

I arbitrarily chose a 90 second timeout to return the to the calling function if the network fails to connect. That may be faulty, but that seems to work for now. The above has been reliable for me.

Apologies for the crazy formatting above. I’m not sure why this editor does what it does.



Rickkas7 gave me the tip to initialize the cellular modem at startup. Without doing that, the modem will never sleep properly and you get the crazy approx 40mA current consumption instead of the 130uA sleep mode. My setup for this looks like:

retained int bootCount = 0;


void setup() {

    if (bootCount == 0 ){
} // setup()

The above has been rock solid for initializing proper, low-power mode. Sorry to hear about your problems. I know just how frustrating this is. Can’t thank Rickkas7 enough for straightening me out.


Very nice breakdown!


I have reformatted your code blocks.
If you want to know how it’s done, you can go into the post via the edit icon :memo: or look in this thread