micropython-pico-deepsleep icon indicating copy to clipboard operation
micropython-pico-deepsleep copied to clipboard

Is machine.freq being reset after coming out of deepsleep?

Open Bicko opened this issue 2 years ago • 4 comments

Hi, Great work @ghubcoder on this, thank you.

To reduce current drawn in 'normal' use, I'm halving the clockspeed thus:-

from machine import freq clockspeed = 64 # Default is 125MHz freq(clockspeed * 1000000)

I see the current drop to nearly half the normal amount (14mA instead of 22mA), which is great.

Then, during idle times, I use deepsleep and see the current drop to 1.8mA - which is fantastic for my project!

However, when coming out of deepsleep, I notice it's drawing 22mA again rather than the original 14mA. Looks like the clockspeed has been reset to the default 125MHz. I don't have a display on the project and, obviously, Thonny loses USB comms to the Pico, so I can't ask machine.freq what it's running at. Guess I'll find a display to throw at it.

Great work, though - really appreciate it.

Bicko avatar Jul 15 '22 11:07 Bicko

Hi @Bicko , really good to hear you have found some use for this. Great way you have found there to save even more power.

It's very likely that this mod is resetting the clock speed back to the defaults when it is awakening from sleep.

At this point:

https://github.com/ghubcoder/micropython-pico-deepsleep/blob/3d3c7a336a58f544802db3f7ea44700495b3be73/ports/rp2sleep/modpicosleep.c#L63-L65

(That file is the main change that this deep sleep modification requires to the original micropython source code)

That calls this function in the Pico SDK. Which appears to go through and reset all the clock frequencies.

Apologies if you have seen this already, but the code for this mod came out of this blog post. Took a little bit of trial and error to awaken the pico after deep sleeping, definitely room for improvement, perhaps not everything in there is required to get it back into a clean state, and we could avoid resetting everything back to defaults when awakening.

The code already stores some of the state prior to sleeping, here:

https://github.com/ghubcoder/micropython-pico-deepsleep/blob/3d3c7a336a58f544802db3f7ea44700495b3be73/ports/rp2sleep/modpicosleep.c#L73-L76

Perhaps this can be expanded upon, and rather than using the SDK version of clocks_init, a custom function could be written to return everything to the state it was prior to sleeping. This should preserve your processor frequencies.

I guess a crude way around it for now would be to reset the frequency after sleeping to what you need it to be. Not a great solution though....

ghubcoder avatar Jul 31 '22 15:07 ghubcoder

Hi @ghubcoder ,

Thanks for your reply, some of which I actually understood! :-) I had seen your blog post, yes. I'll confess that I've opted for the crude solution! Once it's out of deep sleep, the code checks the clock speed and resets it if required. Works well enough for my relatively simple project. I'm now clocking the Pico at just 10MHz, which has reduced the current drawn to 5.2mA, and the Deep sleep is in the 1.4mA region (uncalibrated multimeter). I'm very happy with that.

Bicko avatar Aug 10 '22 13:08 Bicko

@Bicko if you use the latest release of Micropython now there is a function called:

machine.lightsleep(5000)

For example, to sleep for 5 seconds. This provides a means to deep sleep and wake without using this fork. It was released a few months ago. Perhaps you can give that a try and see if the freq is reset when using that?

I'd be interested to see if it does.

ghubcoder avatar Aug 10 '22 18:08 ghubcoder

Thank you for the pointer to machine.lightsleep(). Some interesting developments, here!

Using a nighlty build, I find machine.lightsleep() is working as I'd hoped. I see a current draw of 1.4 to 1.6mA, which is the same as before and most welcome progress. By the way, when coming out of the lightsleep, it does still reset the clock frequency - ah well, my workaround still works fine.

The downside is that I can't clock it down to 10MHz any more. The lowest I can set is 18Mhz. The current drawn at 18MHz is 7.7mA, rather than the 5.1mA of 10MHz - I know it doesn't seem like much, but it's 50% more and will impact battery life.

Previous nighlty builds behave the same. If I go back to the last stable release (v1.19.1 - 2022-06-18), I can clock it down to 10MHz but then I lose lightsleep().

Bicko avatar Aug 24 '22 17:08 Bicko