-
Notifications
You must be signed in to change notification settings - Fork 220
is deepsleep() anywhere near to being implemented ? #32
Comments
Wrapping the esp-idf deep sleep functions isn't a big problem, but it's more a matter of what should it do when it wakes: call a callback function perhaps? |
A callback would be ideal, as the 8266 effectively performs a reset when it wakes up which means that you loose all your values. |
Not having deep sleep really limits the application now to be a powered device as even with a 2700mah battery, the device would only last just over a day on battery power. |
@nickzoic, Why wouldn't it be implemented the same way as the 8266 wakeup (i.e. w/ a reset)? Then the code could check the wake reason. Would make MP scripts backwards compatible with 8266. |
Yeah, it should. When I wrote my earlier comment I was looking at the
underlying ESP-IDF functions not at the esp8266 implementation. The
ESP32 can do some extra new stuff but at least step 1 is to get
functional parity with ESP8266.
It's on my list but I haven't had a chance to look at it, PRs
welcome :-).
…On Thu, Mar 23, 2017, at 05:29, Eric Poulsen wrote:
@nickzoic[1], Why wouldn't it be implemented the same way as the 8266
wakeup (i.e. w/ a reset)? Then the code could check the wake reason.
Would make MP scripts backwards compatible with 8266.
— You are receiving this because you were mentioned. Reply to this
email directly, view it on GitHub[2], or mute the thread[3].
--
Nick Moore <nick@zoic.org> 0409 656 267
Links:
1. https://github.com/nickzoic
2. #32 (comment)
3. https://github.com/notifications/unsubscribe-auth/ABazRj4Y6LZmndTNoYoUaSa-385zZ7FQks5roWiDgaJpZM4MN7Ii
|
Nick,
I'm OK with creating a PR -- my ESP32 devices should arrive tomorrow.
Already have my dev environment up and working (compiled MP-esp32 from
source) -- just need the hardware. Also have the 8266 MP working here.
Would appreciate your thoughts WRT whats below:
…-----------------------------------------------------------------------------------------------------
It will have to be different from the 8266, which is currently:
import machine
# configure RTC.ALARM0 to be able to wake the device
rtc = machine.RTC()
rtc.irq(trigger=rtc.ALARM0, wake=machine.DEEPSLEEP)
# set RTC.ALARM0 to fire after 10 seconds (waking the device)
rtc.alarm(rtc.ALARM0, 10000)
# put the device to sleep
machine.deepsleep()
I'd probably implement more like this for the ESP32:
Import machine
machine.deepsleep(timeMs = None, ext0_pin = None, ext0_level = None,
ext1_pins = 0, ext1_level = None, touchPad = False)
which will throw an exception if none of the sleep options are set, though
perhaps you can enter deep sleep *without* any wake sources.
Note the time would be in milliseconds (though the esp32 supports
microseconds) to match the 8266 API (somewhat).
Wasn't planning on supporting the ULP wakeup, since it looks like you have
to program that in assembly, though maybe some canned routines in the
future?
On Wed, Mar 22, 2017 at 4:03 PM, Nick Moore <notifications@github.com>
wrote:
Yeah, it should. When I wrote my earlier comment I was looking at the
underlying ESP-IDF functions not at the esp8266 implementation. The
ESP32 can do some extra new stuff but at least step 1 is to get
functional parity with ESP8266.
It's on my list but I haven't had a chance to look at it, PRs
welcome :-).
On Thu, Mar 23, 2017, at 05:29, Eric Poulsen wrote:
> @nickzoic[1], Why wouldn't it be implemented the same way as the 8266
> wakeup (i.e. w/ a reset)? Then the code could check the wake reason.
> Would make MP scripts backwards compatible with 8266.
> — You are receiving this because you were mentioned. Reply to this
> email directly, view it on GitHub[2], or mute the thread[3].
>
--
Nick Moore ***@***.***> 0409 656 267
Links:
1. https://github.com/nickzoic
2. https://github.com/micropython/micropython-esp32/
issues/32#issuecomment-288495567
3. https://github.com/notifications/unsubscribe-
auth/ABazRj4Y6LZmndTNoYoUaSa-385zZ7FQks5roWiDgaJpZM4MN7Ii
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#32 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAYHCDx8c1ntqyXgDuYmgnt8TVB0oiv0ks5roaiwgaJpZM4MN7Ii>
.
|
I think the hope is to implement exactly the same as the ESP8266 API, but the underlying SDK functions are quite different so yeah, it's tricky to work out how that'd work. One option, I guess, would be to implement a compatible rtc module which supports the rtc.irq function and then have the deepsleep function understand that. It does seem like an odd way to do it, I agree ... my original thoughts were much like your proposal above. Perhaps this is something Damien could weigh in on since he'll have to approve the PR anyway! |
If there are good ideas for an alternative way to do deepsleep and waking then we can consider them and see if it's possible to change the esp8266 as well, so that everything is the same.
I think this is too complex and won't generalise well to other MCUs. Some MCUs don't have a touch pad, and some would have other events that can wake it up (eg network traffic). That is why the current design has the peripherals configure their own wake-up behaviour, and deepsleep() just goes to sleep. |
Hmm, agreed.
Proposed:Backwards compatible
TouchSet or return wake on touch, wake =
EXT0 pinSet or return waking on a single external pin;
EXT1 pinsSet or return waking on a set of pins;
|
Would it be best to have a high-level "deep sleep" μPy interface (perhaps That way users who "just want to save power for a set period of time" can do so easily, across platforms, but users who want to use different features of their particular hardware (e.g. touch wake on ESP32) can do so. Keeping the In any case, I'm going to move forward on making deep sleep work on the ESP32, and worry about the user-facing API later. |
@pacmac |
Wake on touch is 99% implemented, but since it requires and updated ESP-IDF, the actual call to enable touch wake is commented out in C, and if you try to set a touch wake, you get a RuntimeError. The rest is working (see below); I'm awaiting your comments on the Python API (see above). EXT0 wake:import machine as m
p = m.Pin(4)
r = m.RTC()
p.init(p.IN, p.PULL_UP)
r.wake_on_ext0(pin = p, level = 0)
m.deepsleep() EXT1 wake:import machine as m
pins = (m.Pin(2), m.Pin(4))
for p in pins:
p.init(m.Pin.IN, m.Pin.PULL_UP)
r = m.RTC()
r.wake_on_ext1(pins = pins, level = r.WAKEUP_ALL_LOW)
m.deepsleep() Timer wake:import machine as m
r = m.RTC()
r.irq(trigger=r.ALARM0, wake=m.DEEPSLEEP)
r.alarm(r.ALARM0, 3000)
m.deepsleep() |
Sorrie, I have not had chance to test this, I had to drop my focus on the ESP32 due to other projects on 8266 which I originally was hoping to convert to ESP32. I will try it out in the next couple of days. |
No worries; I look forward to any feedback =)
…On Mon, Apr 3, 2017 at 8:55 PM, pacmac ***@***.***> wrote:
Sorrie, I have not had chance to test this, I had to drop my focus on the
ESP32 due to other projects on 8266 which I originally was hoping to
convert to ESP32.
I will try it out in the next couple of days.
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#32 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAYHCAvif3-jRvgPZ3oLdnlSTpEli9Z-ks5rsb8ygaJpZM4MN7Ii>
.
|
@MrSurly for the pin wake up, the API was originally designed to allow something like: import machine
p = machine.Pin(0, machine.Pin.IN)
p.irq(trigger=p.IRQ_RISING, wake=machine.DEEPSLEEP)
machine.deepsleep() That's how it works on WiPy 1.0. That also mirrors how RTC can be used to wake after a specified time.
Yes, perhaps it is a good idea to allow to pass a time to the deepsleep() function. I think @pfalcon had this idea long ago but I argued against it back then. |
I'm all for it. I can see your point that things like the per-pin IRQ
triggers are best under machine.Pin but the deepsleep functionality
seems pretty universal.
'machine' is always going to be a bit of a jungle though as each
platform has its own eccentricities. It'd be nice to just call
deepsleep(1000) without worrying about the details and having your code
just continue on where it left off ...
|
Folks, just want to let you know that another kind of sleep (light sleep) will land into the IDF soon-ish. In the most basic case of light sleep, CPUs are halted and memory is preserved. All wakeup sources supported for deep sleep are also supported for light sleep. You may want to take this into consideration when designing the API. |
@igrr On a wake from light sleep, does the CPU reset, or does it resume where it left off? Something else? |
By default, it continues from where it stopped. Resetting is also possible, if required. |
@igrr thanks for the info! Light sleep will definitely be useful. |
Thanks for the information. We will keep it in mind when working on the API.
On Apr 12, 2017 15:41, "Ivan Grokhotkov" <notifications@github.com> wrote:
By default, it continues from where it stopped. Resetting is also possible,
if required.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#32 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAYHCPfVzJ4SF0nUAkNL_6vMGBn6SgTsks5rvVMmgaJpZM4MN7Ii>
.
|
The API as it is now matches other implementations, but doesn't make
much sense for the ESP32.
Yeah, that's my feeling as well ... implementing a deepsleep compatible
with ESP8266 makes sense for the moment, but in the longer run we should
be supporting all the abilities of the ESP32. This is, of course, a bit
controversial and we have to, as a community, have a think about exactly
how we're going to handle backwards, forwards and cross-port
compatibility.
I haven't had a chance to really think about it in recent weeks
though ...
------Nick
|
This is what I'm submitting, for now; not implementing wake-on-touch just yet, need to dig deeper. EXT0 wake:import machine as m
p = m.Pin(4)
r = m.RTC()
p.init(p.IN, p.PULL_UP)
r.wake_on_ext0(pin = p, level = 0)
m.deepsleep() EXT1 wake:import machine as m
pins = (m.Pin(2), m.Pin(4))
for p in pins:
p.init(m.Pin.IN, m.Pin.PULL_UP)
r = m.RTC()
r.wake_on_ext1(pins = pins, level = r.WAKEUP_ALL_LOW)
m.deepsleep() Timer wake:import machine as m
m.deepsleep(sleep_ms = 3000) |
PR #85 |
Been a long time since the PR, is this going to happen ?? I have a few 8266 projects that are just waiting to convert to esp32, but deepsleep() is pretty much essential. |
@igrr Any word on light sleep? |
Light sleep available is in ESP-IDF master: http://esp-idf.readthedocs.io/en/latest/api-reference/system/sleep_modes.html. Let me know if you see any issues with that. Note that we still plan to optimize current consumption a bit, since the present value (1.1mA) is higher than the one advertised in the datasheet (0.8mA). |
Thanks for the deep sleep implementation. Do you get the following during the restart after a deepsleep?
According to the ESP-IDF docs, a WDT causes the ESP to initialize RTC memory. Here is my deepsleep trace:
|
Sounds similar to #110 |
The fix for the flash read err on the deep sleep wakeup is to change CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY from 0 to 2000 in sdkconfig.h |
@manningt Thanks for this. When I get around to fixing this up, I'll use this. |
I am using ESP32 board(ESP-WROOM-32). I downloaded the recent binary image(esp32-20171008-v1.9.2-276-ga9517c04.bin) for ESP32 boards (https://micropython.org/download#esp32). I could run codes for GPIO, SPI, and Wifi. However, some methods ( machine.RTC(), utime.localtime()) do not work as follows: >>> import machine
>>> machine.RTC()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'RTC'
>>>
>>> machine.deepsleep(sleep_ms = 3000)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'deepsleep'
>>> >>> import utime
>>> utime.localtime()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'localtime'
>>> Please let me know how I can work these methods. |
|
machine.RTC() and machine.deepsleep() are part of a PR[1] that has
not been merged into the ESP32 port.
... yet!
Links:
1. #85
|
I added the RTC memory implementation to machine_rtc.c, as per the attached file. |
Thanks for this; I'll have time to look at it next week, probably. |
Thank you very much for your contributions. The memory bit works flawlessly, and the bit WRT CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY was critical. Merging this now; added your name/email to the RTC module copyright, if that's okay:
|
@manningt Any luck on getting light sleep to work? It "works" in that it will sleep for the time specified, but then I get a screenfull of gibberish on the serial, then a WDT reset. Memory is not preserved. |
@MrSurly Glad to contribute. I needed both deep-sleep and RTC memory for my application, i.e. selfish motivation. Thanks for adding me on the copyright. I did not test light-sleep, although it looks like may not be ready yet according to this ESP32 forum post. |
As is most of what I'm doing =)
Wow, those last two posts are nearly 2 years apart. |
You looked at the "joined" dates. Happens to me all the time too. |
@robert-hh I sure did =) |
RTC? |
This has moved to micropython/micropython#3531 , closing it here. |
I know this is a big one, but it's really the critical thing when using battery power.
Is this on the near horizon ??
The text was updated successfully, but these errors were encountered: