How to tell deep sleep wake up reason between rising signal on wake up pin and RTC clock time out?

How to tell deep sleep wake up reason between rising signal on wake up pin and RTC clock time out?
I can not find RTC_IRQHandler().
From particle Doc find resetReason() API,But it does not describe deep sleep wake up reset reason.

Anyone know a way to find out deep sleep wake up reason?
Thanks!

resetReason()
Returns a code describing reason of the last device reset. The following codes are defined:

RESET_REASON_PIN_RESET: Reset button or reset pin
RESET_REASON_POWER_MANAGEMENT: Low-power management reset
RESET_REASON_POWER_DOWN: Power-down reset
RESET_REASON_POWER_BROWNOUT: Brownout reset
RESET_REASON_WATCHDOG: Hardware watchdog reset
RESET_REASON_UPDATE: Successful firmware update
RESET_REASON_UPDATE_TIMEOUT: Firmware update timeout
RESET_REASON_FACTORY_RESET: Factory reset requested
RESET_REASON_SAFE_MODE: Safe mode requested
RESET_REASON_DFU_MODE: DFU mode requested
RESET_REASON_PANIC: System panic
RESET_REASON_USER: User-requested reset
RESET_REASON_UNKNOWN: Unspecified reset reason
RESET_REASON_NONE: Information is not available

Hi,

  1. The way I did it here, is to get Time.now() right before going to sleep, and then right after waking up. If less time elapsed than the timeout, then I assumed it was the pin. It works reliably for me.

  2. Another possibility is to read the state of the pin you are triggering on right after waking up. If you are waiting for a high or rising edge, and the pin is high, then you were probably awoken by the pin. However, I’m told this may not be reliable. I tested this method too, and it seemed reliable.

Anyway, I settled on using the first method above, and it has worked for me every 15 minutes for over 100 days now without getting it wrong.

  • Rich
2 Likes

Timer wakeUpButtonDetect(50, wakeUpButtonDetectTimeOut);

bool checkForButtonPress(){

    noInterrupts();
    
    int buttonDetects = 0;
    int reads = 0;
    wakeUpButtonDetect.startFromISR();
    delay(5);
    while(wakeUpButtonDetect.isActive()){
        // take the intergral
        buttonDetects += pinReadFast(WKP);
        reads += 1;
        delay(5); // or what ever you please
    }
    Serial.print("Read wkp pin ");
    Serial.print(reads);
    Serial.println(" number of times");
    
    Serial.print("Detected button was pushed ");
    Serial.print(buttonDetects);
    Serial.println("number of times");
    
    if(buttonDetects > reads/2){
        // if more than 50% are pushes
        return true;
        
    }else{
        return false;
    }
    
    interrupts();
}

But you have to be in Manual Mode or Semi-Auto so that your code kicks off at asap. The STARTUP() macro may do the tick to.

But surely there is a better way as this wastes 50ms at the start.

Read state of pin can work when Photon is sleep,Not sure If it will work when Photon is DEEP sleep.Time.now() will not reset after wake up from deep sleep?

I think there are some news in this field and didn't want to create a new thread - that is why I revive. I think there has been some work done in 0.8.0 for us to know what was the reason Photon/Electron woke up.

I read about it here : Particle Firmware Updates Thread:

If you read some more on Github you might see that even deep sleep was mentioned.
So the questions is (@peekay123 could you help since I've seen your comments in that conversation on github?) : do we (since 0.8.0-rc.2) have a new tool for Photon and Electron to know what was the reason for the device to wake up from deep sleep, or I misinterpreted something? If that is true, could somebody please share some method for using this? I would be grateful since I have to solve exactly this problem for Electron right now, and don't know should I use all of the DIY alternative methods, or is there an actual flag for knowing why Electron woke up from deep sleep, thanks.

I think log RTC stamp to backup RAM before fall into deep sleep it is the only way to tell wake up reason

@ethelder, release 0.8.0-rc.3 includes the wake-by-pin and wake-by-rtc in System.sleepResult(). Take a look at the test app:

1 Like

Thanks!But there are some issues,I can not move to 0.8.0 now.

Hi All,
I'm trying to differentiate between wake by RTC and wake by WKP pin.

Whenever I use:

SleepResult result = System.sleepResult();
int reason = result.reason();

I get one of two results, either:

0 - WAKEUP_REASON_NONE

or

3 - WAKEUP_REASON_PIN_OR_RTC

I never get the other two cases:
1 - WAKEUP_REASON_PIN
2 - WAKEUP_REASON_RTC

Can anyone help me understand how I can differentiate if it's case 1 or 2?

@jimbol I'm working with 1.4.4 ParticleOS and getting the same thing when using SLEEP_MODE_DEEP with a timeout, and I usually get 3 - WAKEUP_REASON_PIN_OR_RTC. I would love to be able to differentiate between PIN or RTC. For now, I'm doing the workaround of saving the time I went to sleep to EEPROM and comparing to Time.now(), but this has a few annoying corner cases and therefore isn't the cleanest.

@peekay123 have you gotten sleep result to differentiate between RST or Clock wakeup with SLEEP_MODE_DEEP?

@avtolstoy I’m trying to figure out if it’s possible to differentiate between a RST pin wakeup and a RTC wakeup when in SLEEP_MODE_DEEP on the electron to intelligently respond when a partner mcu doesn’t wake up the particle in the prescribed interval. I’ve implemented an EEPROM time check, but it’s not a clean solution.

I found in that the Device OS currently simply assigns WAKEUP_REASON_PIN_OR_RTC, but after digging around the Device OS code (see my notes below), I’m curious if you think this could be a future feature.

On the electron, which supports pin and RTC wakeups from standby/SLEEP_MODE_DEEP, do you think there is a mechanism to accurately report PIN or RTC upon wakeup?

… What I’ve found so far:

Digging into the DeviceOS, I noticed that WAKEUP_REASON_PIN_OR_RTC is always returned in the SleepResult when the device comes out of standby mode because the last_reset_reason is set as RESET_REASON_POWER_MANAGEMENT in Init_Last_Reset_Info(). Init_Last_Reset_Info() uses the PWR_FLAG_SB to determine if the device is exiting standby mode.

Going further down the abstraction rabbit hole, it seems to me that to solve the problem, the event causing the device to exit standby would need to be logged and used in Init_Last_Reset_Info. I got stuck because I wasn’t familiar enough with the Cortex M3 to know what gets called after the __WFI() (though I guess it’s likely something like an NVIC routine).

Worth noting: the boron doesn’t allow RTC wakeup from SLEEP_MODE_DEEP, so this feature is not relevant to the platform.

Thanks for any insight!