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
rp2: Can't wake from lightsleep with Pin IRQ #7035
In itself it may not save a lot of energy, but it could serve as a workaround.
For my use case, I want to use the deepsleep mode, which does not seems to be supported yet either. So I have started cobbling together a small experimental lib to use while waiting for the feature to be added in micropython. If any tinkerer feels adventurous and want to give it a run and help improving things they are very welcome:
I have been looking at this, and have found that the raspberrypi/pic--extras repository has the code to activate dormant mode in the hardware_rosc module. It should be accompanied by a method to check that wake_irqs are set before calling the dormant mode.
My cloned repository jf-micropython-pico which also uses jf-pico-sdk repo shows how I implemented and use it. Wake on irq works well using micropython. This is just a proof of concept example. Where this code goes would be up for discusion by more knowledgable persons. I have some code in gpio and some in Pin. The code also needs to be extended to be workable with xosc, and allow transparent use depending on rosc or xosc being used. The repositories may not necessarily be up to date with the originals but still shows that dormant mode can easily be implemented.
machine.sleep() - This function is deprecated, use lightsleep() instead with no arguments.
Pin.irq - wake selects the power mode in which this interrupt can wake up the system. It can be machine.IDLE, machine.SLEEP or machine.DEEPSLEEP. These values can also be OR’ed together to make a pin generate interrupts in more than one power mode.
How about a disclaimer machine.Pin rp2 not fully implemented
@tomjorquera many thanks for this: pico-micropython-lowpower-workaround
Crude test with multi meter when in dormant on following rp2040 boards
Tiny 2040 2.9 mA
Feather 2040 1.7 mA
Though the Feather 2040 doesn't always restart when running lowpower_example.py
@tomjorquera I've got some TPL5111 Low Power Timers on order
I hoping that a cleaner electronic edge might be better that my glitch-ee human applied rising might resolve.
We chose the Feather as it has on-board charger.
I'm new to micropython but have done Squirrel & JavaScript on arm mcu's for IoT proof of concepts.
So I'm more used to call backs for serial coms & timers etc. but loving the experience to date.
I have a simple bme680 talking to long range wireless (LoRaWAN) and to the cloud for storage and viz.
I was testing machine.deepsleep on Pico and it does not save any power, same as machine.sleep. However the lowpower.py works great for me. The powerconsumtion goes from 20mA to 1.1mA. Next step is to connect the DS3231
Hey folks, and thank for the mention @kevindawson.
Sorry to kind of highjacking the topic, but I happen to be in the process of adding a fix made by another people for an issue reported by some user with the pico not going out of dormant mode.
I could not reproduce the bug myself, so if some folks want to help test things (and especially this new branch), while waiting for official support... 😉
Are there any alternatives for nodemcu (esp8266)? The pico workaround does not seem to apply.
I wanted to use lightsleep in my application but once the microcontroller goes to that state, I can't not wake him up anymore. Waking up from deepsleep works fine.
* have you looked at: https://github.com/tomjorquera/pico-micropython-lowpower-workaround by @tomjorquera see above?
* have you looked in here -> https://github.com/pimoroni/pimoroni-pico/releases
Thanks for these links. In fact, I was trying to have MicroPython on RP0204 waking up from lightsleep on interrupt from timer initialized according to the value passed to lightsleep. Waking from lightsleep or deepsleep on pin interrupt and saving power is a good thing to have, but this is a related (as I see it) problem, yet not the one I need to solve now.
Nevertheless, when I get to wake-from-pin interrupts, I'm gonna try the options you mentioned (unless the problem has been already fixed to that moment).
The documentation tells about machine.sleep(): "This function is deprecated, use lightsleep() instead with no arguments."
But indeed, as told and documented, lightsleep without arguments never terminates.
The documentation tells about machine.sleep(): "This function is deprecated, use lightsleep() instead with no arguments." But indeed, as told, lightsleep without arguments never terminates.
I was talking about the Pin IRQ Wake - sorry if that was not clear enough.
Like in self.interrupt_pin.irq(trigger=Pin.IRQ_FALLING, handler=interrupt_handler, wake=machine.SLEEP)
machine.SLEEP does not exist so I can still not wake the RP2040 using an external pin input.
After some tests it seems that the RP2040 does at least react to IRQs (without setting them up with a wake flag). But somehow the IRQ only fires once in a while. I have sensors which trigger the IRQ and if the RP2 runs normal without sleep, it works as expected. If I set it to lightsleep it only gets like 30% of the interrupts.. which is a bit weird tbh.
So the IRQ works with lightsleep but not 100%, anyone else has this experiences?
I was looking into this just now, as a secondary issue to the regression reported in #16181.
I think the current situation for RP2040 is that Pin.irq(...) can wake the CPU from lightsleep, but only when two conditions are true:
A timeout is passed to lightsleep, i.e. machine.lightsleep(120000) but not machine.lightsleep().
A handler function is set (it can be an empty function, but something has to be set).
I've opened draft PR #16442 to make this more consistent, but there still a couple of things that need resolving before that's ready.
The docs indicate that to fix this, the IRQ should be instantiated with wake=machine.SLEEP. Unfortunately this constant does not exist.
FWIW, I think the only port with an irq(wake=) arg that matches the Pin docs is the cc3200 port. The immediate "fix" is probably to update the docs so they reflect the current heterogeneous pin wake-up behaviour, and then maybe aim for a new common wake-up API in the future.
Activity
cipy commentedon Mar 21, 2021
well, it looks like the docs is a bit ahead of its time. also there is no wake or priority parameter to .irq()
tomjorquera commentedon Mar 27, 2021
For what I have seen, support does not seems implemented yet for the pico.
From my experiments, it seems that in the meantime you could try experimenting with using a function such as
wfiputs the pico into a suspended state until any interrupt is received (see https://docs.micropython.org/en/latest/reference/asm_thumb2_misc.html).In itself it may not save a lot of energy, but it could serve as a workaround.
For my use case, I want to use the deepsleep mode, which does not seems to be supported yet either. So I have started cobbling together a small experimental lib to use while waiting for the feature to be added in micropython. If any tinkerer feels adventurous and want to give it a run and help improving things they are very welcome:
https://github.com/tomjorquera/pico-micropython-lowpower-workaround
jmfloyd commentedon Apr 16, 2021
I have been looking at this, and have found that the raspberrypi/pic--extras repository has the code to activate dormant mode in the hardware_rosc module. It should be accompanied by a method to check that wake_irqs are set before calling the dormant mode.
My cloned repository jf-micropython-pico which also uses jf-pico-sdk repo shows how I implemented and use it. Wake on irq works well using micropython. This is just a proof of concept example. Where this code goes would be up for discusion by more knowledgable persons. I have some code in gpio and some in Pin. The code also needs to be extended to be workable with xosc, and allow transparent use depending on rosc or xosc being used. The repositories may not necessarily be up to date with the originals but still shows that dormant mode can easily be implemented.
kevindawson commentedon Apr 27, 2021
machine.IDLE,machine.SLEEPormachine.DEEPSLEEP. These values can also be OR’ed together to make a pin generate interrupts in more than one power mode.How about a disclaimer machine.Pin rp2 not fully implemented
cipy commentedon Apr 29, 2021
Hi @kevindawson
is there a new microPython build available for Pico?
the old/current one doesn't have .IDLE, .SLEEP, .DEEPSLEEP as I quoted above in this thread
kevindawson commentedon Apr 29, 2021
@cipy
I was using rp2-pico-20210418-v1.15.uf2
are you saying I should be using
rp2-pico-20210427-unstable-v1.15-14-g65b90cd0f.uf2 (latest)
cipy commentedon Apr 29, 2021
kevindawson commentedon Apr 29, 2021
@cipy from: rp2-pico-20210418-v1.15.uf2
is this of any help
jmfloyd commentedon Apr 29, 2021
Not much has changed with 1.15 and definitely nothing to do with sleep and wake.
Which is why I started looking at what was involved to implement a basic form of wake on pin interrupt. See my discussions previously.
kevindawson commentedon Apr 29, 2021
@jmfloyd Thanks I will go and read
industrialinternet commentedon May 7, 2021
@tomjorquera many thanks for this: pico-micropython-lowpower-workaround
Crude test with multi meter when in dormant on following rp2040 boards
Tiny 2040 2.9 mA
Feather 2040 1.7 mA
Though the Feather 2040 doesn't always restart when running lowpower_example.py
tomjorquera commentedon May 7, 2021
Good to know @industrialinternet !
I don't have a feather, so I can't reproduce the issue you describe atm, but I created an an issue on my workaround repo.
industrialinternet commentedon May 7, 2021
@tomjorquera I've got some TPL5111 Low Power Timers on order
I hoping that a cleaner electronic edge might be better that my glitch-ee human applied rising might resolve.
We chose the Feather as it has on-board charger.
I'm new to micropython but have done Squirrel & JavaScript on arm mcu's for IoT proof of concepts.
So I'm more used to call backs for serial coms & timers etc. but loving the experience to date.
I have a simple bme680 talking to long range wireless (LoRaWAN) and to the cloud for storage and viz.
Herbert0209 commentedon May 17, 2021
I was testing machine.deepsleep on Pico and it does not save any power, same as machine.sleep. However the lowpower.py works great for me. The powerconsumtion goes from 20mA to 1.1mA. Next step is to connect the DS3231
peterhinch commentedon Jun 16, 2022
Problem with sleep now raised as #8770.
Plaque-fcc commentedon Aug 13, 2022
It's not even implemented in 1.19.1:
dir(machine)
['class', 'name', 'ADC', 'I2C', 'I2S', 'PWM', 'PWRON_RESET', 'Pin', 'RTC', 'SPI', 'Signal', 'SoftI2C', 'SoftSPI', 'Timer', 'UART', 'WDT', 'WDT_RESET', 'bitstream', 'bootloader', 'deepsleep', 'disable_irq', 'enable_irq', 'freq', 'idle', 'lightsleep', 'mem16', 'mem32', 'mem8', 'reset', 'reset_cause', 'soft_reset', 'time_pulse_us', 'unique_id']
kevindawson commentedon Aug 15, 2022
@Plaque-fcc
tomjorquera commentedon Aug 15, 2022
Hey folks, and thank for the mention @kevindawson.
Sorry to kind of highjacking the topic, but I happen to be in the process of adding a fix made by another people for an issue reported by some user with the pico not going out of dormant mode.
It's currently in the following branch https://github.com/tomjorquera/pico-micropython-lowpower-workaround/tree/clear-clocks
I could not reproduce the bug myself, so if some folks want to help test things (and especially this new branch), while waiting for official support... 😉
kevindawson commentedon Aug 15, 2022
@tomjorquera you are welcome
if i can find some time i will take a look
other wise I will eagerly await updates here ;)
Merge pull request micropython#7035 from weblate/weblate-circuitpytho…
vrcoelho commentedon Nov 15, 2022
Are there any alternatives for nodemcu (esp8266)? The pico workaround does not seem to apply.
I wanted to use
lightsleepin my application but once the microcontroller goes to that state, I can't not wake him up anymore. Waking up fromdeepsleepworks fine.Plaque-fcc commentedon Nov 18, 2022
Thanks for these links. In fact, I was trying to have MicroPython on RP0204 waking up from
lightsleepon interrupt from timer initialized according to the value passed tolightsleep. Waking fromlightsleepordeepsleepon pin interrupt and saving power is a good thing to have, but this is a related (as I see it) problem, yet not the one I need to solve now.Nevertheless, when I get to wake-from-pin interrupts, I'm gonna try the options you mentioned (unless the problem has been already fixed to that moment).
Informaticore commentedon Aug 23, 2023
This is still not possible right? At least machine.SLEEP does still not exist but the documentation says so :(
robert-hh commentedon Aug 23, 2023
The documentation tells about machine.sleep(): "This function is deprecated, use lightsleep() instead with no arguments."
But indeed, as told and documented, lightsleep without arguments never terminates.
Informaticore commentedon Aug 23, 2023
I was talking about the Pin IRQ Wake - sorry if that was not clear enough.
Like in
self.interrupt_pin.irq(trigger=Pin.IRQ_FALLING, handler=interrupt_handler, wake=machine.SLEEP)machine.SLEEP does not exist so I can still not wake the RP2040 using an external pin input.
robert-hh commentedon Aug 23, 2023
That's right. At RP2 one cannot stop machine.lightsleep() or machine.deepsleep() with a Pin IRQ.
Informaticore commentedon Aug 28, 2023
After some tests it seems that the RP2040 does at least react to IRQs (without setting them up with a wake flag). But somehow the IRQ only fires once in a while. I have sensors which trigger the IRQ and if the RP2 runs normal without sleep, it works as expected. If I set it to lightsleep it only gets like 30% of the interrupts.. which is a bit weird tbh.
So the IRQ works with lightsleep but not 100%, anyone else has this experiences?
Tico06 commentedon Jan 4, 2024
Hi All,
I am interested in this fix, I subscribed to the thread. Hopefully it'll be fixed soon.
Thanks an Reg
Eric.
projectgus commentedon Dec 18, 2024
I was looking into this just now, as a secondary issue to the regression reported in #16181.
I think the current situation for RP2040 is that
Pin.irq(...)can wake the CPU from lightsleep, but only when two conditions are true:machine.lightsleep(120000)but notmachine.lightsleep().I've opened draft PR #16442 to make this more consistent, but there still a couple of things that need resolving before that's ready.
FWIW, I think the only port with an
irq(wake=)arg that matches the Pin docs is the cc3200 port. The immediate "fix" is probably to update the docs so they reflect the current heterogeneous pin wake-up behaviour, and then maybe aim for a new common wake-up API in the future.