[SOLVED] System.sleep() doubles time after the second wakup

Hello everyone,

I am having some trouble with System.sleep(). I have a battery-powered Photon that needs to take some readings every 5 minutes and upload them to a server, but every minute the Photon must send a pulse to reset an external watchdog timer.

So I wrote a code that looks like this:

SYSTEM_THREAD(ENABLED);

int wakeUpPin = A0;
int pulsePin = WKP;

int wakeCount = 4;
boolean photonWasAsleep = true;

void readSensors() {
    // here goes the previously tested and working reading routine
    
    photonWasAsleep = true;
    WiFi.off();
    System.sleep(wakeUpPin, CHANGE, 60);
}

void setup() {
    // initialize I/Os, serial, etc.
}

void loop() {
    if(photonWasAsleep == true) {
        photonWasAsleep = false;
        
        wakeCount++;
        if(wakeCount == 5) {
            wakeCount = 0;
            
            Particle.connect();
            readSensors();
        }
        else {
            digitalWrite(pulsePin, HIGH);
            delay(100);
            digitalWrite(pulsePin, LOW);

            photonWasAsleep = true;
            WiFi.off();
            System.sleep(wakeUpPin, CHANGE, 60);
        }
    }
}

This code works perfectly for the first two cycles (meaning that the Photon wakes after 60 seconds to send the pulse and then goes back to sleep). The problem is that the third time the Photon goes to sleep it does not wake after 60 seconds, but rather after 120 seconds. In my setup this cannot happen because the external watchdog will reset the Photon if it does not get the pulse in time.

I don’t really have a readSensors() function in my code, I just placed it there as a reference of what is going on. But I can confirm that the rest of the code works without issues. Any clues on what could be wrong here? I would really appreciate your help :smile:

I have no idea but try adding:

Delay(1000);

After the Wifi.off();

and see if anything changes.

What system version are you targeting?

I’d also check for if (wakeCount >= 5) to catch a runaway counter.

Are you sure it doesn’t wake, or could it just wake and immediately go back to sleep?
This would account for the exact 2x60 sec.

BTW, how have you connected your wakeUpPin?
Have you got external pull-resistors in place?

1 Like

I am using system version 0.6.0 and have an external pull-up in place for the wakeup pin.

I added a 500ms delay after each System.sleep() call and it seems you are correct: somehow the Photon wakes and immediately goes back to sleep. I can tell because there are times when the 60s period ends and the RGB LED starts blinking green for a fraction of a second then goes off again for another 60s. I must be able to see that blinking because of the 500ms delay, without the delay it just seemed that the Photon went to sleep for a total of 120s.

Does calling System.sleep() not block application code? That would explain why the delay(500); works but I do not understand why the Photon goes to sleep immediately afterwards, skipping the if(photonWasAsleep == true) {} block.

@morduno, when does your watchdog trip? Is it at 60s exactly?

The watchdog resets the Photon at 66 seconds or so.

But @ScruffR definitively pointed me to the right direction. Since I assumed that System.sleep() stopped code execution, I did not take adequate precautions and was effectively calling the function twice. Adding some simple flags to the code solved the issue.

Thanks to everyone for your help, I really appreciate it!

2 Likes