GPIO

Overview

Some stuff about using GPIO pins

As GND and 3v3

You can power sensors and other low-draw components on GPIO pins alone. On the ESP32 the GPIO pins can usually supply up to around or so, but the "real" 3v3 pin can supply more. It's really just doable for some low-power sensors.

As GND

To configure a pin as GND, you just have to define it as an output pin that has not been turned on:

output:
  - platform: gpio
    id: fake_gnd
    pin:
      number: ${gpio}
      mode:
        pulldown: true
        output: true

Somewhat confusingly, the pin must be defined as output.

Configuring the pin with pulldown activates the internal pull-down resistor on the ESP board. It is a from the GPIO pin to (real) GND.

As 3v3

There are several ways to configure a GPIO pin as a source. The simplest way is to configure the pin as inverted:

output:
  - platform: gpio
    id: supply_3v3
    pin:
      number: ${gpio}
      inverted: true
      mode:
        # Optionally set the maximum amount of current (esp-idf only)
        drive_strength: 40mA
        pullup: true
        output: true

Enabaling pullup activates the internal pull-up resistor on ESP32 boards, which is a resistor from the GPIO to 3v3.

Using strapping pins

If you are using a strapping pin that changes the boot mode by being pulled HIGH, and you will need to define a on_shutdown automation that turns the pin on.

Since the pin is inverted, you'll need to call turn_on() to turn it off.

Note that if the ESP looses power, there is no guarantee that the pin will be in the correct state on boot. Thus it is safer to configure the pin to be turned on during or after booting, so that it is programmed to be LOW when the ESP32 boots.

If you configure the output without inverted it will be LOW on boot, needing an on_boot automation to turn_on and pull it up to HIGH.

output:
  - platform: gpio
    id: supply_3v3
    pin:
      number: ${gpio}
      mode:
        pullup: true
        output: true

esphome:
  on_boot:
    priority: 90
    #  800: hardware init, vital components
    #  600: most sensors are ready
    #  250: wifi is initialized
    #  200: network connections and the esphome tcp api are set up
    # -100: everything is initialized
    then:
      - output.turn_on: supply

Another way is to just use the pin in an gpio switch:

switch:
  - platform: gpio
    id: supply_3v3
    name: "${hostname} GPIO 3v3"
    pin:
      number: ${gpio}
      mode:
        pullup: true
        output: true

Unless internal is enabled, this will show up and work like a regular switch entity in Home Assistant, so it can be turned on/off at will.

Both of these methods are useful for strapping pins as they avoid setting the state of the pin in flash and do it at runtime instead.

References

6

Pull-up and Pull-down resistors - EEPower: primer on pull-up/pull-down resistors and how they are used on MCUs.

7

Powering sensors - Alex Mekkering: Using GPIO pins as 3V3 or GND.