Particle Electron Sleep() duration limitations: are there any?

Hi there. I’ve recently modified my Particle Electron code to do a lot more sleeping, trying to get 30 days life off the battery. Depending on how active I expect to be, my code either calls:

System.sleep(WKP, RISING, sleepForSeconds, SLEEP_NETWORK_STANDBY) with a sleep duration of up to 10 minutes, or:

System.sleep(SLEEP_MODE_DEEP, sleepForSeconds), with a sleep duration of up to 2 hours.

When my code wakes up and decides it needs to send something it calls:

Particle.connect();
waitFor(Particle.connected, 60);

…and then:

Particle.publish("thing", "thing", 60, PRIVATE);

I’m never interested in downlink stuff from the cloud, only uplink Publishes, hence I don’t call Particle.process().

However, with this build on multiple devices I’m finding that around 30% of them mysteriously fail to send stuff to the Particle cloud after a little while. It may, of course, be my bug but I’m having immense trouble finding it and, browsing here, I see there is some suggestion of an upper limit on the sleep time one can use and still expect to successfully publish afterwards. So my question is:

Is there a limitation on how long one can sleep a Particle Electron board and then expect to successfully connect (within 60 seconds) and publish (within 60 seconds) to the Particle cloud afterwards?

This is with firmware 0.5.1 and MANUAL mode.

Further on this, I have some data (saved away in retained RAM so that I can read it out after waking up from a reset) which suggests that System.sleep(SLEEP_MODE_DEEP, sleepForSeconds) is not always waking me up at the specified time. The scenario is as follows:

  1. I call Particle.connect() and wait for 60 seconds for it to succeed, as above.
  2. It fails.
  3. I call System.sleep(SLEEP_MODE_DEEP, 30).
  4. I never wake up.

Is it true that, though my waitFor() condition has timed out, there might be processing still going on in Particle code? I’m wondering if the setting of the RTC wake-up interrupt when going to sleep is being confused by the tail-end of the connection process, possibly it even succeeds in the background, and somehow I end up with a wake-up time in the past? This is quite difficult to reproduce, occurring on a percentage of devices only

Is there anything I can do, something I can call (Cellular.off() or Particle.disconnect()) at my connection time-out, which would workaround such a potential problem?

Do your devices end up in Listening Mode (blinking blue)?
But you should move to 0.5.2 or even give 0.5.3-rc.1 a try. AFAIK there was a problem with RTC and/or longish sleep periodes.

In the fail case it’s difficult to tell as they are inside opaque plastic boxes. Unfortunately I’ve not yet managed to get one “out in the open” and in a fail case when I happen to be watching the LED. Is there somewhere I can look at the fix list for 0.5.2 or 0.5.3-rc.1 to see if there’s a fail case that fits my scenario?

This is the thread that informs about new releases

Particle Firmware Updates Thread

And here you can see known issues (past/closed and present/open)

https://github.com/spark/firmware/issues

1 Like

Many thanks.

Can’t see anything in the fix lists for 0.5.2 or 0.5.3-rc.1 that looks like they would fix my problem. We’re meant to have sent these devices to a customer already so I’m slightly loathe to risk a core firmware update in any case. As I understand it, since I’m running single-threaded, my waitFor() on connect doesn’t do anything anyway, the Particle.connect() call just times out when it wants to, so I don’t really have any control when the Particle code stops acting at a connect, but presumably it’s stopped doing whatever it does before control returns to my code?

The evidence I have, until I find a bug in my own code, suggests that calling System.sleep(SLEEP_MODE_DEEP, sleepForSeconds), either with small values of sleepForSeconds (30 seconds or less) or after a connection failure, can sometimes not wake up at all. Just wish I could tie it down more specifically but it is a statistical problem and takes some time to reproduce.

This was an issue I filed a while ago about waitFor() and @mdma (Particle Senior Dev) responded.
Maybe this helps, or you could chime in on that issue (or any other that issue that might fit your symptoms - even opening a new one) with a comment to increase priority

https://github.com/spark/firmware/issues/1028

OK, I think I’ll hang fire until I’ve got more data, now adding a logging mechanism so that I can narrow down under what circumstances the problem is occurring.

Update on this: testing on 9 of my Electron boards, the following failure case eventually occurs:

  1. Perform a connect/publish action with the modem, so the modem is awake.
  2. Call System.sleep(SLEEP_MODE_DEEP, 30).
  3. System never wakes up.

I have a separate interrupt running to the WKP pin from an accelerometer and even that going off fails to cause a wake-up in the fail case. The failure does not occur all the time but it does eventually occur. So I’ve added a step between 1 and 2:

1a. Call Cellular.off().

Preliminary testing suggest that this fixes the problem. I need to do some more testing but, if this proves to be the case, I will raise a bug report.

EDIT: issue report raised https://github.com/spark/firmware/issues/1075.

EDIT: FYI, this is a known issue, https://github.com/spark/firmware/issues/1043. It is not yet patched to any released version of the Particle firmware and my workaround is not quite foolproof as the modem may not switch off when commanded. For example, right now nothing is connecting (it’s the 2nd of the month so I guess the server is rather busy with billing) and I can clearly see the LED flashing rapid cyan when I’ve already called Cellular.off(). So I’m using the workaround pattern suggested by @avtolstoy instead:

Cellular.disconnect();
Cellular.off();
while (Cellular.ready() && (sleepForSeconds > 0)) {
    delay(1000);
    sleepForSeconds--;
}
if (sleepForSeconds > 0) {
    System.sleep(SLEEP_MODE_DEEP, sleepForSeconds);
}
2 Likes