Photon won't sleep reliably with command System.sleep(D0, RISING, 60)

Hi All,

I hope you can help. I’m attempting to have my Photon go into standby mode (not deep sleep) for 1 minute. So I call:
System.sleep(D0, RISING, 60);

D0 is soldered to ground.

The behavior I see is intermittent. About 90% of the time, the PHOTON goes to sleep (I know this because it disconnects from the serial USB) but then wakes up in less than a second. About 10% of the time, the PHOTON goes to sleep for the asked for 60 seconds.

What could be causing the PHOTON to wake up prematurely most of the time? And why would this behavior be intermittent? Does anything else cause a wakeup besides the pin and the timeout?

I’ve been trying to debug this for hours, so any help is appreciated.

I’d not do that without a current limiting resistor. If your code (or some code meant for another device of yours OTAed by accident to that one) happens to drive the pin HIGH you probably can say “bye, bye” to that GPIO (or more).

Due to the implicitly applied 40k pull-down, you should not even need to do that - but adding a 2k2 external pull-down won’t hurt.

But for System.sleep(pin, ...) I’d consider the same restrictions as mentioned for attachInterupt() as the waking is triggerd by means of EXTI interrupts just the same.

Good advice. I guess I was just getting frustrated and decided to nail down D0.

Turns out D0 is not on the list of eligible wakeup pins for System.sleep(). I’ll switch to a different GPIO pin and see what happens.

Thanks!

2 Likes

So, I figured it out the cause, but I don’t know the solution. By stripping my application of functionality piece by piece until discovered the part that was causing the Sleep to not function.

The very popular library “ParticleSoftSerial” attaches an interrupt on the Rx pin. When this occurs, the System.sleep(pin,...) function stops working reliably. It works occasionally, which itself is odd. I’m using D4 for Rx.

Below is the minimal code that I believe can demonstrate the problem.

#include <Particle.h>
SYSTEM_MODE(MANUAL);
SYSTEM_THREAD(ENABLED);
#include <ParticleSoftSerial.h>

uint32_t lastSleep;
#define SLEEP_PIN D1

ParticleSoftSerial ss(D4,D5);

void setup()
{
  WiFi.off();
  Serial.begin();
  ss.begin(9600); // Comment out this line and sleep/wakeup works
  pinMode(SLEEP_PIN,INPUT_PULLDOWN);
  lastSleep = millis();
}

void loop()
{
  if (millis()-lastSleep > 10000) {
    Serial.println("Going to sleep");
    delay(1000);
    System.sleep(SLEEP_PIN,RISING,10);
    delay(1000);
    Serial.println("Waking up");
    lastSleep = millis();
  }
}

Conveniently ParticleSoftSerial provides an ‘end’ function as well as a begin. Surrounding the sleep with a end/begin works. And I have confirmed that the soft serial continues to function after the wakeup as well.

    ss.end();
    System.sleep(SLEEP_PIN,RISING,10);
    ss.begin(9600);
1 Like

Good you found the cause and a workaround, but IMO any non-related interrupt should not impact the function of System.sleep().

If that’s the case, could you please file a GitHub issue about this?