micropython
micropython copied to clipboard
docs: Add Power Management documentation.
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
- The MakeCode implementation, which is a relatively thin wrapper around CODAL, had to offer the option to "request sleep" which goes to sleep when the current fiber yields, or to "request sleep and block the fiber until it goes to sleep". For MicroPython I think we could have only the second option, as the usage of fibers is limited
- MakeCode example for reference: https://makecode.microbit.org/_EoqLgCDgr9Vj
- CODAL also offers
lowPowerEnable()
andlowPowerIsEnabled()
as barriers to disable sleep in important portions of code. With the current implementation I don't think is required to expose these to the MicroPython users, but if we find a use case that needs it we might have to reconsider.
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
- The pin classes might need to be updated to be able to set them as wake up sources? It's an implementation detail, but might be worth discussing if there are trade offs.
- MakeCode extension implementation for reference: https://github.com/microbit-foundation/pxt-microbit-v2-power/blob/master/power.cpp
- We are providing a way to detect the wake up source
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.
@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.
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.)
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:
- https://github.com/microbit-foundation/micropython-microbit-v2/issues/118