I have an ESP32 that drives a controller by active-low, it has a npn transistor, and two external pull resistors to function as both input and output if needed, since it can be externally driven down by a few physical buttons.
Now the question is, how can I set up my ESPHOME config to make the GPIO pins act as both Input as output, or sensing whether it’s driven down, and driving it down via the esp32?
The ESP32 architecture supports this use case, but as far as I am aware nothing supports it on the ESPHome platform.
Never tried anything like this but give it a try.
Set output (switch) as INPUT_OUTPUT_OPEN_DRAIN
Set both input (binary sensor) and output for allow_other_uses: true
Use external pullup.
Not quite the same thing as you are after but I have my VELUX blinds controlled in a similar method using the remote. It uses two GPIO’s one to control and one to sense. Details can be found here including code and Kicad files. Something you may be able to adapt if you have enough GPIO’s.
I’m not the author of this.
I solved it with this post: Open drain output and binary sensor at the same pin - #6 by laschrocket
I had issues at boot with sensors being on so used the initial lambda to on_boot as well. Seems to work so far, no burnt out components yet.
Also added open drain, just in case someone gets the brilliant idea of pushing the button when it happens to be on.
#....
esphome:
name: name
friendly_name: friendly_name
on_boot:
- priority: -100
then:
- lambda: |-
id(in_pin_18)->pin_mode(gpio::FLAG_INPUT);
id(sensor_up)->setup();
#....
binary_sensor:
- platform: gpio
name: "Up"
id: sensor_up
pin:
id: in_pin_18
number: 18
allow_other_uses: true
mode: INPUT
inverted: true
output:
- platform: gpio
id: button_up
pin:
id: out_pin_18
number: 18
allow_other_uses: true
inverted: true
button:
# Recall Presets
- platform: template
id: go_up_now
name: "go up"
icon: "mdi:numeric-1-box"
on_press:
- lambda: |-
id(out_pin_18)->pin_mode(gpio::FLAG_OUTPUT | gpio::FLAG_OPEN_DRAIN);
id(button_up)->setup();
- output.turn_on: button_up
- delay: 4s
- output.turn_off: button_up
- delay: 10ms
- lambda: |-
id(in_pin_18)->pin_mode(gpio::FLAG_INPUT);
id(sensor_up)->setup();