Arduino Nano ESP32 - Button

The button is a basic component and widely used in many Arduino Nano ESP32 projects. It is not simple as it looks like (because of mechanical, physical characteristics). Beginners may have a lot of troubles with it. This tutorial makes it easy for the beginners. Let's start!

※ NOTE THAT:

Before presenting about the button, We would like to notice that there are two common mistakes that newbies usually meet:

  1. The floating input problem:
    • Symptom: When connecting a button to Arduino Nano ESP32 input pin, the state of the input pin is random and not matched with the button's pressing state.
    • Cause: The button pin is NOT used a pull-down resistor or a pull-up resistor.
    • Solution: ⇒ Use a pull-down resistor or a pull-up resistor on the input pin. The detail will be described later in this tutorial.
  • The chattering phenomenon
    • Symptom: The code on Arduino Nano ESP32 reads the state of the button and identifies the pressing event by detecting the state change (HIGH to LOW, or LOW to HIGH). When the button is actually pressed only one time, Arduino Nano ESP32 code detects multiple presses rather than once.
    • Cause: Due to mechanical and physical characteristics, when you do a single press on a button, the state of the input pin is quickly toggled between LOW and HIGH several times rather than once
    • Solution: ⇒ Debounce. The detail will be described in Arduino Nano ESP32 - Button - Debounce tutorial.

    The chattering phenomenon causes the malfunction in only some kinds of application that needs to detect exactly number of the pressing. In some kind of application, it is harmless.

    Hardware Preparation

    1×Arduino Nano ESP32
    1×USB Cable Type-C
    1×Push Button
    1×(Optional) Panel-mount Push Button
    1×Breadboard
    1×Jumper Wires
    1×(Optional) DC Power Jack
    1×(Recommended) Screw Terminal Adapter for Arduino Nano

    Or you can buy the following sensor kit:

    1×DIYables Sensor Kit 30 types, 69 units
    Disclosure: Some of the links provided in this section are Amazon affiliate links. We may receive a commission for any purchases made through these links at no additional cost to you. We appreciate your support.

    Overview of Button

    The push button, also referred to as a pushbutton, tactile button, or momentary switch, is a type of switch that closes when pressed and held, and opens when released. Various types of push buttons exist, broadly categorized into two groups:

    • PCB-mount push buttons (suitable for breadboard mounting)
    • Panel-mount push buttons
    Arduino Nano ESP32 Push button

    Button Pinout

    A PCB-mount button usually has four pins that are internally connected in pairs.

    Button Pinout

    We only need to use two of the four pins, which are NOT in the same connected pair. Accordingly, There are four ways to do wiring with the button (see bimage below)

    How To Use Button

    Actually, because of symmetry, these four ways becomes two ways. The rest of this tutorial will use two pins: Pin A and Pin B that are not connected together.

    Why does the button has four pins while we only need two pins?

    ⇒ The button receives the force from users. To make it stand stably and firmly in PCB (board), It has four pins to resist the pressing force.

    A panel-mount button usually has two pins.

    two-pin push button Pinout
    image source: diyables.io

    How Button Works

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

    Arduino Nano ESP32 - Button

    One button's pin is connected to a digital input pin of Arduino Nano ESP32. The other pin is connected to VCC or GND. In Arduino Nano ESP32 code, by reading the state of the input pin, we can infer the button is pressed or NOT.

    Input State and Pressing State

    The relation between the state of the input pin and the button's pressing state depends on how we connect the button with Arduino Nano 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 a digital input pin of ESP32, the other pin is connected to VCC:
      • A pull-down resistor MUST be used
      • If the button is pressed, the state of ESP32's pin is HIGH. Otherwise, the state of ESP32's pin is LOW
  • One button's pin is connected to a digital input pin of ESP32, the other pin is connected to GND:
    • A pull-up resistor MUST be used
    • If the button is pressed, the state of ESP32's pin is LOW. Otherwise, the state of ESP32's pin is HIGH

    ※ NOTE THAT:

    If neither a pull-down resistor nor a pull-up resistor is used, the state of the input pin is random between HIGH or LOW (unstable, unfixed) when the button is NOT pressed. This is called The “floating input problem”. This results in the malfunction.

    To make it simple for newbies, this tutorial highly recommens newbies using an internal pull-up resistor for Arduino Nano ESP32 pin. No external resistor is required. This saves the hardware, simplifies the wiring diagram.

    Wiring Diagram between Button and Arduino Nano ESP32

    • Wiring Diagram between Arduino Nano ESP32 and PCB-mount button
    The wiring diagram between Arduino Nano ESP32 and Button

    This image is created using Fritzing. Click to enlarge image

    • Wiring Diagram between Arduino Nano ESP32 and panel-mount button
    The wiring diagram between Arduino Nano ESP32 and two-pin push button

    This image is created using Fritzing. Click to enlarge image

    How To Program Button

    • Initializes the Arduino Nano ESP32 pin as an internal pull-up input by using pinMode() function. For example, pin D2:
    pinMode(D2, INPUT_PULLUP); // config D2 as input pin and enable the internal pull-up resistor
    • Reads the state of the input pin by using digitalRead() function.
    int button_state = digitalRead(BUTTON_PIN);

    ※ NOTE THAT:

    There are two wide-used use cases:

    • The first use case: If the input state is HIGH, do something. If the input state is LOW, do another thing.
    • The second use case: If the input state is changed from LOW to HIGH, do something. If the input state is changed from HIGH to LOW, do another thing.

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

    • If we want to turn the LED ON when the button is pressed and turn it OFF when the button is NOT pressed, we SHOULD use the first case.
    • If we want to toggle the LED between ON and OFF each time the button is pressed, we SHOULD use the second case.

    The below example code show how to detect the state change from LOW to HIGH

    #define BUTTON_PIN D2 // D2 pin connected to button int prev_state = HIGH; // the previous state from the input pin int button_state; // the current reading from the input pin void setup() { Serial.begin(9600); // initialize the pushbutton pin as an pull-up input pinMode(BUTTON_PIN, INPUT_PULLUP); } void loop() { // read the state of the switch/button: button_state = digitalRead(BUTTON_PIN); if(prev_state == LOW && button_state == HIGH) Serial.println("The state changed from LOW to HIGH"); // save the last state prev_state = button_state; }

    Arduino Nano ESP32 Code

    Detailed Instructions

    To get started with Arduino Nano ESP32, follow these steps:

    • If you are new to Arduino Nano ESP32, refer to the tutorial on how to set up the environment for Arduino Nano ESP32 in the Arduino IDE.
    • Wire the components according to the provided diagram.
    • Connect the Arduino Nano ESP32 board to your computer using a USB cable.
    • Launch the Arduino IDE on your computer.
    • Select the Arduino Nano ESP32) board and its corresponding COM port.* Copy the below code and paste it to Arduino IDE.
    #define BUTTON_PIN D2 // Arduino Nano ESP32 pin D2 pin connected to button void setup() { // Initialize the Serial to communicate with the Serial Monitor. Serial.begin(9600); // initialize the button pin as an pull-up input (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 button_state = digitalRead(BUTTON_PIN); // print out the button's state Serial.println(button_state); }
    • Compile and upload code to Arduino Nano ESP32 board by clicking Upload button on Arduino IDE
    How to upload Arduino Nano 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
    • Check out the result on the 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.

    Line-by-line Code Explanation

    The above Arduino Nano ESP32 code contains line-by-line explanation. Please read the comments in the code!

    Modifying Arduino Nano ESP32 Code

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

    Detailed Instructions

    /* * This Arduino Nano ESP32 code was developed by newbiely.com * * This Arduino Nano ESP32 code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/arduino-nano-esp32/arduino-nano-esp32-button */ #define BUTTON_PIN D2 // Arduino Nano ESP32 pin D2 pin connected to button int prev_state = LOW; // The previous state from the input pin int button_state; // The current reading from the input pin void setup() { // Initialize the Serial to communicate with the Serial Monitor. Serial.begin(9600); // initialize the button pin as an pull-up input (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: button_state = digitalRead(BUTTON_PIN); if (prev_state == HIGH && button_state == LOW) Serial.println("The button is pressed"); else if (prev_state == LOW && button_state == HIGH) Serial.println("The button is released"); // save the the last state prev_state = button_state; }
    • Compile and upload code to Arduino Nano ESP32 board by clicking Upload button on Arduino IDE
    • Open Serial Monitor on Arduino IDE
    • Press the button and then release
    • Check out the result on the 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:

    • The Serial Monitor may print several pressed and released events even though you did only one press and release. This is a normal behavior of the button. This behavior is called the “chattering phenomenon”. In some application, we need a method to eliminate it. You can learn more in Arduino Nano ESP32 - Button Debounce tutorial.
    • To make it simple for beginners, especially when using multiple buttons, we created a library, called ezButton. You can learn about ezButton library here.

    Video Tutorial

    Additional Knowledge

    When should and should NOT use a pull-down/pull-up resistor?
    • SHOULD: If the sensor has two states: closed and open, it 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)...
    • SHOULD NOT: If the sensor outputs two voltage levels (LOW and HIGH), it does NOT need a pull-up or pull-down resistor. For example, motion sensor, touch sensor ...

    Language References