Esphome esp32s3 with two reed contact and deep sleep

Hi everyone,

I’m trying to use my ESP32-S3 Mini with two reed contacts. My goal is:

  1. The ESP should wake from deep sleep when either contact changes.
  2. After waking, it should send the updated status via MQTT.

I’d like to use the same GPIO pins for both deep sleep wakeup and as binary sensors.
However, when I try to compile my ESPHome configuration, I get the error:

Pin is used in multiple places

Is it possible to achieve this? How can I configure the pins so the ESP can wake up and read their state afterward?

Thanks in advance for any guidance!

deep_sleep:
  id: deep_sleep_ctrl
  run_duration: 40s          # ESP bleibt nach Wakeup 10 Sekunden aktiv
  esp32_ext1_wakeup:
    pins: [2, 3]   # beide Pins, die den ESP wecken sollen
    mode: ANY_LOW          # wake when any selected pin goes LOW
    


binary_sensor:
  - platform: gpio
    pin:
      number: 2
      mode: INPUT_PULLUP   # <- richtig eingerückt unter pin
      inverted: true       # optional, wenn LOW = gedrückt
    name: "Taster"
    device_class: door
    filters:
      - delayed_on: 50ms
      - delayed_off: 50ms
    on_press:
      - logger.log: "Taster gedrückt, Gerät wacht auf!"
  - platform: gpio
    name: "Tuer Verriegelt"
    id: lock_sensor
    pin:
      number: 3
      mode: INPUT_PULLUP
      inverted: true
    filters:
      - delayed_on: 50ms
      - delayed_off: 50ms

At me it works with “allow_other_uses”.

deep_sleep:
  id: deepsleep_cam_garage
		
  esp32_ext1_wakeup:
    pins: 
      number: 13
      allow_other_uses: true
    mode: ALL_LOW 
.
.
.


binary_sensor:
  - platform: gpio
    pin: 
      number: 13
      allow_other_uses: true
.
.
.

thank you.

after adding “allow_other_users” i got this error

deep_sleep: [source esp32cminiS3_Tuer.yaml:110]
  id: deep_sleep_ctrl
  run_duration: 40s
  esp32_ext1_wakeup: 
    pins: 
      - 3
      - 4
    mode: ANY_LOW
    
    [allow_other_uses] is an invalid option for [esp32_ext1_wakeup]. Please check the indentation.
    allow_other_uses: True

Strange, this is the code copied from my ESPCam that works at me:

esp32:
  board: esp32cam
  framework:
    type: arduino
.
.
.

# Deep sleep configuration 
deep_sleep:
  id: deepsleep_cam_garage
  esp32_ext1_wakeup:
    pins: 
      number: 13
      allow_other_uses: true
    mode: ALL_LOW 
    #mode: ANY_HIGH

  wakeup_pin_mode: KEEP_AWAKE
  run_duration: 45s
  sleep_duration: 10min

maybe you have to add it on a different way:

  esp32_ext1_wakeup:
    pins: 
      number: 3
      allow_other_uses: true
      number: 4
      allow_other_uses: true

or

  esp32_ext1_wakeup:
    pins: 
      - pin:
          number: 3
          allow_other_uses: true
      - pin:
          number: 4
          allow_other_uses: true

or similar.

In case allow_other_uses doesn’t work for multiple wakeup pins, you can physically split the input to two separate gpios, one configured for wakeup and other as binary sensor.

i thought i can use more than now gpis to wake up the esp32s3 mini

Afaik as many as you have free ext1 gpios on your board.

1 Like

I have now connected each of the two outputs with a diode to a third GPIO, which is then used as the wakeup GPIO.
This seems to work.

How can I now ensure that the last state change is also sent via MQTT,
for example if the door was opened and closed very quickly before the ESP woke up?

I’m not able to follow the description of your actual wiring.

Since your wake-up is LOW and you have binary sensors for actual state, what information is missing?

Did you check that you added allow-other_uses in all the places where those pins are used (ie the binary sensor(s) as well as deep_sleep) ?

  1. You can use the esp_sleep_get_wakeup_cause() function to determine whether the ESP32 was woken by GPIO pin
  2. It takes time for the ESP32 to boot up, but you can put code in on_boot at priority 600 to try to detect the reason for the wakeup even before wi-fi connects.

My code for detecting the first tip of a rain gauge (hoping the rain started gradually):

esphome:
  name: $devicename
  platformio_options:
    board_build.flash_mode: dio 
  on_boot: 
    - priority: 600            # most sensors setup, but before wi-fi connected
      then:
        #  2 - ESP_SLEEP_WAKEUP_EXT0: Wakeup caused by external signal using RTC_IO
        - lambda: |-
            if ( int(esp_sleep_get_wakeup_cause()) == 2 ) {
                      // process the rain gauge pulse which woke us up asap so we don't miss more tips
              ESP_LOGD("", "   >>>> RAIN detected while asleep. <<<<" );
              id(rain_gauge).publish_state(1.0);
                      // hopefully the next tip will be recorded by the pulse_counter
              ESP_LOGD(" ", " ");
            };

    - priority: -100
      then:
      - logger.log: "########### ON_BOOT at -100 ##########"
...

Maybe it’s not fast enough, but I can’t think of anything faster that wouldn’t involve adding more hardware.

Where I called publish_state you might need to store your finding and transmit it when MQTT is established (as indicated by the MQTT on_connect; trigger).