Page 1 of 1

Strange GPIO behaviour

Posted: Tue Nov 20, 2018 8:43 am
by andermutu99
Dear Community;

I am making a low consumption system with an ESP32. I use deepsleep mode to save power. I need to wake up my ESP32 every x seconds and when a button is pressed. To achieve that I use the following code:

Code: Select all

import machine
import time
import esp32

time.sleep(2)
d1 = machine.Pin(14, machine.Pin.IN, machine.Pin.PULL_UP)
bit0 = d1.value()
print (bit0)

esp32.wake_on_ext0(d1)
machine.deepsleep(20000)
Apparently, it works well, the ESP32 wakes up when the button is pressed or every x seconds. However, there is a strange behaviour: At first boot, bit0 value is 1, as it is a pull-up GPIO, but when wakes up from deepsleep, bit0 is always 0, does not matter if the button is pressed or not.

I have tested this code on two different ESP32 boards, can anyone explain this or test this code?

Thanks in advance.

Ander.

Re: Strange GPIO behaviour

Posted: Tue Nov 20, 2018 8:22 pm
by OutoftheBOTS_
If I am wrong someone here will correct me.

It is my understanding that the ESP32 has 3 cores (2 main cores and 1 ultra low power core). When you put the ESP32 into deep sleep it turns off the 2 main cores and powers down there RAM to save power consumption. The ULP core continues to run but it has little processing power or RAM but it does have the ability to restart the 2 main cores (exit deep sleep). When the 2 main cores restart it will be a fresh restart without any of the states of be fore entering deep sleep. If you need to return the 2 main cores to same state as before entering deep sleep you will need to write all needed data to either the flash storage or thr ULP RAM.

Re: Strange GPIO behaviour

Posted: Tue Nov 20, 2018 8:49 pm
by loboris
GPIO used for wakeup must be deinit after wake up to be used as digital input/output again, something like this:

Code: Select all

if (rtc_gpio_is_valid_gpio(self->id)) rtc_gpio_deinit(self->id);
I think that part is missing in the official MicroPython ESP32 port and that is the reason for the "Strange GPIO behaviour".

Re: Strange GPIO behaviour

Posted: Wed Nov 21, 2018 10:51 am
by andermutu99
loboris wrote:
Tue Nov 20, 2018 8:49 pm
GPIO used for wakeup must be deinit after wake up to be used as digital input/output again, something like this:

Code: Select all

if (rtc_gpio_is_valid_gpio(self->id)) rtc_gpio_deinit(self->id);
I think that part is missing in the official MicroPython ESP32 port and that is the reason for the "Strange GPIO behaviour".
So if that part is missing I can't do anything to solve the problem?

I have also noticed that if I remove these line:

Code: Select all

esp32.wake_on_ext0(d1)
The problem is solved, and everything works as expected. So maybe is not a problem of deinit...

Thanks for your answer.

Re: Strange GPIO behaviour

Posted: Wed Nov 21, 2018 10:52 am
by andermutu99
OutoftheBOTS_ wrote:
Tue Nov 20, 2018 8:22 pm
If I am wrong someone here will correct me.

It is my understanding that the ESP32 has 3 cores (2 main cores and 1 ultra low power core). When you put the ESP32 into deep sleep it turns off the 2 main cores and powers down there RAM to save power consumption. The ULP core continues to run but it has little processing power or RAM but it does have the ability to restart the 2 main cores (exit deep sleep). When the 2 main cores restart it will be a fresh restart without any of the states of be fore entering deep sleep. If you need to return the 2 main cores to same state as before entering deep sleep you will need to write all needed data to either the flash storage or thr ULP RAM.
Hi, I think that ULP core is powered off during deep sleep...

Re: Strange GPIO behaviour

Posted: Wed Nov 21, 2018 3:55 pm
by loboris
andermutu99 wrote:
Wed Nov 21, 2018 10:51 am
So if that part is missing I can't do anything to solve the problem?
If the pin is not used for wake-up, no deinit is needed.
If you remove

Code: Select all

esp32.wake_on_ext0(d1)
then you cannot wake-up with a pin.

It works in my MicroPython port (Forum).

Code: Select all

>>> import machine
>>> rtc = machine.RTC()
>>> d1 = machine.Pin(32, machine.Pin.IN, machine.Pin.PULL_UP)
I (155332) gpio: GPIO[32]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 
>>> bit0 = d1.value()
>>> print(bit0)
1
>>> bit0 = d1.value()
>>> print(bit0)
0
>>> rtc.wake_on_ext0(d1)
>>> machine.deepsleep()
D (402960) DEEP SLEEP: EXT0=32
After wake-up with pin pulled low:

Code: Select all

...
I (1173) MicroPython: [=== MicroPython FreeRTOS task started (sp=3ffd8850) ===]
...
FreeRTOS running on BOTH CORES, MicroPython task started on App Core (1).
 
 Reset reason: Deepsleep wake-up
Wakeup source: EXT_0 wake-up
    uPY stack: 15360 bytes
     uPY heap: 3073664/144/3073520 bytes (in SPIRAM using heap_caps_malloc)
MicroPython ESP32_LoBo_v3.2.25 - 2018-11-06 on ESP32 board with ESP32
Type "help()" for more information.
>>> import machine
>>> d1 = machine.Pin(32, machine.Pin.IN, machine.Pin.PULL_UP)
I (49142) gpio: GPIO[32]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 
>>> bit0 = d1.value()
>>> print(bit0)
1
>>> bit0 = d1.value()
>>> print(bit0)
0
>>> 

Re: Strange GPIO behaviour

Posted: Thu Nov 22, 2018 8:28 am
by andermutu99
loboris wrote:
Wed Nov 21, 2018 3:55 pm
andermutu99 wrote:
Wed Nov 21, 2018 10:51 am
So if that part is missing I can't do anything to solve the problem?
If the pin is not used for wake-up, no deinit is needed.
If you remove

Code: Select all

esp32.wake_on_ext0(d1)
then you cannot wake-up with a pin.

It works in my MicroPython port (Forum).

Code: Select all

>>> import machine
>>> rtc = machine.RTC()
>>> d1 = machine.Pin(32, machine.Pin.IN, machine.Pin.PULL_UP)
I (155332) gpio: GPIO[32]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 
>>> bit0 = d1.value()
>>> print(bit0)
1
>>> bit0 = d1.value()
>>> print(bit0)
0
>>> rtc.wake_on_ext0(d1)
>>> machine.deepsleep()
D (402960) DEEP SLEEP: EXT0=32
After wake-up with pin pulled low:

Code: Select all

...
I (1173) MicroPython: [=== MicroPython FreeRTOS task started (sp=3ffd8850) ===]
...
FreeRTOS running on BOTH CORES, MicroPython task started on App Core (1).
 
 Reset reason: Deepsleep wake-up
Wakeup source: EXT_0 wake-up
    uPY stack: 15360 bytes
     uPY heap: 3073664/144/3073520 bytes (in SPIRAM using heap_caps_malloc)
MicroPython ESP32_LoBo_v3.2.25 - 2018-11-06 on ESP32 board with ESP32
Type "help()" for more information.
>>> import machine
>>> d1 = machine.Pin(32, machine.Pin.IN, machine.Pin.PULL_UP)
I (49142) gpio: GPIO[32]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 
>>> bit0 = d1.value()
>>> print(bit0)
1
>>> bit0 = d1.value()
>>> print(bit0)
0
>>> 
Ok, thank you Loboris, I will consider using your MicroPython port.