ESP8266 - Button

This tutorial instructs you how to use ESP8266 with button. In detail, we will learn:

The button is known by other names, such as pushbutton, tactile button or momentary switch. It is a common component used in many ESP8266 projects and is easy to use. However, it can be confusing for beginners due to its mechanical, physical aspects and the ways it can be used. This tutorial makes it easier for those just starting out.

Hardware Preparation

1×ESP8266 NodeMCU
1×Micro USB Cable
1×Push Button
1×(Optional) Panel-mount Push Button
1×Breadboard
1×Jumper Wires
1×(Optional) 5V Power Adapter for ESP8266
1×(Optional) ESP8266 Screw Terminal Adapter

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

When working with a button, beginners commonly encounter two issues:

1. Floating input problem:.

  • Symptom: The value read from the input pin does not correspond with the state of the button press.
  • Cause: A pull-up or pull-down resistor is not in use with the input pin.
  • Solution: Utilize a pull-up or pull-down resistor as instructed in this tutorial.

2. Chattering phenomenon:.

  • Symptom: Despite being pressed once, the button is causing the ESP8266 code to detect multiple presses.
  • Cause: The state of the button (or switch) is rapidly oscillating between LOW and HIGH due to mechanical and physical issues.
  • Solution: The ESP8266 - Button - Debounce tutorial will explain how to utilize debounce to address this problem.

This is a factor that should only be taken into account for applications that require precise press detection.

※ NOTE THAT:

Do not confuse the button with the following:

The Button Pinout

There are various types of push buttons, which can be broadly categorized into two groups:

  • PCB-mount push button (suitable for mounting on a breadboard)
  • Panel-mount push button
Push button

A PCB-mount button typically have four pins.

Button pinout

Nevertheless, these pins are connnected in pair internally. Thus, we only have to utilize two of the four pins, which are not connnected within.

There are four methods of connecting to the button, two of which are symmetrical (as seen in the image).

How To Use Button

? Why does a button have four pins when we only use two of them?

⇒ To ensure that it is firmly mounted on the PCB (printed circuit board) and can withstand the pressure.

A panel-mount button usually have two pins.

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

How It Works

  • When the button is not pressed, pin A is not connected to pin B.
  • However, when the button is pressed, pin A is connected to pin B.
How Button Works

ESP8266 - Button

One button's pin is connected to either VCC or GND. The other pin is connected to a pin on the ESP8266. By checking the state of an ESP8266 pin configured as an input, we can determine whether a button has been pressed or not.

Button State and Pressing State

The connection between the button and ESP8266, as well as the configuration of the ESP8266's pin, will determine the relationship between the button state and the pressing state.

There are two ways to use a button with ESP8266:

  1. One button's pin is connected to VCC, the other is connected to an ESP8266's pin with a pull-down resistor
    • When the button is pressed, the ESP8266's pin state will be HIGH. If not, the pin state will be LOW
    • We can either use an internal or external resistor. The internal resistor is already built inside ESP8266, and can be set via ESP8266 code.
  • One button's pin is connected to GND, the other is connected to an ESP8266's pin with a pull-up resistor
    • When the button is pressed, the ESP8266's pin state will be LOW. If not, the pin state will be HIGH
    • We can either use an internal or external resistor. The internal resistor is already built inside ESP8266, and can be set via ESP8266 code.

    ※ NOTE THAT:

    If we do not follow the best practice, the state of the input pin will be “floating” when the button is NOT pressed. This means the state can be HIGH or LOW (unstable, unfixed), resulting in wrong detection.

    • The worst practice: initializes the ESP8266 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 ESP8266 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.

    For the sake of simplicity, this tutorial utilizes the most basic approach: initializing the ESP8266 pin as an internal pull-up input without the use of an external resistor. Newcomers do not have to worry about connecting the pull-up/pull-down resistor. All they need to do is write the ESP8266 code.

    Wiring Diagram

    • Wiring Diagram between ESP8266 and PCB-mount button
    The wiring diagram between ESP8266 NodeMCU and Button

    This image is created using Fritzing. Click to enlarge image

    See more in ESP8266's pinout and how to supply power to the ESP8266 and other components.

    • Wiring Diagram between ESP8266 and panel-mount button
    The wiring diagram between ESP8266 NodeMCU and two-pin push button

    This image is created using Fritzing. Click to enlarge image

    How To Program For Button

    • Using the pinMode() function, set the ESP8266 pin to an internal pull-up input. For example, pin D7:
    pinMode(D7, INPUT_PULLUP);
    • Access the state of the ESP8266 pin by using the digitalRead() function.
    int button_state = digitalRead(BUTTON_PIN);

    ※ NOTE THAT:

    Two common use cases are available:

    • The first is to take action if the input state is HIGH, and to do something in reverse if the input state is LOW.
    • The second is to take action when the input state changes from LOW to HIGH (or HIGH to LOW).

    We select one of them depending on the application. For example, if we want to use a button to control an LED:

    • If the intention is for the LED to be ON when the button is pressed and OFF when the button is NOT pressed, the first use case should be used.
    • If the goal is for the LED to toggle between ON and OFF each time the button is pressed, the second use case should be employed.

    How to detect the state change from LOW to HIGH

    const int BUTTON_PIN = D7; // The ESP8266 pin D7 connected to button int prev_button_state = HIGH; // 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 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: button_state = digitalRead(BUTTON_PIN); if(prev_button_state == LOW && button_state == HIGH) Serial.println("The state changed from LOW to HIGH"); // save the last state prev_button_state = button_state; }

    ESP8266 Code

    Detailed Instructions

    To get started with ESP8266 on Arduino IDE, follow these steps:

    • Check out the how to setup environment for ESP8266 on Arduino IDE tutorial if this is your first time using ESP8266.
    • Wire the components as shown in the diagram.
    • Connect the ESP8266 board to your computer using a USB cable.
    • Open Arduino IDE on your computer.
    • Choose the correct ESP8266 board, such as (e.g. NodeMCU 1.0 (ESP-12E Module)), and its respective COM port.
    • Attach the ESP8266 to your computer with a USB cable.
    • Launch the Arduino IDE, select the correct board and port.
    • Copy the code below and open it in the Arduino IDE.
    #define BUTTON_PIN D7 // The ESP8266 pin D7 connected to button void setup() { // Initialize the Serial to communicate with the Serial Monitor. Serial.begin(9600); // Configure the ESP8266 pin as a pull-up input: HIGH when the button is open, LOW when pressed. 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); }
    • Click the Upload button on the Arduino IDE to compile and upload the code to the ESP8266 board.
    How to upload code to ESP8266 NodeMCU using Arduino IDE
    • Open the Serial Monitor.
    • Press and release the button multiple times.
    • Check out the result in the Serial Monitor.
    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

    Check out the line-by-line explanation contained in the comments of the source code!

    Modifying ESP8266 Code

    Let's change the code so that it can detect when a press and release event occurs.

    Detailed Instructions

    • Wire the components as shown in the diagram.
    • Connect the ESP8266 board to your computer using a USB cable.
    • Open Arduino IDE on your computer.
    • Choose the correct ESP8266 board, such as (e.g. NodeMCU 1.0 (ESP-12E Module)), and its respective COM port.
    • Alter the code as follows:
    /* * This ESP8266 NodeMCU code was developed by newbiely.com * * This ESP8266 NodeMCU code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/esp8266/esp8266-button */ #define BUTTON_PIN D7 // The ESP8266 pin D7 connected to button int prev_button_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); // Configure the ESP8266 pin as a pull-up input: HIGH when the button is open, LOW when pressed. pinMode(BUTTON_PIN, INPUT_PULLUP); } void loop() { // read the state of the switch/button: button_state = digitalRead(BUTTON_PIN); if (prev_button_state == HIGH && button_state == LOW) Serial.println("The button is pressed"); else if (prev_button_state == LOW && button_state == HIGH) Serial.println("The button is released"); // save the the last state prev_button_state = button_state; }
    • Click the Upload button on the Arduino IDE to compile and upload the code to the ESP8266.
    Arduino IDE Upload Code
    • Open the Serial Monitor.
    • Press the button and hold it down.
    • Release the button and observe the result in the Serial Monitor.
    COM6
    Send
    The button is pressed The button is released
    Autoscroll Show timestamp
    Clear output
    9600 baud  
    Newline  

    ※ NOTE THAT:

    Even if you press and release the button just once, the output in the Serial Monitor may display multiple pressed and released events. This is the expected behavior of the button. This is known as the "chattering phenomenon". For more information, please refer to the ESP8266 - Button Debounce tutorial.

    ※ NOTE THAT:

    We have developed a library, called ezButton, to make it simpler for those just starting out, particularly when using multiple buttons. You can find out more about the ezButton library here.

    Video Tutorial

    Challenge Yourself

    • When the button is pressed, turn on the LED.
    • When the button is not pressed, turn off the LED.
    • Each time the button is pressed, switch the LED between ON and OFF.

    Additional Knowledge

    1. At what times should we NOT use a pull-down/pull-up resistor for an input pin? 2. When should we not utilize a pull-down/pull-up resistor for an input pin?
    • If the sensor has either closed or open states, a pull-up or pull-down resistor is required to make these states become LOW and HIGH. Examples of such sensors are push-button, switch, magnetic contact switch (door sensor).
    • On the other hand, if the sensor has two defined voltage levels (LOW and HIGH), a pull-up or pull-down resistor is not needed. Examples of such sensors are motion sensor and touch sensor.

    Function References