ESP32: get which EXT1 pin caused wake

All ESP32 boards running MicroPython.
Target audience: MicroPython users with an ESP32 board.
sergei.nz
Posts: 6
Joined: Fri Oct 15, 2021 4:08 am

ESP32: get which EXT1 pin caused wake

Post by sergei.nz » Fri Oct 15, 2021 4:15 am

Is it possible to detect which pin caused the ESP32 to wake from deepsleep when using EXT1 trigger?

My issue is that by the time the board boots the pin goes low thus no way to figure out which pin triggered.

I guess I could use the EXT0 with EXT1 to split between two pins (I assume it is possible?) but that seems a dirty solution and would only work with 2 pins.

Other alternative is to add a delay one-shot (hardware) timer to just keep the pin up long enough for it to be registered in the code, but that also has issues: if the second pin becomes up a little bit after the first, I would not be able to tell the wake pin reliably.

davef
Posts: 811
Joined: Thu Apr 30, 2020 1:03 am
Location: Christchurch, NZ

Re: ESP32: get which EXT1 pin caused wake

Post by davef » Fri Oct 15, 2021 5:47 am

I am also working with gpio_wakeup so thought I'd have a look, don't know if this is helpful:
https://rntlab.com/question/how-to-know ... deepsleep/

Looks like 2 years ago there wasn't a proper way to do it but ...

sergei.nz
Posts: 6
Joined: Fri Oct 15, 2021 4:08 am

Re: ESP32: get which EXT1 pin caused wake

Post by sergei.nz » Fri Oct 15, 2021 6:06 am

It looks like there is no such mechanism in micropython: https://github.com/micropython/micropython/issues/6981

I am trying various ways with hardware to do such thing.
Three options:

1) use transistors in a simple delay circuit. This works great except the output slowly drops as it follows RC circuit voltage.
2) Use 555 timer. This doesn't really work as it requires inverted input. Might need to invert it with a transistor.
3) Use opamp mono-stable, I haven't looked at this as yet.

So the basic idea with a hardware botch is to hold the input high long enough for the micro to boot from deepsleep.

davef
Posts: 811
Joined: Thu Apr 30, 2020 1:03 am
Location: Christchurch, NZ

Re: ESP32: get which EXT1 pin caused wake

Post by davef » Fri Oct 15, 2021 6:56 am

The other thing that occurred to me but perhaps a bit clunky ... could you save which pin caused the wakeup as per the link and on boot have a look at what is in the file?

sergei.nz
Posts: 6
Joined: Fri Oct 15, 2021 4:08 am

Re: ESP32: get which EXT1 pin caused wake

Post by sergei.nz » Fri Oct 15, 2021 8:06 am

davef wrote:
Fri Oct 15, 2021 6:56 am
The other thing that occurred to me but perhaps a bit clunky ... could you save which pin caused the wakeup as per the link and on boot have a look at what is in the file?
That method does not work as the signal goes away before I could get value of the pin (boot takes few seconds).
I have tried to read the value first thing after the boot, no success.
In other words if the signal lasts only 0.1s and the boot takes 2s, there is no way to capture the value of the pin.

Meanwhile I have tried the opamp approach, and the LM358 idles at 0.5mA. It does work though, and allow me arbitrary delay OFF time (very lazy debouncer), with 10uF/100k RC (plus parasitics from non-inverting Schmidt trigger opamp feedback/divider) I get about 2 seconds worth of latch time.

I wish opamp would consume an order of magnitude less.... I might go back to transistor method and replace BJT with MOSFETs.

User avatar
Roberthh
Posts: 3667
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: ESP32: get which EXT1 pin caused wake

Post by Roberthh » Fri Oct 15, 2021 8:57 am

You could use a digital schmitt-trigger like 74hc14 + R-C-Diode instead of an op-amp, with a typical supply current of 2µA, or an Attinyx5 with a sleep current of <1µA, which would be woken up by the ext1 signal and creates the intended response. No external parts required.

User avatar
karfas
Posts: 193
Joined: Sat Jan 16, 2021 12:53 pm
Location: Vienna, Austria

Re: ESP32: get which EXT1 pin caused wake

Post by karfas » Fri Oct 15, 2021 6:36 pm

As the Espressif API provides a call to find out the wakeup sources, there is no reason I can imagine (besides the ultra-slow process to get ESP32 related changes into the micropython main line) why micropython can't have support for finding out the wakeup sources.

See https://docs.espressif.com/projects/esp ... modes.html
There you will find:

uint64_t esp_sleep_get_ext1_wakeup_status(void)
Get the bit mask of GPIOs which caused wakeup (ext1)
If wakeup was caused by another source, this function will return 0.
Return
bit mask, if GPIOn caused wakeup, BIT(n) will be set
A few hours of debugging might save you from minutes of reading the documentation! :D
My repositories: https://github.com/karfas

sergei.nz
Posts: 6
Joined: Fri Oct 15, 2021 4:08 am

Re: ESP32: get which EXT1 pin caused wake

Post by sergei.nz » Fri Oct 15, 2021 7:37 pm

karfas wrote:
Fri Oct 15, 2021 6:36 pm
As the Espressif API provides a call to find out the wakeup sources, there is no reason I can imagine (besides the ultra-slow process to get ESP32 related changes into the micropython main line) why micropython can't have support for finding out the wakeup sources.

See https://docs.espressif.com/projects/esp ... modes.html
There you will find:

uint64_t esp_sleep_get_ext1_wakeup_status(void)
Get the bit mask of GPIOs which caused wakeup (ext1)
If wakeup was caused by another source, this function will return 0.
Return
bit mask, if GPIOn caused wakeup, BIT(n) will be set
This is exactly what I am after, at the moment this functionality is not available in micropython....
Roberthh wrote:
Fri Oct 15, 2021 8:57 am
You could use a digital schmitt-trigger like 74hc14 + R-C-Diode instead of an op-amp, with a typical supply current of 2µA, or an Attinyx5 with a sleep current of <1µA, which would be woken up by the ext1 signal and creates the intended response. No external parts required.
I will try your idea (74HC14 one), it seems more efficient than running a dual opamp, plus with 6 inverters I can do 3 inputs.

User avatar
Roberthh
Posts: 3667
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: ESP32: get which EXT1 pin caused wake

Post by Roberthh » Fri Oct 15, 2021 8:12 pm

@karfas: you are right, in that creating a method like machine.wake_ext1_status() similar to machine.wake_reason() in modmachine.c is pretty simple. Something like the code below. Doing that is not a problem, getting a PR merged may take some time.

Code: Select all

STATIC mp_obj_t machine_wake_ext1_status(void) {
    return mp_obj_new_int_from_ull(esp_sleep_get_ext1_wakeup_status());
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(machine_wake_ext1_status_obj, machine_wake_ext1_status);
And in the dictionary at the end of modmachine.c:

Code: Select all

    { MP_ROM_QSTR(MP_QSTR_wake_ext1_status), MP_ROM_PTR(&machine_wake_ext1_status_obj) },

sergei.nz
Posts: 6
Joined: Fri Oct 15, 2021 4:08 am

Re: ESP32: get which EXT1 pin caused wake

Post by sergei.nz » Sat Oct 16, 2021 6:08 am

I have finished the 74HC14 high/leading edge de-bouncer/delay board with great results. Thanks for the suggestion!
The idle current is around 40uA (due to pull up resistors), which is acceptable for this particular application.

Here it is:
High side Schmidt delay debouncer board sm.jpg
High side Schmidt delay debouncer board sm.jpg (303.37 KiB) Viewed 10600 times
High side Schmidt delay debouncer.png
High side Schmidt delay debouncer.png (9.2 KiB) Viewed 10600 times
It would be great to have the wake status ported to the micropython, so I don't have to have hacks like the above.
The downside of this board, well, it is the existence of this board. The real estate of the project enclosure is at premium.

Post Reply