Wiring up a switch or button to an ESP8266 or ESP32 is one of the most basic things you can do. A switch can control many things, including other devices connected to the ESPHome node, such as an LED strip or a relay.
Or you can pass on the status of the switch or button to Home Assistant and have it control any of the devices you have integrated. You could, for example, build a master light switch using several buttons to control every connected lightbulb in your smart home.
Being able to properly configure a physical switch or button in ESPHome is one of the fundamental things you should be able to do when planning projects. This guide will show you how to do it right. My goal is that any ESPHome beginner will be able to wire up a switch or button and configure it using YAML.
Table of Contents
- Types of switches and buttons
- The problem with toggle switches
- Wiring up a switch to an ESP8266 or ESP32
Types of switches and buttons
Switches come in many different shapes and forms. There are tactile or momentary switches, which are push buttons that are only engaged while they are being depressed. As soon as you release a momentary switch, the circuit is open. Toggle switches on the other hand stay in either the on or off position. They are usually operated by moving a lever to open or close an electrical circuit.
The problem with toggle switches
I really like toggle switches, but unfortunately, they aren’t very well suited to be used with ESPHome and Home Assistant. It isn’t an issue if the physical toggle switch is the only element controlling whatever device might be hooked up to the ESP8266 or ESP32.
But as soon as you pass things on to Home Assistant and also want to control your device from the dashboard, things can get out of sync. By that, I mean that you might have set the software switch to on while the hardware switch is in the off position. If you wanted to use the physical toggle switch to turn the device on again, you would first have to switch it to off and then to on again. For that reason, I advise against using toggle switches on ESPHome projects, even if they are fun to play around with.
Wiring up a switch to an ESP8266 or ESP32
The wiring of a switch is rather simple. All you have to do is to connect one end (also known as terminal) of the switch to the ground on the ESP8266 or ESP32 board (marked with a G on the board) and the other end to one of the GPIO pins. The goal is that the pin to which the switch is connected reads LOW when the switch is pressed and HIGH whenever it isn’t being pressed.
With the button wired up, we can create a GPIO binary sensor in our configuration using the code below. In this example, the device class is set to be a window. You can pick from any of the supported device classes in Home Assistant:
binary_sensor: - platform: gpio pin: D2 name: "Living Room Window" device_class: window
Configuring the internal pull-up resistor in ESPHome
There is one issue with this setup, though. If we read the input on the pin the switch is connected to and press the switch, the pin will read LOW. However, once we release the switch, there is no guarantee that the pin will read HIGH. This can either be solved by using a physical pull-up resistor. A pull-up resistor (or pull-down resistor, they also exist) is a resistor used to ensure a known state for a signal, in this case, HIGH.
Or you can choose the option for solving this issue. ESP8266 and ESP32 boards have built-in pull-up resistors, which can be enabled in the ESPHome configuration. All that needs to be added is one line of YAML:
binary_sensor: - platform: gpio pin: number: D2 mode: INPUT_PULLUP name: "Living Room Window" device_class: window
Inverting the switch in ESPHome
With the setup above, ESPHome will report the switch to be off when the switch is pressed and on whenever it isn’t pressed. If you wish to have the options inverted, you can do so by adding a further line to your code:
binary_sensor: - platform: gpio pin: number: D2 mode: INPUT_PULLUP inverted: True name: "Living Room Window" device_class: window
Debouncing in ESPHome
Whenever you release a mechanical switch, such as the one used in our current hypothetical scenario, it will not immediately switch from LOW to HIGH, as you might expect. It will instead oscillate a bit before switching. Because of this, it ESPHome can sometimes read the wrong values (such as a very rapid switching from one value to the other before it finally switches). The oscillation happens in the order of microseconds, and thus is easy for us to filter out with a few lines of code. In electronics, this is called debouncing.
binary_sensor: - platform: gpio pin: number: D2 mode: INPUT_PULLUP inverted: True name: "Living Room Window" device_class: window filters: - delayed_on: 10ms
Using this filter will only make the signal go high if the button has stayed high for more than 10ms, which should be more than enough to filter out the oscillation.