You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
lightsleep() not working properly Pi Pico WH v1.24.0 #16180
MicroPython v1.24.0 on 2024-10-25; Raspberry Pi Pico W with RP2040
Reproduction
Attempt following code, both with lightsleep() having no ms argument and one with:
importmachinefrommachineimportPin, deepsleep, lightsleepdefwake_up(pin):
# Handle wake-up logic hereled.toggle()
print("Button pressed, waking up!")
# Configure buttonsbutton=Pin(11, Pin.IN, Pin.PULL_UP) # Example pinled=Pin(20, Pin.OUT)
led.on()
# Set up interruptbutton.irq(trigger=Pin.IRQ_FALLING|Pin.IRQ_RISING, handler=wake_up)
# Go to sleep until a button is pressedlightsleep()
Expected behaviour
Expect LED to react to button press when asleep and execute wake_up function. LED is on by default. LED should toggle/turn off when button is pressed down, both when machine is asleep and not asleep.
Observed behaviour
USB power tester indicates that the board sleeps only when NO MILLISECONDS ARGUMENT IS SPECIFIED.
When milliseconds ARE SPECIFIED, board does not appear to sleep as power consumption does not drop according to the USB tester. The board continues to work at full power, and the LED reacts to the button.
When NO MILLISECONDS ARE SPECIFIED, board appears to go to sleep (reducing power from >10ma to 0-1ma. But button does not do anything to LED.
Additional Information
I have tried adding the wake argument to button.irq, but Micropython says that extra keyword arguments are present.
I understand sleeping may have issues on the Pico W models. I have also tried turning off WiFi/setting the pin associated with Wifi to "low". That does not seem to have any impact whatsoever, since my code never explicitly turns Wifi on
I'm sorry, forgive me because I'm new to Micropython still...
I've tried 2 Pico boards, but that example you posted just now... Does the sleeping need to happen in a loop?
@RYoder97 this is just a proof of concept to reproduce the bug, it's to prove that on 1.24.0 and more recent lightsleep never do anything
Ah okay! So I'm not going crazy! I tried 1.22.2 and 1.23.0 and it works. However, you still need to specify a time otherwise the Pi Pico will be permanently asleep. This is less than ideal, but a workaround would be to set the time for a long time, or, set it for a long time and put it to sleep again after it wakes up. If a contributor is able to update the source code for the next release though, it would be greatly appreciated.
I hit something similar before I saw this issue. For me its ok as is with 1.24.0 on pico 1. On a Pico 2 the 1st lightsleep does not work. if I comment out the time.sleep(0.1) in the example below, then both lightsleeps work fine. Hope this helps pin it down.
import machine
import time
led = machine.Pin("LED", machine.Pin.OUT)
led.off()
while True:
led.on()
time.sleep(0.1)
machine.lightsleep(10000)
led.off()
machine.lightsleep(10000)
I am seeing same issue on Rpi PICO-W (rp2040) .. lightsleep is broken starting with 1.24 up to latest commit (tested a few days ago so not sure if something got fixed since then)
If time_ms is specified then this will be the maximum time in milliseconds that the sleep will last for.
...
With or without a timeout, execution may resume at any time if there are events that require processing.
Between 1.23.0 and 1.24.0 commit 74fb42a added use of rp2040 hardware timer 2.
When hardware timer 2 expires lightsleep() will return.
Based on the documentation, the 1.24.0 behavior is not a bug.
My testing, as I reported in the discussion indicates lightsleep() average sleep is about 60 milliseconds.
Users who need to sleep for an exact amount of time need to call lightsleep() in a loop.
Something like:
from time import ticks_ms, ticks_diff
from machine import lightsleep
def my_lightsleep(time_ms) :
before_tick = ticks_ms()
after_tick = before_tick
sleep_ms = time_ms
while sleep_ms > 0 :
sleep_ms = time_ms - ticks_diff(after_tick, before_tick)
if sleep_ms > 0 :
lightsleep(sleep_ms)
after_tick = ticks_ms()
Thanks for looking into it, cpottle9, and everyone else too for their time considering these issues. The work by cpottle9 raises some interesting questions. I do not know as much as others do about the code but, sticking to the original issue on the pico w :
Are we suggesting that pre 1.24.0 lightsleep was not giving correct results or has the documentation changed for 1.24.0?
Unless I am mistaken/misinterpreting (please forgive me if so), elsewhere I have seen references to the non W pico with 1.24.0 behaving like it does with 1.23.0 e.g. scruss:
I'm surprised that you're seeing this on a regular non-wireless RP2040 Pico. I can only make the example code on the issue #16181 fail on a Pico W, not on a Pico
He also highlighted:
a lot has changed in lightsleep, seemingly mostly to allow for the wifi to sleep gracefully and any USB devices to be dealt with.
So are we suggesting that lightsleep is/will be intentionally different for a Pico and a PicoW?
The next bit of the document for lightsleep says:
Such events, or wake sources, should be configured before sleeping, like Pin change or RTC timeout.
To me, this suggests that you can voluntarily set up such things if you want to interrupt the sleep, if you don't it will wake up when you asked it.
What are the timer changes in 74fb42a meant to do , why were they introduced in 1.24.0 and are they working correctly? Was it intentional to change lightsleep behaviour?
There seems to me to be some overlapping issues here that are making even understanding the implications of the differences between different hardware and different software versions more difficult. Obviously, sorry if I am missing something and wasting peoples time.
@ssotheremail, first I am a user of micropython and PICO W like you.
I did submit one minor change to micropython a little over a year ago, so I have some limited understanding of micropython internals. I have loads of experience coding in C.
I have an interest in reducing the power consumed by PICO so my applications can run from battery for a longer time.
That is why I've looked at lightsleep in the past.
I will do my best to answer you questions. @projectgus would provide better answers.
He submitted 74fb42a and made changes to lightsleep to fix issues when USB is active.
No, I am not suggesting lightsleep() in 1.23.0 was incorrect. From the documentation lightsleep() can return early or it can return on time. If it returned late that would be a bug.
I can't comment on non-W PICO behavior. I only have PICO W. Having said that, I did turn off the WIFI block and I still see lightsleep() returning early. Also, I do not have an PICO2 boards.
You raise a good point. This section does imply that only events configured in micropython code are of concern. The code in 74fb42a is written in C and the event is handled in C.
No, I do not think the changes in 74fb42a were intended to change lightsleep behavior. But that is a guess on my part. I still assert the new behavior is not a bug.
Quick update. I submitted a pull request to issue #16181 that addresses the problem of lightsleep returning early.
That pull request does nothing to help with Pin interrupts waking lightsleep.
Apologies, I missed this issue when it was opened. Thanks @cpottle9 for the investigation and the heads-up.
There's a more detailed explanation in the PR, but one of the root causes here is that before v1.24 the MicroPython soft timer expiring did not wake the rp2 from lightsleep. Commit 74fb42a (released in V1.24) accidentally changed this so that soft timer did wake the rp2 from lightsleep, and on the PICO_W board there is a wakeup for lwIP every 64ms. So, effectively, this limited the max lightsleep time to 64ms. Draft PR with the fix, so soft timer doesn't wake from lightsleep any more, is #16431.
I don't expect that PR will resolve everything reported here, in particular a pin irq not waking from machine.lightsleep() seems like something else.
Thanks for all this work. Just had a quick check with RPI_PICO2-20241218-v1.25.0-preview.125.gd10cda66d.uf2 in case the fixes have come through and the same versions for pico and pico w (cant see previews for pico 2 w).
Pico - lightsleep(5000) still ok
Pico W lightsleep(5000) 64ms
Pico 2 lightsleep(5000) ok, except when preceeded by a sleep(nn). e.g. sleep(5)
If the fixes are not in RPI_PICO2-20241218-v1.25.0-preview.125.gd10cda66d.uf2 etc can you say when it will be worth retesting, please?
ok, as its nearly Christmas, I have finally put the effort into fixing my micropython build problems on my pi 5 (I still cant do pico2W but never mind for now.....) I have managed to build 1.25.0.preview130 for the others so now:
Pico - lightsleep(5000) still ok
Pico W lightsleep(5000) 64ms
Pico 2 loaded to 2(led flashes) and 2W(led does not flash) lightsleep(5000) ok, except when preceeded by a sleep(nn). e.g. sleep(5) - not sure whether 2W result is useful.
Am I still too early to test?
Child to Adult: How many sleeps till Christmas?
Adult: Who knows? They are lightsleeps on a Pico.......
If the fixes are not in RPI_PICO2-20241218-v1.25.0-preview.125.gd10cda66d.uf2 etc can you say when it will be worth retesting, please?
Sorry for the confusing messaging, I've edited my previous post to clarify what I meant. At the moment no fixes have been merged, so the preview builds won't be any different.
If you care in particular about lightsleep with a timeout then I suggest watching #16181. When that issue closes then the next preview build after that should have the relevant fix in it.
Activity
bclermont commentedon Nov 8, 2024
@RYoder97
lightsleepdo not work at allWhich is much more simple use case, do not works. There is no sleep at all while executing
machine.lightsleep(10000)it just loop immediatelytested on a Pico W and 1.24 and 1.25 latest snapshot
bclermont commentedon Nov 8, 2024
@RYoder97 I just tried Micropython 1.23.0 and
lightspeedworks as expectedRYoder97 commentedon Nov 8, 2024
I'm sorry, forgive me because I'm new to Micropython still...
I've tried 2 Pico boards, but that example you posted just now... Does the sleeping need to happen in a loop?
bclermont commentedon Nov 8, 2024
@RYoder97 this is just a proof of concept to reproduce the bug, it's to prove that on 1.24.0 and more recent lightsleep never do anything
RYoder97 commentedon Nov 8, 2024
Ah okay! So I'm not going crazy! I tried 1.22.2 and 1.23.0 and it works. However, you still need to specify a time otherwise the Pi Pico will be permanently asleep. This is less than ideal, but a workaround would be to set the time for a long time, or, set it for a long time and put it to sleep again after it wakes up. If a contributor is able to update the source code for the next release though, it would be greatly appreciated.
ssotheremail commentedon Nov 10, 2024
I hit something similar before I saw this issue. For me its ok as is with 1.24.0 on pico 1. On a Pico 2 the 1st lightsleep does not work. if I comment out the time.sleep(0.1) in the example below, then both lightsleeps work fine. Hope this helps pin it down.
import machine
import time
led = machine.Pin("LED", machine.Pin.OUT)
led.off()
while True:
led.on()
time.sleep(0.1)
machine.lightsleep(10000)
led.off()
machine.lightsleep(10000)
cgm999 commentedon Nov 11, 2024
I am seeing same issue on Rpi PICO-W (rp2040) .. lightsleep is broken starting with 1.24 up to latest commit (tested a few days ago so not sure if something got fixed since then)
cpottle9 commentedon Dec 12, 2024
I did some investigation into this and reported my findings in discussion https://github.com/orgs/micropython/discussions/12573.
The main point I noted there is the micropython documentation for machine.lightsleep() is clear that it can return early.
https://docs.micropython.org/en/latest/library/machine.html
Between 1.23.0 and 1.24.0 commit 74fb42a added use of rp2040 hardware timer 2.
When hardware timer 2 expires lightsleep() will return.
Based on the documentation, the 1.24.0 behavior is not a bug.
My testing, as I reported in the discussion indicates lightsleep() average sleep is about 60 milliseconds.
Users who need to sleep for an exact amount of time need to call lightsleep() in a loop.
Something like:
ssotheremail commentedon Dec 13, 2024
Thanks for looking into it, cpottle9, and everyone else too for their time considering these issues. The work by cpottle9 raises some interesting questions. I do not know as much as others do about the code but, sticking to the original issue on the pico w :
Are we suggesting that pre 1.24.0 lightsleep was not giving correct results or has the documentation changed for 1.24.0?
Unless I am mistaken/misinterpreting (please forgive me if so), elsewhere I have seen references to the non W pico with 1.24.0 behaving like it does with 1.23.0 e.g. scruss:
He also highlighted:
So are we suggesting that lightsleep is/will be intentionally different for a Pico and a PicoW?
To me, this suggests that you can voluntarily set up such things if you want to interrupt the sleep, if you don't it will wake up when you asked it.
There seems to me to be some overlapping issues here that are making even understanding the implications of the differences between different hardware and different software versions more difficult. Obviously, sorry if I am missing something and wasting peoples time.
cpottle9 commentedon Dec 13, 2024
@ssotheremail, first I am a user of micropython and PICO W like you.
I did submit one minor change to micropython a little over a year ago, so I have some limited understanding of micropython internals. I have loads of experience coding in C.
I have an interest in reducing the power consumed by PICO so my applications can run from battery for a longer time.
That is why I've looked at lightsleep in the past.
I will do my best to answer you questions. @projectgus would provide better answers.
He submitted 74fb42a and made changes to lightsleep to fix issues when USB is active.
cpottle9 commentedon Dec 14, 2024
Quick update. I submitted a pull request to issue #16181 that addresses the problem of lightsleep returning early.
That pull request does nothing to help with Pin interrupts waking lightsleep.
I posted on the raspberry pi forum https://forums.raspberrypi.com/viewtopic.php?t=380979 expressing my opinions about lightsleep on PICO.
Take a look.
projectgus commentedon Dec 17, 2024
Apologies, I missed this issue when it was opened. Thanks @cpottle9 for the investigation and the heads-up.
There's a more detailed explanation in the PR, but one of the root causes here is that before v1.24 the MicroPython soft timer expiring did not wake the rp2 from lightsleep. Commit 74fb42a (released in V1.24) accidentally changed this so that soft timer did wake the rp2 from lightsleep, and on the PICO_W board there is a wakeup for lwIP every 64ms. So, effectively, this limited the max lightsleep time to 64ms. Draft PR with the fix, so soft timer doesn't wake from lightsleep any more, is #16431.
I don't expect that PR will resolve everything reported here, in particular a pin irq not waking from
machine.lightsleep()seems like something else.projectgus commentedon Dec 18, 2024
There is an older issue tracking this at #7035 . I've just left a comment there and opened another draft PR.
I think the still-open issues #16181 and #7035 are tracking everything reported in this issue. Does that seem correct? (EDIT: Rephrased this.)
ssotheremail commentedon Dec 18, 2024
Thanks for all this work. Just had a quick check with RPI_PICO2-20241218-v1.25.0-preview.125.gd10cda66d.uf2 in case the fixes have come through and the same versions for pico and pico w (cant see previews for pico 2 w).
Pico - lightsleep(5000) still ok
Pico W lightsleep(5000) 64ms
Pico 2 lightsleep(5000) ok, except when preceeded by a sleep(nn). e.g. sleep(5)
If the fixes are not in RPI_PICO2-20241218-v1.25.0-preview.125.gd10cda66d.uf2 etc can you say when it will be worth retesting, please?
ssotheremail commentedon Dec 18, 2024
ok, as its nearly Christmas, I have finally put the effort into fixing my micropython build problems on my pi 5 (I still cant do pico2W but never mind for now.....) I have managed to build 1.25.0.preview130 for the others so now:
Pico - lightsleep(5000) still ok
Pico W lightsleep(5000) 64ms
Pico 2 loaded to 2(led flashes) and 2W(led does not flash) lightsleep(5000) ok, except when preceeded by a sleep(nn). e.g. sleep(5) - not sure whether 2W result is useful.
Am I still too early to test?
Child to Adult: How many sleeps till Christmas?
Adult: Who knows? They are lightsleeps on a Pico.......
Sorry.
projectgus commentedon Dec 18, 2024
Sorry for the confusing messaging, I've edited my previous post to clarify what I meant. At the moment no fixes have been merged, so the preview builds won't be any different.
If you care in particular about lightsleep with a timeout then I suggest watching #16181. When that issue closes then the next preview build after that should have the relevant fix in it.