How to recognize awakening from PySense go-to-sleep?



  • I would like to avoid re-executing some code when awakening from "deepsleep". Is there a way to recognize that the LoPy/PySense has reawakened versus restarted by power on?



  • @jalperin

    This works to restore RTC after pysense go-to-sleep.

    py.setup_sleep(sleepsec)
    pycom.nvs_set('gtsSec',sleepsec)
    pycom.nvs_set('ttSec',time.time())
    py.go_to_sleep()

    rtc = RTC()
    ttSec = pycom.nvs_get('ttSec') # time.time() previous value
    if ttSec:
    gtsSec = pycom.nvs_get('gtsSec') # go to sleep seconds
    # reset clock to prior saved time plus length of sleep (both in seconds)
    rtc.init(time.gmtime( ttSec + gtsSec ))
    else:
    # Initialize your wifi, then
    rtc.ntp_sync("pool.ntp.org")
    # rtc.ntp_sync("23.239.26.89")
    while not rtc.synced():
    time.sleep(1)

    Since I can't distinguish awakening from reset, I am currently setting ttSec manually before running code. pycom.nvs_set('ttSec',0)



  • Further testing has shown that the RTC is reset during the PySense go_to_sleep() process. So, if it were possible to know that you have reawakened, it would still not be easy to determine how long you had slept.

    What I would like to do is to enable WiFi just long enough to set the RTC, deepsleep (or pysense.go_to_sleep() - whatever works better) for long portions of the day, awake at certain times, send lora packets on a timed basis, deepsleeping in between. I'm looking to put the LoPy outside for weeks at a time with minimal battery draw.

    The only way I can see to do this at the moment would be to save the RTC in multiple nvs keys and also save the sleepsec value before go_to_sleep(). Upon awakening I could then recognize my state and reinitialize the RTC to near accuracy without the high battery cost of enabling wifi.

    I would welcome other suggestions or observations.

    I have yet to get lora.nvram_save/restore to work, but I'll worry about that later.



  • @jmarcelino this is an interesting point - I'll have a check with @daniel but I can't see any reason why we wouldn't add this functionality to the Pytrack/Pysense.



  • @jalperin
    Good question, I'd expect something like the Deepsleep shield API with a get_wake_status() function but this not available on the Pytrack/Pysense yet.

    Maybe @bucknall knows what's planned around this?



  • @jalperin
    I thought maybe the machine.wake_reason() might help, but that stays 0 for power on, deepsleep, and py.go-to-sleep.



  • I've been testing py.go_to_sleep(), and the power savings of the new code are substantial. But, there seems to be a problem with the "reset cause."

    machine.reset_cause() returns 0 when the LoPy is first powered on. It returns 1 after syncing new code. Both good.

    After machine.deepsleep() machine.reset_cause() returns 3, also good.

    But, following py.go_to_sleep() the return code is again 0. I would have expected 3.

    So, as of the moment I cannot tell when the board has been powered on versus when it has awakened from py.go_to_sleep().



  • Got it. But, there seems to be a problem.

    machine.reset_cause() returns 0 when the LoPy is first powered on. It returns 1 after syncing new code. Both good.

    After machine.deepsleep() machine.reset_cause() returns 3, also good.

    But, following py.go_to_sleep() the return code is again 0. I would have expected 3.

    So, as of the moment I cannot tell when the board has been powered on versus when it has come out of py.go_to_sleep().



Pycom on Twitter