Skip to content

esp32 - Cannot Read Pin Value After Wake on Pin #3835

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
diginfo opened this issue Jun 2, 2018 · 10 comments
Closed

esp32 - Cannot Read Pin Value After Wake on Pin #3835

diginfo opened this issue Jun 2, 2018 · 10 comments

Comments

@diginfo
Copy link

diginfo commented Jun 2, 2018

This is also reported here: https://forum.micropython.org/viewtopic.php?f=18&t=4856
And Here: #3531 (comment)

This is what I thought would be a simple toggling of the wake pin trigger edge, but it turns out not !

This code should get the current value of door pin, and set the wake from deepsleep edge based on the pin value high or low and then put the device into deepsleep awaiting the trigger edge.

There is a 10K pull-down on pin 34 and the switch pulls it high.

The purpose is to wake up and sleep again each time the interrupt is triggered on a different edge.

The time.sleeps() are just to give time to view the output and should not have any other effect other than de-bouncing, but given that the esp32 startup time is 2 seconds, debouncing should not be needed.

It appears to work the first time deepsleep is fired, but thereafter door.value() always reads 0 even though the switch is closed and pulled high !

boot.py

import machine as mc, time
time.sleep(1)
door = mc.Pin(34,mc.Pin.IN)
edge =  5- door.value()
edgeMc = {
  5:'WAKE_HIGH',
  4:'WAKE_LOW'
}[edge] or 'BAD'

print('door:{}, edge:{}, edgeMc: {}'.format(door.value(), edge, edgeMc))
door.irq(trigger = edge, wake = mc.DEEPSLEEP)

time.sleep(5)
mc.deepsleep(60000)

Initially the switch was low:
door:0, edge:5, edgeMc: WAKE_HIGH

Then switch was then enabled (high):
door:1, edge:4, edgeMc: WAKE_LOW

Then, without changing the switch position, it just continuously loops, apparently unable to read the value of door any more:

door:0, edge:5, edgeMc: WAKE_HIGH
door:0, edge:5, edgeMc: WAKE_HIGH
door:0, edge:5, edgeMc: WAKE_HIGH
door:0, edge:5, edgeMc: WAKE_HIGH
door:0, edge:5, edgeMc: WAKE_HIGH
door:0, edge:5, edgeMc: WAKE_HIGH
@MrSurly
Copy link
Contributor

MrSurly commented Jun 2, 2018

So, this part:

door:0, edge:5, edgeMc: WAKE_HIGH
door:0, edge:5, edgeMc: WAKE_HIGH
door:0, edge:5, edgeMc: WAKE_HIGH
door:0, edge:5, edgeMc: WAKE_HIGH
door:0, edge:5, edgeMc: WAKE_HIGH

I assume you've removed the intervening logging -- can I get a full log printout of 2 or 3 cycles?

@diginfo
Copy link
Author

diginfo commented Jun 2, 2018

if 1==1:
  import machine as mc, time  
  wake = mc.Pin(35,mc.Pin.IN)
  
  time.sleep(1)
  val = wake.value()
  if val == 1:
    edge = mc.Pin.WAKE_LOW
  else:
    edge = mc.Pin.WAKE_HIGH

  wake.irq(trigger = edge , wake = mc.DEEPSLEEP)
  print('value:{}, edge:{}'.format(val, edge))

  time.sleep(1)
  mc.deepsleep()

  1. Set Switch / Pin High
  2. Hard Reset
  3. Code stops correctly at: value:1, edge:4
  4. Set Switch / Pin Low
  5. Code loops forever
  6. Set Switch High
  7. Code continues looping and shows pin value = 0 and not 1
ets Jun  8 2016 00:22:57

rst:0x1 (POWERON_RESET),boot:0x33 (SPI_FAST_FLASH_BOOT)
flash read err, 1000
ets_main.c 371 
ets Jun  8 2016 00:22:57

rst:0x10 (RTCWDT_RTC_RESET),boot:0x33 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0018,len:4
load:0x3fff001c,len:4484
load:0x40078000,len:0
load:0x40078000,len:11816
entry 0x4007a9fc
I (408) cpu_start: Pro cpu up.
I (408) cpu_start: Single core mode
I (409) heap_init: Initializing. RAM available for dynamic allocation:
I (412) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
I (418) heap_init: At 3FFC5098 len 0001AF68 (107 KiB): DRAM
I (424) heap_init: At 3FFE0440 len 00003BC0 (14 KiB): D/IRAM
I (431) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (437) heap_init: At 4008DD1C len 000122E4 (72 KiB): IRAM
I (443) cpu_start: Pro cpu start user code
I (14) cpu_start: Starting scheduler on PRO CPU.
value:1, edge:4
ets Jun  8 2016 00:22:57

rst:0x5 (DEEPSLEEP_RESET),boot:0x33 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0018,len:4
load:0x3fff001c,len:4484
load:0x40078000,len:0
load:0x40078000,len:11816
entry 0x4007a9fc
I (407) cpu_start: Pro cpu up.
I (408) cpu_start: Single core mode
I (408) heap_init: Initializing. RAM available for dynamic allocation:
I (411) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
I (417) heap_init: At 3FFC5098 len 0001AF68 (107 KiB): DRAM
I (424) heap_init: At 3FFE0440 len 00003BC0 (14 KiB): D/IRAM
I (430) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (436) heap_init: At 4008DD1C len 000122E4 (72 KiB): IRAM
I (443) cpu_start: Pro cpu start user code
I (13) cpu_start: Starting scheduler on PRO CPU.
value:0, edge:5
ets Jun  8 2016 00:22:57

rst:0x5 (DEEPSLEEP_RESET),boot:0x33 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0018,len:4
load:0x3fff001c,len:4484
load:0x40078000,len:0
load:0x40078000,len:11816
entry 0x4007a9fc
I (408) cpu_start: Pro cpu up.
I (408) cpu_start: Single core mode
I (408) heap_init: Initializing. RAM available for dynamic allocation:
I (411) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
I (417) heap_init: At 3FFC5098 len 0001AF68 (107 KiB): DRAM
I (424) heap_init: At 3FFE0440 len 00003BC0 (14 KiB): D/IRAM
I (430) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (436) heap_init: At 4008DD1C len 000122E4 (72 KiB): IRAM
I (443) cpu_start: Pro cpu start user code
I (13) cpu_start: Starting scheduler on PRO CPU.
value:0, edge:5

@MrSurly
Copy link
Contributor

MrSurly commented Jun 2, 2018

Does this happen on other pins?

@diginfo
Copy link
Author

diginfo commented Jun 2, 2018

Just tried on pin 26 exactly the same behaviour.

@MrSurly
Copy link
Contributor

MrSurly commented Jun 8, 2018

Still looking at this. Hang tight.

@MrSurly
Copy link
Contributor

MrSurly commented Jun 8, 2018

Filed upstream bug: espressif/esp-idf#2043

There are actually two bugs here (I think).

  1. Not being able to read the GPIO pin properly. I've fixed this already by calling gpio_config(), per GPIO input from pin used for wakeup not readable after wakeup espressif/esp-idf#245 (comment). This sort of "masks" the problem below, because the pin always reads 0, so that's why it's immediately triggering, right? Not really ...

  2. Seems that EXT0 wakes when level is 0 (wake low) don't work -- it always wakes immediately.

@MrSurly
Copy link
Contributor

MrSurly commented Jun 13, 2018

Workaround from Espressif, but I cannot implement or test until after the 25th, as I will be out-of-town.

@diginfo
Copy link
Author

diginfo commented Jun 13, 2018

can this be implemented using the python pin settings ?

@dpgeorge
Copy link
Member

It looks like Espressif have now fixed this bug in the latest ESP IDF. In d61d119 I updated the esp32 to use the new IDF version, so this bug should be fixed now.

@MrSurly
Copy link
Contributor

MrSurly commented Jun 24, 2018

@diginfo Can you confirm?

tannewt added a commit to tannewt/circuitpython that referenced this issue Feb 14, 2024
Greedily grab as much RMT memory as we can. It blocks other RMT
transmit channels but we only use it temporarily anyway. The more
we can grab, the fewer interrupts are needed to keep the transmit
going.

On ESP32, move CircuitPython to the second core. This helps NeoPixel
by moving the RMT interrupt to the second core as well.

When testing ESP32 I noticed that settings.toml writes won't apply
until after hard reset. This removes that constraint but still
requires the password to enable the web workflow.

Fixes micropython#3835
tannewt added a commit to tannewt/circuitpython that referenced this issue Feb 14, 2024
Greedily grab as much RMT memory as we can. It blocks other RMT
transmit channels but we only use it temporarily anyway. The more
we can grab, the fewer interrupts are needed to keep the transmit
going.

Flickers may still happen due to file system writes but most of the
time the animation just pauses.

On ESP32, move CircuitPython to the second core. This helps NeoPixel
by moving the RMT interrupt to the second core as well.

When testing ESP32 I noticed that settings.toml writes won't apply
until after hard reset. This removes that constraint but still
requires the password to enable the web workflow.

Fixes micropython#3835
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants