GPIO input stops working for garage door sensor after some days

I have two garage doors on my garage. I used an ESP32, 2 channel 5V relay, and 2 Honeywell garage door sensors to create a garage door opener and door status monitoring device. The relays signal the doors to open and close and the sensors tell me if the door is currently in an open or closed state. Here’s a snippet from my ESPHome yaml file for this device:

esphome:
  name: garage_door
  platform: ESP32
  board: esp32doit-devkit-v1

# ...

binary_sensor:
  # Garage Door 1
  - platform: gpio
    pin:
      number: GPIO18
      mode: INPUT_PULLUP
      inverted: False
    name: "Garage Door 1 Sensor"
    id: garage_door_1_sensor
    device_class: garage_door
    filters:
      - delayed_on: 500ms
      - delayed_off: 500ms
      - delayed_on_off: 1s

  # Garage Door 2
  - platform: gpio
    pin:
      number: GPIO21
      mode: INPUT_PULLUP
      inverted: False
    name: "Garage Door 2 Sensor"
    id: garage_door_2_sensor
    device_class: garage_door
    filters:
      - delayed_on: 500ms
      - delayed_off: 500ms
      - delayed_on_off: 1s

switch:
  # Garage Door 1
  - platform: gpio
    id: garage_door_1_relay
    pin:
      number: GPIO22
      inverted: False
    restore_mode: ALWAYS_OFF
  - platform: template
    name: "Garage Door 1 Switch"
    icon: "mdi:garage"
    turn_on_action:
    - switch.turn_on: garage_door_1_relay
    - delay: 1s
    - switch.turn_off: garage_door_1_relay

  # Garage Door 2
  - platform: gpio
    id: garage_door_2_relay
    pin:
      number: GPIO23
      inverted: False
    restore_mode: ALWAYS_OFF
  - platform: template
    name: "Garage Door 2 Switch"
    icon: "mdi:garage"
    turn_on_action:
    - switch.turn_on: garage_door_2_relay
    - delay: 1s
    - switch.turn_off: garage_door_2_relay

cover:
  # Garage Door 1
  - platform: template
    name: Garage Door 1
    device_class: garage
    lambda: !lambda |-
      if (id(garage_door_1_sensor).state) {
        return COVER_OPEN;
      } else {
        return COVER_CLOSED;
      }
    open_action:
      - switch.turn_on: garage_door_1_relay
      - delay: 1s
      - switch.turn_off: garage_door_1_relay
    close_action:
      - switch.turn_on: garage_door_1_relay
      - delay: 1s
      - switch.turn_off: garage_door_1_relay
    stop_action:
      - switch.turn_on: garage_door_1_relay
      - delay: 1s
      - switch.turn_off: garage_door_1_relay

  # Garage Door 2
  - platform: template
    name: Garage Door 2
    device_class: garage
    lambda: !lambda |-
      if (id(garage_door_2_sensor).state) {
        return COVER_OPEN;
      } else {
        return COVER_CLOSED;
      }
    open_action:
      - switch.turn_on: garage_door_2_relay
      - delay: 1s
      - switch.turn_off: garage_door_2_relay
    close_action:
      - switch.turn_on: garage_door_2_relay
      - delay: 1s
      - switch.turn_off: garage_door_2_relay
    stop_action:
      - switch.turn_on: garage_door_2_relay
      - delay: 1s
      - switch.turn_off: garage_door_2_relay

This device worked great when I first wired it up and starting using it. A couple of weeks later I noticed that the binary sensor on door 2 (garage_door_2_sensor) was not reporting correctly. The binary sensor was always showing that the door was closed, even when it was in fact open. The relay switch still worked fine for open/closing it, however.

After doing some basic troubleshooting with my multimeter, I discovered that the sensor hardware and wiring were still working as expected. After rebooting the ESP32 several times, the problem was not resolved so I thought there might be a problem with the GPIO pin. I moved the garage_door_2_sensor from GPIO19 to GPIO21, made the pin number change in the ESPHome yaml config, loaded new firmware OTA, and everything starting working properly again as expected.

I thought I had solved the problem and it was just some issue with that pin on the ESP32. Fast forward a couple of days, and now the same problem has started happening again on GPIO21. garage_door_2_sensor is always reporting that the door is closed. I assume that I could move the sensor to another GPIO again and it will start working again temporarily.

Any idea what is going on here? Why would these pins stop working for door 2? Door 1 has not had any problems and it is wired up the same way. One end of the sensor wire goes to ground and the other end to the GPIO. Why are these pins dying?

What is your wiring?

I don’t think delayed_on, delayed_off and delayed_on_off together makes sense?

One end of the binary sensor wire goes to ground and the other end to the GPIO

What is the voltage on the sensor wire (with the ESP disconnected from it)?
Is the Honeywell device perhaps sending 5v at your GPIO pin, which eventually damaged it?

Voltage is 0. It has no power source. I don’t see how it could send anything other than what is coming out of the GPIO circuit it is hooked up to on the ESP32.

It was just a guess, since I know nothing about the Honeywell device, electrically. (does it have a model # I could look up?)
I once built a very similar setup using a Craftsman door monitor, which lit a red or green LED based on the door status. But rather than take a chance using voltage dividers, etc, I just added an optoisolator to the Craftsman, creating a solid-state relay with ‘dry’ contacts for my GPIO to use for detecting the state of the LED.
There’s also the possibility that the wire to the Honeywell - if it’s long - is picking up some induced current from something it passes near, and that it is of sufficient voltage to damage your GPIO. (again, just a guess)

I linked the Honeywell device up in the original post. The wires are a bit long on the sensors. Maybe 20 ft to door #2. The wire to door #1 sensor is probably 30 ft, though. You could be right though, since I think it is laying across a few 120v romex circuits up in the attic. Maybe I can try stapling it up off the floor so that it doesn’t have to cross those lines. Any other ideas?

Ah, I failed to see that it was a link. Yes, I recognize that sensor (contactor) instantly. It’s commonly used on alarm systems (for garages), too. And, wherever I’ve seen them, I’ve also seen cases where the door shifts slightly in its tracks (some looseness is by design), and that’s enough to keep the magnet too far away from the sensor to register when closed. So verify, if you haven’t already, that the circuit through the sensor is closed when the door magnet is next to it.

But my first guess would be induced current.
Try using only twisted-pair wires to the contactor. They won’t absorb nearly as much induced current as a plain flat pair does. But if lightning ever hits nearby, don’t be surprised if the entire ESP gets fried. 20 feet makes a handy antenna for an EM pulse of that size (ask me how I know :wink:

You could also try limiting it with an inline 1-5K resistor. It only has to be below about 1/3 the resistance of the GPIO’s pullup, and might help protect the GPIO.
Alternatively, run your own voltage (e.g. from the 5V supply) through the contactor and make your own pullup/pulldown network of resistors, and don’t use internal pullup on the GPIO, so you can choose larger resistance values, which can also help block routine induced voltages.

The magnets seem to be working fine on open/close, which I verified with my continuity tester. The circuit is currently using some old speaker wire that I had lying around. I have some cat 6 here too. I might try that. I’ll also explore adding some resistors. Thanks for the input.

Good luck, and let us know!

1 Like

Any thoughts on this as a possible solution? Trying to use what I already have available.

Feed the door sensor/contactor with 5V from the power supply and a 10k resistor going into a 74AHCT125 to step down to 3.3v before going into the ESP32 GPIO.

That’d probably work fine, but would still be susceptible to lightning pulses, etc. and it adds another potential failure point.
It would probably suffice to use two resistors, thusly:
5V --> 220K --> to sensor and GPIO --> 330K --> Gnd
(other end of sensor also to Gnd.)
This creates a voltage divider so the GPIO can never experience more than ~3.3v, and is easier to build. Just be sure to configure the GPIO to NOT have internal pullup, else these large-value resistances might not be able to overcome it and change the state of the pin.
Oh, and definitely go with one of the pairs (e.g. Blue and White/Blue) in the CAT6 for the run to the sensor, to supress induced currents.

1 Like