Sleep 2.0 Use cases - optimal duration for keeping network on

So I am just starting to play around with the new Sleep configuration with LTS 2.0.1. I had 2 questions was hoping for some guidance on. 1) Do we still need to execute a “disconnectFromParticle()” with something like what’s shown below to reach lowest power sleep. This was referenced in the earlier version of system.sleep() before 2.0 as a way to reach lowest power consumption. It’s what I’ve been using previously. Just didn’t know if I can clean it up and just use the new version of SystemSleepConfiguration config or do i need to keep this before falling asleep.

bool disconnectFromParticle()                                     // Ensures we disconnect cleanly from Particle
{
  Particle.disconnect();
  waitFor(notConnected, 15000);                                   // make sure before turning off the cellular modem
  Cellular.off();
  delay(2000);                                                    // Bummer but only should happen once an hour
  return true;
}
  1. Any clear guidance on what the threshold would be where a person is better off to keep the network on with .network(NETWORK_INTERFACE_CELLULAR, SystemSleepNetworkFlag::INACTIVE_STANDBY) vs turning it off if the goal was for maximum battery life? Is there a magical number of minutes where it makes more sense to turn network off?

I know the docs say les than 10 minutes keep the network up to prevent your SIM from being banned for aggressively reconnecting to the cellular network and after 23 minutes the keep alive would of expired which extends the reconnection time. But my question is what about durations of time > 10 minutes and less than 23 minutes? What would be the threshold where it’s better to turn network off and sleep vs keeping network on? I also understand you will get better battery life if you reconnect every 20 minutes 3x per hour rather than every 30 minutes or 2X per hour simply due to longer handshake required due to the keep alive time expiring.

Today I take readings and fall back asleep every 5 minutes and then on the 4th cycle of this (i.e. every 20 minutes before the keep alive expires) it turns on cellular, connects to the cloud, publishes the all the readings it took and then falls back asleep. My goal is to maximum battery life but still provide readings at a minimum every 20 minutes. Should I sleep with keeping network on and send data every 5 minutes, or keep doing what I’m doing and only turn cellular on every 20 minutes?

Does this just depend mostly on how good of cellular coverage it has which determines how fast the reconnect is? I.e. if a device is in a weak cellular coverage area it seems like it could take 2-3 minutes at times to connect. During this entire time, it’s using up a lot of power. rather in this scenario, am I better off leaving network on? vs. a device near a cell tower may only take 20 seconds to reconnect.

Finally, does anyone have economical recommendations you have for hardware I can use to properly measure power consumption to test different scenarios.

Here is what I plan on using:

// EXAMPLE 2
SystemSleepConfiguration config;
config.mode(SystemSleepMode::ULTRA_LOW_POWER)
      .duration(15min)
      .network(NETWORK_INTERFACE_CELLULAR, SystemSleepNetworkFlag::INACTIVE_STANDBY);
  1. Do we still need to execute a “disconnectFromParticle()” with something like what’s shown below to reach lowest power sleep.

Not necessary anymore, except in one case: If you are currently connected, and want to wake up in a disconnected state because you don’t want to connect every time, then you should disconnect before sleep for ULTRA_LOW_POWER or STOP sleep modes with cellular off. Upon wake, the network will restore to its previously connected state so by default it will reconnect.

  1. Any clear guidance on what the threshold would be where a person is better off to keep the network on with .network(NETWORK_INTERFACE_CELLULAR, SystemSleepNetworkFlag::INACTIVE_STANDBY) vs turning it off if the goal was for maximum battery life? Is there a magical number of minutes where it makes more sense to turn network off?

There are too many variables to determine the exact value that will work in every case.

Today I take readings and fall back asleep every 5 minutes and then on the 4th cycle of this (i.e. every 20 minutes before the keep alive expires) it turns on cellular, connects to the cloud, publishes the all the readings it took and then falls back asleep. My goal is to maximum battery life but still provide readings at a minimum every 20 minutes. Should I sleep with keeping network on and send data every 5 minutes, or keep doing what I’m doing and only turn cellular on every 20 minutes?

It’s hard to stay for sure. Staying with the scheme you have will probably use the least power.

The closer you get to 10 minutes the more likely staying connected to cellular will use less power.

While not necessary in your case, the other reason to stay connected is if you need to able to wake the device from the cloud, for example by variable or function call. That’s possible when you use wake on network with cellular on.

Does this just depend mostly on how good of cellular coverage it has which determines how fast the reconnect is?

This is one of the variables. If you have a good cellular connection with LTE Cat M1, the connection can be very fast, so turning cellular off will almost always use less power, subject to the 10 minute aggressive reconnection limit.

If you are regularly seeing several minute reconnect times, then staying connected will save power.

Finally, does anyone have economical recommendations you have for hardware I can use to properly measure power consumption to test different scenarios.

There are three devices that we use, two of which are not inexpensive.

The Qoitech Otii Arc is the main device we use. It’s a power supply and accurately measures current including small spikes. It also has a neat feature where it can capture serial data and correlate it to the power graph. We redirect USB debug serial to Serial1 and use that feature frequently.

I also have a Siglent SDM3055 on my desk, which is what I used before the Otii. It can log power consumption over USB to a Windows app.

The uCurrent Gold can be used to solve the burden voltage issue and change current ranges when using an inexpensive DMM.

Thanks @rickkas7. Your suggestions just helps speed up my development and learning.

I did have one additional question… Sounds like I’ll need to continue to disconnectFromParticle() and then re-connect every 20 minutes. However, when I reconnect, I still am recieving vitals even though I call Particle.PublishVitals(0). I don’t recall this happening with the old sleep method I was using but now seems to happen every time with the new sleep method. I even commented out any instance of Particle.PublishVitals(0) to make sure my sketch wasn’t doing it. Is this just a consequence of the new version of system.sleep(). Is there anything that can be done to stop publishing this every 20 minutes. I normally published it every 2 hours so just burning up more data and I assume power than I’d like to.

I also appreciate the recommendations for power measurement devices as well! Based on this and some google searching I decided to go with the CurrentRanger from lowPowerLabs. CurrentRanger
I believe it has the same principles as the uCurrent Gold but a few additional features. I already have a Fluke Multimeter so will use that paired with the CurrentRanger to help me learn all of this further. Here was a decent video explaining the two: https://youtu.be/HmXfyLyN38c

And another question… in testing keeping network connected during sleep, about 80% of the time it behaves exactly as expected (i.e. wakes up and immediately connects in maybe 1-3 seconds, publishes the data it needs to and then falls right back asleep). This is AWESOME! Super excited in having this flexibility for short sleep durations. However, the other roughly 20% of wake-ups, it spends 60-180 seconds doing the “fast blinking” which I believe is “Connecting to the Cloud”. My understanding of this is it still is connected to the cell tower but doing the handshake with the Particle cloud. Status LED and Device Modes - Boron | Tutorials | Particle Why would this be lost and why would this take so long as normally this phase of establishing a connection seems to be very quick. If I don’t sleep, the device will stay connected to particle for days so I doubt it’s due to cellular connectivity.

Here is a log file I was able to capture (difficult as I have to start the serial monitor (i.e. Putty) immediately when it wakes up. As you can see in this debug log, it seems to have lost connection with the particle cloud and spend 145 seconds before it was connected.

0041308752 [app] INFO: stat message: 
{"254":1610124900,"4":13945,"3":800,"1":1,"                                                                                                         5":1,"252":78,"255":-115}
0041308753 [app.pubq] INFO: queueing eventName=Stat data={"254":1610124900,"4":1                                                                                                         3945,"3":800,"1":1,"5":1,"252":78,"255":-115} ttl=60 flags1=1 flags2=2 size=84
0041308755 [app] INFO: {"prevState": st_PubStat, "newState": st_Connect, "millis                                                                                                         ": 41308755, "elpsdms": 1617, "elpsdTimeInState_ms": 1615}
0041308757 [app] INFO: lost cloud connection
0041454303 [comm.protocol.handshake] INFO: Skipping HELLO message
0041454408 [comm.protocol] INFO: Checksum has not changed; not sending application DESCRIBE
0041454409 [comm.protocol] INFO: Checksum has not changed; not sending subscriptions
0041454640 [comm.protocol] TRACE: Reply recieved: type=2, code=0
0041454641 [comm.protocol] TRACE: message id 597 complete with code 0.00
0041454642 [comm.protocol] TRACE: rcv'd message type=13
0041454679 [comm.protocol] TRACE: Reply recieved: type=2, code=0
0041454679 [comm.protocol] TRACE: message id 598 complete with code 0.00
0041454681 [comm.protocol] TRACE: rcv'd message type=13
0041454692 [comm.protocol] TRACE: Reply recieved: type=2, code=0
0041454693 [comm.protocol] TRACE: message id 599 complete with code 0.00
0041454694 [comm.protocol] TRACE: rcv'd message type=13
0041454794 [system] INFO: Cloud connected
0041454795 [app] INFO: cloud connected in 146038 ms
0041454795 [app.pubq] INFO: publishing Stat {"254":1610124900,"4":13945,"3":800,"1":1,"5":1,"252":78,"255":-115} ttl=60 flags=3
0041454800 [app.pubq] INFO: published successfully

This is what I’m using to sleep. Works most of the time but would like to avoid the several minute cloud reconnection.

case st_SleepWNetwork:
      {
      //Stop the Watchdog
      ab1805.stopWDT();

      //Configure for sleeping but keep the cellular connected for fast reconnect
      SystemSleepConfiguration config;
      config.mode(SystemSleepMode::ULTRA_LOW_POWER)
            .duration(slpTimems)
            .network(NETWORK_INTERFACE_CELLULAR, SystemSleepNetworkFlag::INACTIVE_STANDBY);
      System.sleep(config);

      //Resume the Watchdog once awake
      ab1805.resumeWDT();
      ab1805.updateWakeReason();
      newState = st_rptStrt;
      }
      break;

However, when I reconnect, I still am recieving vitals even though I call Particle.PublishVitals(0).

That’s expected, if not slightly annoying. publishVitals(0) sets it to not send vitals after sending them once. There is no way to stop it from sending any vitals.

If you use a STOP or ULTRA_LOW_POWER sleep mode with cellular active, the cloud connectionis is never broken so the vitals won’t be sent again. But in all other cases, including using INACTIVE_STANDBY mode, vitals will be sent on wake.

it spends 60-180 seconds doing the “fast blinking” which I believe is “Connecting to the Cloud”

It shouldn’t take that long, however, the reason it needs to reconnect to the cloud is the use of the SystemSleepNetworkFlag::INACTIVE_STANDBY option.

If you use .network(NETWORK_INTERFACE_CELLULAR then the modem is left on so it does not need to go through the connecting to tower (blinking green) step.

If you use INACTIVE_STANDBY then the cloud is disconnected before sleep. This prevents cloud requests like functions, variables, OTA, and subscriptions from waking the device. However, as a side-effect, it also means on wake that it needs to reconnect to the cloud (blinking cyan). It will also resend device vitals.

If you do not use INACTIVE_STANDBY then both the cellular and cloud connections are left up. As long as you sleep less than the keep-alive value (23 minutes) the connection will stay alive and not have to reconnect at all. This is the lowest data usage, and also does not resend vitals.

Alright, understood. Thanks for clarifying! I don’t have a problem with waking the MCU with received data so I’ll switch to this mode by dropping the flag.

  • Maybe this can be a feature request for a future release to have an option to only send vitals when calling Particle.PublishVitals() and to disable the background publish that happens automatically upon reconnect. Not a huge deal for me but might save me some data and power.

Might be worth updating the docs portion explaining this further with this undesirable side affect:
https://docs.particle.io/reference/device-os/firmware/boron/#network-systemsleepconfiguration-

Currently says:

The second example adds the SystemSleepNetworkFlag::INACTIVE_STANDBY flag which keeps the cellular modem powered, but does not wake the MCU for received data. This is most similar to SLEEP_NETWORK_STANDBY .

However, it doesn’t mentioned it will require additional time when waking up to reestablish connection to Particle. I’m thinking it should say something like this: INACTIVE_STANDBY flag which keeps the cellular connection established but disconnects the device from the particle Cloud preventing it from waking up the MCU for received data. Using this mode does require additional time for the device to reestablish connection to the Particle Cloud. This can add between 30-180 seconds before establishing connection when it wakes up.

Thanks!