ESP32: get which EXT1 pin caused wake

All ESP32 boards running MicroPython.
Target audience: MicroPython users with an ESP32 board.
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 » Sat Oct 16, 2021 6:32 am

Only one thing I would query about the hardware solution is leakage current of the electro with temperature and aging.

I would vote for some experienced person to submit a PR.

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 » Sat Oct 16, 2021 7:36 am

Roberthh wrote:
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) },
@roberthh:
This OK as a quick hack to get at least some info about the wakeup pins.

However, we should also think over a more micropypthon-like interface. We use a list of Pin objects to define the Ext1 sources, so this should at return a list of Pin objects as well (or at least one Pin - I have no idea if the function returns N bits set when more than one EXT1 inputs become active at the same time).

And I didn't check whether other useful functions here are not accessible from micropython - e.g. esp_sleep_enable_wifi_wakeup() ?
A few hours of debugging might save you from minutes of reading the documentation! :D
My repositories: https://github.com/karfas

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 » Sat Oct 16, 2021 8:35 am

I did not look into the return code in detail, but my first impression was that of a bit map of GPIO pins. That would have the information about which pin fired.

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 » Sat Oct 16, 2021 10:19 am

Roberthh wrote:
Sat Oct 16, 2021 8:35 am
... of a bit map of GPIO pins. That would have the information about which pin fired.
Yes, it's a bit map. OK, that's enough for a fast and easy solution - I might have done it in this way instead of building external, power-hungry devices.
But is this consistent with other micropython API calls ? I don't think so.

Someone already decided to abstract away the bitmap found in the ESP-IDF esp_sleep_enable_ext1_wakeup() call. The setup of the wakeup sources gets a tuple of Pin objects, like in https://rntlab.com/question/how-to-know ... deepsleep/

Code: Select all

wake1 = Pin(32, mode = Pin.IN)
wake2 = Pin(25, mode = Pin.IN)
esp32.wake_on_ext1(pins = (wake1, wake2), level = esp32.WAKEUP_ANY_HIGH)
It's not useful/consistent from a caller/user perspective to setup the sources like above and require the interpretation of a bitmap on the other hand.
What should a micropython function machine.wake_ext1_status() return ?
  • the bitmap ?
  • A single pin number or Pin object ?
  • A tuple of pin numbers/objects ?
  • A list of pin numbers/objects ?
  • Something (what ?) else ?
Am I thinking way too much about these details ?

Regards,
Thomas
A few hours of debugging might save you from minutes of reading the documentation! :D
My repositories: https://github.com/karfas

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 » Sat Oct 16, 2021 12:48 pm

AFAIK, you are asking for information that does not exist. EXT0 and EXT1 cause a wakeup from deep sleep, which behaves like a reset. Any previous information of the code that was kept in RAM does not exist any more. So the only information available is about the hardware - the port bitmap.

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 » Sat Oct 16, 2021 1:06 pm

@sergei.nz I can provide to you a firmware image with the little addition I've posted. Just tell me, which board you have, ESP32 GENERIC or GENERIC_SPIRAM.

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 » Sat Oct 16, 2021 2:03 pm

Of course it's not possible to return the original Pin objects. These are gone and away.
But the bitmap translates to a set/tuple(?) of port numbers.
Why do you want to introduce a new object type "Pin bitmap" nobody ever heard of (AFAIK) in the context of Micropython pins?
A few hours of debugging might save you from minutes of reading the documentation! :D
My repositories: https://github.com/karfas

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 » Sat Oct 16, 2021 3:13 pm

The bitmap is just an integer. Testing, whether a certain bit is set is as easy as checking, whether a tuple contains a number - at least when one knows the binary coding of numbers. But if you like a different data type, please do so.
b.t.w. it's better to have that method in the esp32 module together with the wake_on_ext1() method, since it is ESP32-specific.

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 » Sat Oct 16, 2021 4:14 pm

Creating a tuple of integers is not that bulky. Assigning a pin object to the tuple would be C-wise easy, but that static table of pin objects is encapsulated in machine_pin.c. I do not know whether it would be helpful in checking, whether a certain pin fired, because then the pin object has to be created first for comparison, so e.g. instead of:

wakes = esp32.wake_on_ext1_status()
if 4 in wakes:
....

you'd have to write

if (Pin(4) in wakes:
......

Code: Select all

STATIC mp_obj_t esp32_wake_on_ext1_status(void) {
    uint64_t status = esp_sleep_get_ext1_wakeup_status();
    uint64_t mask;
    int len=0, index;
    // For simplicity, just allocate the maximum number of tuples on the stack
    // instead of fiddling with dynamic lists, which will anyhow be discarded.
    mp_obj_t tuple[64]; 
    for (mask = 1, index = 0; index < 64; mask <<= 1, index++) {
        if (status & mask) {
            tuple[len] = MP_OBJ_NEW_SMALL_INT(index);
            len++;
        }
    }
    return mp_obj_new_tuple(len, tuple);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(esp32_wake_on_ext1_status_obj, esp32_wake_on_ext1_status);

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

Re: ESP32: get which EXT1 pin caused wake

Post by sergei.nz » Sun Oct 17, 2021 12:09 am

Roberthh wrote:
Sat Oct 16, 2021 1:06 pm
@sergei.nz I can provide to you a firmware image with the little addition I've posted. Just tell me, which board you have, ESP32 GENERIC or GENERIC_SPIRAM.
Thanks for the offer! Really appreciate it, although at this stage my hardware work around is in place (I just need to tweak my logic a bit).
I can wait until the feature is in official image.
karfas wrote:
Sat Oct 16, 2021 2:03 pm
Of course it's not possible to return the original Pin objects. These are gone and away.
But the bitmap translates to a set/tuple(?) of port numbers.
Why do you want to introduce a new object type "Pin bitmap" nobody ever heard of (AFAIK) in the context of Micropython pins?
I may sound stupid, but from end user perspective having a list of pin numbers (a set or a tuple will also work) is more convenient than a int/bytes object as a map. But either way even having just a bitmap, as long as there is a documented way to calculate the actual pin numbers would be fine.

Post Reply