-
In doing an all micropython implementation for the esp32 based T-watch 2020 - see #10741 (comment), I hit a problem with lightsleep. Essentially, ideally, the watch should be woken up from light sleep by either a real-time clock, accelerometer or power management interrupt. However, since the real-time clock is active low and is not configurable neither of the EXT1 wakeup modes - ALL LOW or ANY HIGH works. The esp32 does have a GPIO wakeup facility that only applies to light sleep not deep sleep but this is not available in the current ESP32 port. There is a pull request for GPIO wakeup for the ESP32 C3 - see Issue #9583 (comment) Has anyone had the same problem? |
Beta Was this translation helpful? Give feedback.
Replies: 8 comments 3 replies
-
Yes, it would have saved me putting transistor inverters in several projects to use WAKEUP_ANY_HIGH. Could the constant not be changed? |
Beta Was this translation helpful? Give feedback.
-
The problem with GPIO wakeup is that it only applies to LOW and HIGH LEVEL interrupt triggers and these cause problems with ESP32 micropython in that you get continuous interrupts which do not give the ISR a chance to run and cancel the interrupt. To overcome this, I have implemented a solution which disables interrupts on a Pin immediately the LEVEL interrupt occurs. This leads to the light sleep solution example below:
Sample trace:
This implementation is consistent with the current micropython documentation for I would be interested on whether others view this as a sensible solution. |
Beta Was this translation helpful? Give feedback.
-
While I am sure your modification does work (I'm using it with the watch currently on my wrist), I am not happy with the concept of using At least on micropython level, a wakeup from light sleep or deep sleep has nothing to do with an IRQ. It has been a bad decision to mix wakeup sources (ext0) in the We can't do much regarding the ext0 configuration in In the moment...We have two different possibilities to configure ext0 wakeup sources:
We have an error in the documentation:
I could not find any call to To discussThe ESP-IDF functions for power save are complex and include e.g. functions like Doing some of these things implicit from functions in the For
Further calls to power save related functions should also live in Common power-save configurations (e.g. lightsleep while modem-sleep is in effect) can be handled in micropython itself. |
Beta Was this translation helpful? Give feedback.
-
Thanks for the feedback. In general, the Micropython approach seems to be to, as much as possible, abstract the details of specific architectures in the I have tried to follow this approach in implementing support for GPIO wakeup and have followed the existing documentation for In my view, GPIO wakeup is the most useful and general of the many esp32 wakeup mechanisms and it is a pity it did not also apply to I don't think there is any issue with backward compatibility as the existing implementation involving |
Beta Was this translation helpful? Give feedback.
-
I have the same problem : device with multiple buttons (pulled low when pressed) and need to use lightsleep(). My dive into the problem found: On ESP32, esp32.wake_on_ext1() wakes from lightsleep(), but the fact that only a 'ALL_LOW' option is possible means it doesn't work (have to press all the buttons simultaneously to trigger!). On ESP32S3, I can't get wake_on_ext1() to exit lightsleep() at all... I added a esp32.wake_on_gpio() method, which uses the gpio_wakeup_enable() and esp_sleep_enable_gpio_wakeup() functions. This works to exit lightsleep() as you say on both esp32 and esp32S3. [btw putting this function in esp32 module seems like the 'good' place for it to me as its specific to the esp32.] However, when the IRQ callback (set by Pin.irq()) gets called at the exit of the sleep the pin value is always 1 - and in fact the execution post-sleep blocks until the buttons is released. Reading this thread lets me see this is probably because triggering on level=0 means that the MCU is blocked looping on the IRQ until the button is released - and then the callback is run but the button is now released ie value()=1! @jeffmer : where did you add the interupt disabling to avoid this problem? Is there a patch available? I also wonder if the trigger for the irq gets changed by gpio_wakeup_enable() permanently to level detect (from the edge detect trigger I set when configuring the Pin to start with)? Then, having an 'enable()' and 'disable()' method on Pin seems generic enough to me to be ok (although I would call them enable_irq()/disable_irq() to make the purpose clear) |
Beta Was this translation helpful? Give feedback.
-
Also trying to get lightsleep wake on GPIO working. Here's what I see with current 1.22 preview.
If an allowed I tried adding the code to enable lightsleep GPIO wake up for Since the handler is ignored when However it doesn't work to call p = machine.Pin(8, machine.Pin.IN)
p.irq(lambda p: print("IRQ"), trigger=machine.Pin.IRQ_RISING, wake=machine.SLEEP)
p.irq(trigger=machine.Pin.WAKE_HIGH, wake=machine.SLEEP) That will IRQ loop! The problem is that |
Beta Was this translation helpful? Give feedback.
-
When I couldn't get my head around the GPIO wakeup minefield earlier this year I had no choice but to find a way to detect edges using esp32.wake_on_ext0. I ended up setting the level in esp32.wake_on_ext0(pin, level) to not pin() which wakes the esp32 whenever the pin level changes. Since my post wakeup tasks took longer than typical switch contact chatter I didn't even need a debouncer. Apologies if I'm too off topic but the technique seemed vaguely relevant. |
Beta Was this translation helpful? Give feedback.
-
What is the current I am using this firmware: Appreciate any insights. |
Beta Was this translation helpful? Give feedback.
The problem with GPIO wakeup is that it only applies to LOW and HIGH LEVEL interrupt triggers and these cause problems with ESP32 micropython in that you get continuous interrupts which do not give the ISR a chance to run and cancel the interrupt. To overcome this, I have implemented a solution which disables interrupts on a Pin immediately the LEVEL interrupt occurs. This leads to the light sleep solution example below: