I’m trying to use my ESP32-S3 Mini with two reed contacts. My goal is:
The ESP should wake from deep sleep when either contact changes.
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
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 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?
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) ?
You can use the esp_sleep_get_wakeup_cause() function to determine whether the ESP32 was woken by GPIO pin
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).