ESP32 - Button

The button is a basic component and widely used in many ESP32 projects. It is simple to use. However, it may make the beginners confuse, due to mechanical, physical issues and ways to use it as well. This tutorial makes it easy for the beginners

※ NOTE THAT:

There are two common troubles that beginners usually get into:

  1. Floating input problem:
  • Symptom: the reading value from the input pin is not matched with the button's pressing state.
    • Cause: input pin is NOT used pull-up or pull-down resistor.
    • Solution: Use pull-up or pull-down resistor. It will be described in this tutorial
      1. Chattering phenomenon

    It should be considered in only some application that needs to detect exactly number of the pressing.

    • Symptom: Button is pressed one, but ESP32 code detects several times.
    • Cause: Due to mechanical and physical issues, the state of the button (or switch) is quickly toggled between LOW and HIGH several times
    • Solution: Debounce. It will be described in ESP32 - Button - Debounce tutorial.

    Hardware Required

    1×ESP-WROOM-32 Dev Module
    1×Micro USB Cable
    1×Button
    1×Breadboard
    2×Jumper Wires
    Please note: These are affiliate links. If you buy the components through these links, We may get a commission at no extra cost to you. We appreciate it.

    About Button

    Pinout

    Button usually have four pins.

    Button Pinout

    However, these pins are internally connected in pairs. Therefore, we only need to use two of the four pins, which are NOT internally connected.

    There are four ways (actually two ways because of symmetry) to connect to button (see image)

    How To Use Button
    We can use only two pins of a button, why does it have four pins?

    ⇒ To make it stand firmly in PCB (board) to resist the pressing force.

    How It Works

    • When the button is NOT pressed, pin A is NOT connected to pin B
    • When the button is pressed, pin A is connected to pin B
    • How Button Works

    ESP32 - Button

    One button's pin is connected to VCC or GND. The other pin is connected to an ESP32 pin.

    By reading the state of ESP32's pin (configured as input pin), we can detect the button is pressed or NOT.

    Button State and Pressing State

    The relation between the button state and the pressing state depends on how we connect the button with ESP32 and the setting of the ESP32's pin.

    There are two ways to use a button with ESP32:

    1. One button's pin is connected to VCC, the other is connected to an ESP32's pin with a pull-down resistor
      • If the button is pressed, ESP32's pin state is HIGH. If otherwise, ESP32's pin state is LOW
      • We MUST use an external resistor.
    2. One button's pin is connected to GND, the other is connected to an ESP32's pin with a pull-up resistor
      • If the button is pressed, ESP32's pin state is LOW. If otherwise, ESP32's pin state is HIGH
      • We can use either an internal or external resistor. The internal resistor is built inside ESP32, we just need to set via ESP32 code.

    ※ NOTE THAT:

    If we do NOT use neither pull-down nor pull-up resistor, the state of the input pin is “floating” when the button is NOT pressed. It means the state can be HIGH or LOW (unstable, unfixed), resulting in the wrong detection.

    • The worst practice: initializes the ESP32 pin as an input (by using pinMode(BUTTON_PIN, INPUT)) and does NOT use any external pull-down/pull-up resistor.
    • The best practice: initializes the ESP32 pin as an internal pull-up input (by using pinMode(BUTTON_PIN, INPUT_PULLUP)). It does NOT need to use any external pull-down/pull-up resistor.

    To make it easy for beginners, this tutorial uses the simplest method: initializes the ESP32 pin as an internal pull-up input without using the external resistor. The beginners do NOT need to care about how to wire the pull-up/pull-down resistor. The beginners just need to use the ESP32 code.

    Wiring Diagram

    ESP32 Button Wiring Diagram

    Image is developed using Fritzing. Click to enlarge image

    How To Program For Button

    • Initializes the ESP32 pin as an internal pull-up input by using pinMode() function. For example, pin GIOP21:
    pinMode(21, INPUT_PULLUP);
    • Reads the state of the ESP32 pin by using digitalRead() function.
    int buttonState = digitalRead(BUTTON_PIN);

    ※ NOTE THAT:

    There are two wide-used use cases:

    • The first: If the input state is HIGH, do something. If the input state is LOW, do another thing in reverse.
    • The second: If the input state is changed from LOW to HIGH (or HIGH to LOW), do something.

    Depending on the application, we choose one of them. For example, in case of using a button to control an LED:

    • If we want the LED to be ON when the button is pressed and OFF when the button is NOT pressed, we SHOULD use the first use case.
    • If we want the LED to be toggle between ON and OFF each time we press the button, we SHOULD use the second use case.
    • How to detect the state change from LOW to HIGH
    // constants won't change. They're used here to set pin numbers: const int BUTTON_PIN = 21; // GIOP21 pin connected to button // Variables will change: int lastState = HIGH; // the previous state from the input pin int currentState; // the current reading from the input pin void setup() { // initialize serial communication at 9600 bits per second: Serial.begin(9600); // initialize the pushbutton pin as an pull-up input // the pull-up input pin will be HIGH when the switch is open and LOW when the switch is closed. pinMode(BUTTON_PIN, INPUT_PULLUP); } void loop() { // read the state of the switch/button: currentState = digitalRead(BUTTON_PIN); if(lastState == LOW && currentState == HIGH) Serial.println("The state changed from LOW to HIGH"); // save the the last state lastState = currentState; }

    ESP32 Code

    Quick Steps

    • If this is the first time you use ESP32, see how to setup environment for ESP32 on Arduino IDE
    • Connect the ESP32 board to your PC via a micro USB cable
    • Open Arduino IDE, select the right ESP32 board and COM port
    • Copy the below code and open with Arduino IDE
    // constants won't change. They're used here to set pin numbers: const int BUTTON_PIN = 21; // GIOP21 pin connected to button void setup() { // initialize serial communication at 9600 bits per second: Serial.begin(9600); // initialize the pushbutton pin as an pull-up input // the pull-up input pin will be HIGH when the switch is open and LOW when the switch is closed. pinMode(BUTTON_PIN, INPUT_PULLUP); } void loop() { // read the state of the switch/button: int buttonState = digitalRead(BUTTON_PIN); // print out the button's state Serial.println(buttonState); }
    • Click Upload button on Arduino IDE to compile and upload code to ESP32 board
    • How to upload ESP32 code on Arduino IDE
    • Open Serial Monitor on Arduino IDE
    • How to open serial monitor on Arduino IDE
    • Press and release the button several time
    • See the result on Serial Monitor. It looks like the below::
    • COM6
      Send
      1 1 1 0 0 0 0 0 0 1 1 1
      Autoscroll Show timestamp
      Clear output
      9600 baud  
      Newline  

    1 is HIGH, 0 is LOW.

    Code Explanation

    Read the line-by-line explanation in comment lines of code!

    Modifying ESP32 Code

    Let's modify the code to detect the press and release events

    Quick Steps

    /* * Created by esp32io.com * * This example code is in the public domain * * Tutorial page: https://esp32io.com/tutorials/esp32-button */ // constants won't change. They're used here to set pin numbers: const int BUTTON_PIN = 21; // GIOP21 pin connected to button // Variables will change: int lastState = LOW; // the previous state from the input pin int currentState; // the current reading from the input pin void setup() { // initialize serial communication at 9600 bits per second: Serial.begin(9600); // initialize the pushbutton pin as an pull-up input // the pull-up input pin will be HIGH when the switch is open and LOW when the switch is closed. pinMode(BUTTON_PIN, INPUT_PULLUP); } void loop() { // read the state of the switch/button: currentState = digitalRead(BUTTON_PIN); if(lastState == HIGH && currentState == LOW) Serial.println("The button is pressed"); else if(lastState == LOW && currentState == HIGH) Serial.println("The button is released"); // save the the last state lastState = currentState; }
    • Click Upload button on Arduino IDE to compile and upload code to ESP32 board
    • Arduino IDE Upload Code
    • Open Serial Monitor on Arduino IDE
    • How to open serial monitor on Arduino IDE
    • Press the button and then release
    • See the result on Serial Monitor. It looks like the below:
    • COM6
      Send
      The button is pressed The button is released
      Autoscroll Show timestamp
      Clear output
      9600 baud  
      Newline  

    ※ NOTE THAT:

    Even you pressed and released the button only once, the output in Serial Monitor may show several pressed and release events. This is the normal behavior of the button. This behavior is called the “chattering phenomenon”. You can learn more in ESP32 - Button Debounce tutorial.

    ※ NOTE THAT:

    To make it much easier for beginners, especially when using multiple buttons, we created a library, called ezButton. You can learn about ezButton library here.

    Video Tutorial

    We are considering to make the video tutorials. If you think the video tutorials are essential, please subscribe to our YouTube channel to give us motivation for making the videos.

    Challenge Yourself

    • Turn on LED when button is pressed and turn off LED when button is NOT pressed.
    • Toggle LED between ON and OFF each time the button is pressed.

    Additional Knowledge

    When should and should NOT we use a pull-down/pull-up resistor for an input pin?
    • If the sensor has either closed (connected to VCC or GND) or open (NOT connected to anything) states, you need a pull-up or pull-down resistor to make these states become two states: LOW and HIGH. For example, push-button, switch, magnetic contact switch (door sensor)...
    • If the sensor has two defined voltage levels (LOW and HIGH), you do NOT need a pull-up or pull-down resistor. For example, motion sensor, touch sensor ...

    Button on Commercial Products

    Most electronic products have a reset button. Additionally, the button also keeps other functionalities in many products.

    Function References

    ※ NOTE THAT:

    Note that this tutorial is incomplete. We will post on our Facebook Page when the tutorial is complete. Like it to get updated.

    ※ NOTICES

    • We are AVAILABLE for HIRE. See how to hire us to do your project
    • If this tutorial is useful for you, please support us to make more tutorials.
    • We spent a lot of time and effort to create the content for this tutorial, please respect our work! Please do not copy the content to share on other websites. Howerver, please feel free to share the link of this tutorial anywhere