How to use a ESP8266/ ESP32 with physical buttons via ESPHome

How to use a ESP8266/ ESP32 with physical buttons via ESPHome

This project started in the quest to figure out if I could make an alternative to the IKEA Wireless Dimmer (E1743) with a ESP8266 or ESP32.

For my proof of concept, I thought I would try to build something that could switch four different buttons and it could either be a momentary / toggle or latching switch to achieve it.

One thing to note, I did have some trouble with latching switches becoming out of sync with the switch being on or off. As a result, I ended up going with momentary switches for this reason.

With most of these types of projects, I opted to use ESPHome, and utilise a binary_sensor for this project.

Parts

To do this project, the following parts are needed. I have sourced my parts from Jaycar, eBay and AliExpress, but you can get these from any shop or online.  

Part Cost Qty URL
ESP8266 $7.50 roughly 1 Where ever you source it, I have them on hand
PCB $4.95ea 1 https://www.jaycar.com.au/universal-pre-punched-experimenters-board-small/p/HP9550?pos=1&queryId=8cd84040f21ef1435b83488de55f3224&sort=relevance
2-Way PCB Mount Screw Terminal 5mm $1.35ea 5 https://www.jaycar.com.au/2-way-pcb-mount-screw-terminals-5mm-pitch/p/HM3172?pos=1&queryId=85b57945933ef7b9e4abf9a3e59c62c4&sort=relevance
Small Black Momentary Switch $3.95ea 4 https://www.jaycar.com.au/small-black-spst-n-o-momentary-action/p/SP0700?pos=1&queryId=659eadde5b5b56785c204a334351cba7&sort=relevance
Various Colours and length of cable $5 x Where ever you source it from. I had this on hand.

Wiring

With one side of the switches, we will be tieing this to ground. The other side will be connected to the various GPIO pins on the ESP8266 as shown below. I also added additional power input using the screw terminal connectors. Just connect to the 3v and Ground to do this.

In my prototype here as well I used Female Header Pins to allow me to remove the ESP8266 from the board. This allows me to swap out to different boards if I wish.

ESPhome

Inside ESPhome, create a new device, and fill in the various options for wifi etc. The ESP8266 is also very convenient in having the USB connection onboard easily allowing you to write firmware to it.

The ESPhome configuration I ended up using is found below:

esphome:
  name: water-buttons
  platform: ESP8266
  board: esp01_1m

wifi:
  ssid: !secret esphome_ssid
  password: !secret esphome_ssid_password
  manual_ip:
    static_ip: 192.168.xxx.xxx
    gateway: 192.168.xxx.xxx
    subnet: 255.255.255.0

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Water-Buttons"
    password: "Password"

captive_portal:

# Enable logging
logger:
  
# Enable Home Assistant API
api:
  password: !secret esphome_api_ota_password

ota:
  password: !secret esphome_api_ota_password
  
web_server:
  port: 80

binary_sensor:
   - platform: gpio
     pin:
       number: 4
       mode: INPUT_PULLUP
       inverted: True
     name: "WB1"
     filters:
       - delayed_on: 10ms  
   - platform: gpio
     pin:
       number: 13
       mode: INPUT_PULLUP
       inverted: True
     name: "WB2"
     filters:
       - delayed_on: 10ms
   - platform: gpio
     pin:
       number: 12
       mode: INPUT_PULLUP
       inverted: True
     name: "WB3"
     filters:
       - delayed_on: 10ms       
   - platform: gpio
     pin:
       number: 14
       mode: INPUT_PULLUP
       inverted: True
     name: "WB4"
     filters:
       - delayed_on: 10ms  
     

Each binary_sensor utilises a couple of different things.

mode: INPUT_PULLUP:  Is used to ensure that we can reliably read the high and low states. The good thing about ESP8266 or ESP32 boards are that they have built in pull-up resisters to help combat this problem. With the help of ESPHome we can program the board to turn this feature on with mode: INPUT_PULLUP.

inverted: True: When setting up the switches without this setting added the switches will present as ON or as known as normally open rather than off or as known as normally closed which is what we want them to operate as. Unless you have a requirement in your project to have the switch normally open, I would suggest setting invert.

filters: delayed_on: 10ms: When we use switches in circuits where digital/ analog circuitry is involved, we need to try to clean up the signal when the switch goes from LOW to HIGH. If we don't do something about this, it will oscillate for a while before switching. This is what you call debouncing. If you want to read up on it a bit more here's a link that talks about it more.

When this type of thing occurs ESPHome can read the wrong values and can cause some problems later down the track when you go to implement automation where you might poll the switches state.

To tackle this problem, we can use the inbuilt filter to keep the button HIGH for 10ms which should be enough time for it to then properly read LOW.

Lets see it in action!

What's next?

So not only can we just click the button once and have it do something, but we could also implement a double, triple click or hold to do another three things per button.

So my proof of concept to get the button up is functional now. My next task here will be to then implement it into my irrigation setup and have it in a waterproof box to trigger the individual irrigation zones via NodeRed and Home Assistant

I will be doing a V3 of Automated Watering to include more of the programming side of things in NodeRed and improvements and additions. So stay tuned for that!