bbcmicrobit / micropython

Port of MicroPython for the BBC micro:bit
https://microbit-micropython.readthedocs.io
Other
595 stars 287 forks source link

docs: Add Power Management documentation. #754

Closed microbit-carlos closed 1 year ago

microbit-carlos commented 2 years ago

Proposal

The current proposal has been simplified to only have two sleep functions power.deep_sleep() and power.off() (as there is already microbit.sleep() we had to use different wording) and a function to configure the wake up sources power.wake_source().

Preview build of the docs: https://microbit-micropython--754.org.readthedocs.build/en/754/power.html

Things Still Under Consideration

Alternative Proposals

Wake up sources as deep_sleep() arguments

The reason the wake up sources have been separated to a different function call was allow setting the sources once during startup, so that programmes with multiple deep_sleep() calls didn't have to replicate these values around.

from microbit import *
import radio

power.wake_source(pins=(pin0, pin1), buttons=button_a)

@run_every(s=1)
def check_pin_every_second():
    if pin2.read_digital():
        power.deep_sleep()

radio.on()
while True:
    if button_b.is_pressed():
        power.deep_sleep()
    if radio.receive() == 'sleep':
        power.deep_sleep()

However, this is the kind of thing that could be resolved by the user creating a wrapper function:

from microbit import *
import radio

def go_to_sleep():
    power.deep_sleep(pins=(pin0, pin1), buttons=button_a)

@run_every(s=1)
def check_pin_every_second():
    if pin2.read_digital():
        go_to_sleep()

radio.on()
while True:
    if button_b.is_pressed():
        go_to_sleep()
    if radio.receive() == 'sleep':
        go_to_sleep()

One of the advantages of having the wake up sources as arguments is that it removes any ambiguity about the sources also being applicable to power.off(), as it only applies for deep_sleep().

At this point I'm leaning towards this simplification, unless somebody can think of a good reason to keep them separated.

Implementation details not shown in the docs

microbit-carlos commented 2 years ago

On reflection, the alternative listed in the PR description makes sense and I think it's a better starting point. So I've updated the docs to do that, and if based on the review/discussion/testing it turns out we need a separate function for the wake up sources then we can revert it.

microbit-carlos commented 2 years ago

@dpgeorge this is ready to do an initial implementation (although technically is lower priority than the Sound Effects), mostly to see if there are any technical reasons that might affect the functions as they are defined here. The MakeCode implementation turned out a bit more complex than we anticipated, mostly to be able to deal with how all fibers go to sleep, but I think that should not affect MicroPython.

dpgeorge commented 1 year ago

As discussed elsewhere, my suggestion is that run_every=True does not end the deep_sleep() call, but rather wakes briefly to execute the run every and then resumes the deep sleep. The deep sleep only ends when the given timeout expires, or a wake_on event occurs. In particular, power.deep_sleep(run_every=True) will never return. (And maybe we can then make run_every=True the default.)

microbit-carlos commented 1 year ago

This has been shipped in v2.1.0-beta.1 in the current form, so I'll merge the docs, and any changes to sleep will need a new PR here as well.

And the last comment has been captured in this issue: