Strange GPIO behaviour

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Post Reply
andermutu99
Posts: 18
Joined: Thu Sep 27, 2018 10:19 am

Strange GPIO behaviour

Post by andermutu99 » Tue Nov 20, 2018 8:43 am

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.

OutoftheBOTS_
Posts: 847
Joined: Mon Nov 20, 2017 10:18 am

Re: Strange GPIO behaviour

Post by OutoftheBOTS_ » 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.

loboris
Posts: 344
Joined: Fri Oct 02, 2015 6:19 pm

Re: Strange GPIO behaviour

Post by loboris » 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".

andermutu99
Posts: 18
Joined: Thu Sep 27, 2018 10:19 am

Re: Strange GPIO behaviour

Post by andermutu99 » Wed Nov 21, 2018 10:51 am

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.

andermutu99
Posts: 18
Joined: Thu Sep 27, 2018 10:19 am

Re: Strange GPIO behaviour

Post by andermutu99 » Wed Nov 21, 2018 10:52 am

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...

loboris
Posts: 344
Joined: Fri Oct 02, 2015 6:19 pm

Re: Strange GPIO behaviour

Post by loboris » 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
>>> 

andermutu99
Posts: 18
Joined: Thu Sep 27, 2018 10:19 am

Re: Strange GPIO behaviour

Post by andermutu99 » Thu Nov 22, 2018 8:28 am

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.

Post Reply