Proper way to deepsleep....



  • What is the proper way to deepsleep a module using pysense or pytrack in order to minimal power to be used/

    Is below correct?
    # machine.deepsleep(sleepOfftime * 1000) #do i need to do this?
    py.setup_sleep(sleepOfftime)
    py.go_to_sleep()

    Can anyone share a routine to deepsleep, seems easy but the doco is all over the place.



  • This post is deleted!


  • Wow! Thanks for the followup on this @PeterB, that looks great. I'm glad the idea works, though concerned by the issues you are still having. I appreciate the code sample and will be integrating it soon. If I learn anything more, I'll pass it along.



  • @misterlisty said in Proper way to deepsleep....:

    @PeterB Tell me if i'm wrong but i do not see how this resolves the issue. When you put the pycom to deepsleep, it shuts down the os, but on restart is still needs to load the OS to execute your code so how does this resolve the issue?

    Because it closes the OS gracefully with the machine.deepsleep(1), including file handling etc etc. I did before calling gotosleep().
    Therafter it restarts, but as I do not do anything else than shown in my solution in the code I have given, before putting it to sleep via py.go_to_sleep(); It does not matter that py.go_to_sleep() then just kills the OS. I need py.go_to_sleep() as I need the sleepfunctions of the pysense board as well.



  • @PeterB Tell me if i'm wrong but i do not see how this resolves the issue. When you put the pycom to deepsleep, it shuts down the os, but on restart is still needs to load the OS to execute your code so how does this resolve the issue?



  • @misterlisty said in Proper way to deepsleep....:

    @PeterB Be interested in seeing your solution if you share..if i deepsleep the esp32, then the code after this command will no longer execute..when the esp32 wakes doesn't the boot.py start again?

    Exactly. So what I do now at the start of main.py (so I do not use the "machine.wake_reason()" as thought earlier, but jist a special flag in flash):

    INT_PIN = Pin("P9", Pin.IN, Pin.PULL_DOWN)
    py = Pysense()
    acc = LIS2HH12()
    
    ESP32sleep = pycom.nvs_get("ESP32sleep")
    if ESP32sleep is None:
        ESP32sleep = 0
    pycom.nvs_set("ESP32sleep", 0)
    if ESP32sleep > 0:
        blink("red", 5, speed=0.1)
        state = pycom.nvs_get("state")
        if state is None:
            state = STATE_NOT_SET
        # enable wakeup source from INT pin (PIC_RC1 - pin#6 on External IO Header)
        py.setup_int_pin_wake_up(True)
        if state == STATE_WAIT_FOR_ACC:
            py.setup_int_wake_up(True, False)
            acc.enable_activity_interrupt(ACC_THRESHOLD, ACC_DURATION)
    
        py.setup_sleep(LONGSLEEP)
        py.go_to_sleep()
    
    # REST OF NORMAL CODE FOLLOWS which is executed when it restarts
    # without the instruction as indicated by "ESP32sleep" to go to sleep immediately via py.go_to_sleep()
    # ...
    

    And for going to sleep I call the following function:

    def gotosleep():
        pycom.nvs_set("ESP32sleep", 1)
        machine.deepsleep(1)
    

    It works partly as expected. The closure of the ESP32 is good in this way as I can see it does not make garbage of any files.
    It does the wake up on a time-wake-up of pysense. I have problems with the external button and aacelerometer still.
    Need to investigate that furrther.



  • @PeterB Be interested in seeing your solution if you share..if i deepsleep the esp32, then the code after this command will no longer execute..when the esp32 wakes doesn't the boot.py start again?



  • @misterlisty said in Proper way to deepsleep....:

    Not sure if the question is answered...if i use the pysense deepsleep, how do i get the esp32 to shutdown gracefully?

    As indicated below, first deepsleep the ESP32 for a very short while, shutting it down gracefully, and when that wakes go_to_sleep on pysense, which will not gracefully shutdown the ESP32, but nothing essential should have been done since te wakeup.

    I am working on it now.



  • Not sure if the question is answered...if i use the pysense deepsleep, how do i get the esp32 to shutdown gracefully?



  • @John-Baird said in Proper way to deepsleep....:

    @PeterB Quick question - it's painful but, would a machine.deepsleep() of one second followed by py.go_to_sleep() fix the graceful shutdown question? Our periods of sleep are all in the 10-60 minute range so an extra second or so isn't an issue. If I get time I'll try it, but was wondering what you thought?

    Nice idea.
    The issue then will be that the "py.go_to_sleep()" can not be put after the "machine.deepsleep()" directly because a wake from "machine.deepsleep()" will restart at boot.py.
    Then I should be able to recognise a wake from machine.deepsleep() from any of the wakes from "py.go_to_sleep()" , i.e. power up, accelerometer, time and external button press.
    Perhaps via "machine.reset_cause()" if that works in Pycom as it can distinguish between a power wake of the ESP32, which is expected to happen after any of the wakereasons by "py.go_to_sleep()", and a timed wakeup of the ESP32. In that case a power wake from pysense means a power wake of both and shlould not be followed by a "py.go_to_sleep()" but by the rest of the program.

    Badly documented by Pycom (again):
    According https://docs.micropython.org/en/latest/library/machine.html#machine-constants
    and https://docs.micropython.org/en/latest/library/machine.html
    the "machine.wake_reason()" should not be used for this, but the "machine.reset_cause()" as it leads to:
    machine.PWRON_RESET
    machine.HARD_RESET
    machine.WDT_RESET
    machine.DEEPSLEEP_RESET
    machine.SOFT_RESET
    and as "machine.wake_reason()" would most likely only lead to:
    machine.WLAN_WAKE
    machine.PIN_WAKE
    machine.RTC_WAKE



  • @John-Baird Sounds like a practical work around to me.



  • @PeterB Quick question - it's painful but, would a machine.deepsleep() of one second followed by py.go_to_sleep() fix the graceful shutdown question? Our periods of sleep are all in the 10-60 minute range so an extra second or so isn't an issue. If I get time I'll try it, but was wondering what you thought?



  • There is another major problem with py.go_to_sleep() !!!!
    As said it switches off power to the ESP32, but be careful: without a proper shutdown of the ESP32, meaning it looses/corrupts data when using its filesystem before goring to sleep, even if that was more than 5 seconds ago.
    The machine.deepsleep() shuts down the ESP32 gracefully but then the pysense remains powered.



  • @jcaron As you said this is an FAQ, I suggest you make a Tutorial/example code with proper documentation for it.



  • @jcaron thanks



  • @misterlisty this has been discussed many times in the many questions you asked on this topic, not sure it warrants yet another new thread.

    If you want the absolute minimal power consumption, use the Pysense deep sleep (setup_sleep and go_to_sleep). This will completely power off the ESP32 and everything else on the module, and puts the PIC on the Pysense in sleep, disabling USB etc.

    The drawback is that the ESP32’s RTC is no longer functional, and there may be issues with SD card writes if you use those, as the ESP32 is shut down abruptly.

    The alternative is to use the ESP32’s native deep sleep (machine.deepsleep). This will keep the RTC active, but then you have the issue of minimising the Pysense power consumption. I have never used that mode myself, so I don’t know what you should expect. Did you measure power draw in that situation? It shouldn’t be too high...


Log in to reply
 

Pycom on Twitter