This tutorial instructs you how to use the ESP8266 NodeMCU to read a button module, so your project can react when someone presses a key: ring a WiFi doorbell, start a timer, or step through the modes of a lamp. The module is a small board with three labeled pins, and it needs no extra parts on the breadboard. In detail, we will learn:
What the button module is, and why its OUT pin goes HIGH when you press it
How to connect the module to the NodeMCU, using 3V3 for power and D7 (GPIO13) for the signal
How to program the ESP8266 to print the raw level of the button again and again
How to program the ESP8266 to catch each press and each release, with a short delay() debounce
How to program the ESP8266 to do the same job without blocking, with the ezButton library
We suggest:
Utilizing the classic push button tutorial if you want to see how a bare 4-leg button and its resistor are wired.
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. Additionally, some of these links are for products from our own brand, DIYables .
Overview of Button Module
image source: diyables.io
In short, the button module is a push button with its resistor already on board. A tactile switch with a colored cap sits on a tiny PCB, together with a pull-down resistor. The switch is momentary: it closes only while your finger holds it, and it springs open as soon as you let go. DIYables ships the modules in packs of five, one cap in each color: red, yellow, green, blue and white. That makes it easy to give every key its own job, for example green for start and red for stop.
The pull-down resistor keeps the OUT pin at 0V while nobody touches the cap. When you press, the switch connects OUT straight to VCC. So the signal is simple to read: LOW means released, HIGH means pressed.
Like every mechanical switch, the metal contacts bounce for a few milliseconds when they meet or part. During that short time the ESP8266 can see several quick LOW/HIGH changes, so a single press may look like many. The second and third sketches below deal with this.
Button Module
Switch type
momentary tactile push button with cap
Colors in the pack
red, yellow, green, blue, white
Operating voltage
3.3V to 5V DC
On-board resistor
pull-down on the OUT line
Output when released
LOW (0V)
Output when pressed
HIGH (same voltage as VCC)
Connector
3-pin 2.54mm male header
The Button Module Pinout
The header pins are printed on the board in this order: VCC, OUT, GND.
VCC pin: must be connected to the 3V3 pin of the NodeMCU. Never use the VIN or 5V pin for this module (see the warning below).
OUT pin: must be connected to a NodeMCU digital input pin. This tutorial uses D7 (GPIO13).
GND pin: must be connected to a G (GND) pin of the NodeMCU (0V)
※ NOTE THAT:
When the button is pressed, the OUT pin carries the full VCC voltage. The ESP8266 is a 3.3V chip, and its GPIO pins are not made for 5V. If VCC is taken from VIN or 5V, every press sends 5V into D7, which can damage the pin over time. Always power the module from 3V3.
※ NOTE THAT:
The arrangement of pins on a module may differ from one manufacturer to another. It is essential to always refer to the labels printed on the module when using it. Take a close look!
Wiring Diagram
Three jumper wires are enough. The module takes 3.3V and ground from the NodeMCU, and it reports the button level on D7.
This image is created using Fritzing. Click to enlarge image
Do you prefer another input pin? D1, D2, D5 and D6 work just as well. Stay away from D3, D4 and D8. The ESP8266 checks the level of these pins at boot, and D8 must be LOW while D3 and D4 must be HIGH. A button pressed during power-up could stop the board from starting. If you change the pin, change BUTTON_MODULE_PIN in the code too.
How To Program For Button Module
The ESP8266 core for Arduino IDE has everything needed for the first two sketches. The third one adds the ezButton library.
The first step is to give a name to the NodeMCU pin that is wired to the OUT pin:
#define BUTTON_MODULE_PIN D7 // D7 = GPIO13
Then, set this pin as a plain input with the pinMode() function. Do not choose INPUT_PULLUP. The module already pulls OUT down, and an internal pull-up would work against it.
pinMode(BUTTON_MODULE_PIN, INPUT);
Finally, read the level with the digitalRead() function. HIGH means the cap is held down, LOW means it is free.
int level = digitalRead(BUTTON_MODULE_PIN);
ESP8266 NodeMCU Code for Button Module - Read the Raw State
This first sketch is a quick health check of the wiring. Five times per second, it reads D7 and prints the level, plus a short word that says what the level means.
/* * 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-module */#define BUTTON_MODULE_PIN D7 // ESP8266 pin D7 (GPIO13) connected to the OUT pin of the button modulevoidsetup() {Serial.begin(9600);// Plain INPUT: the module already has its own pull-down resistor.// Do not use INPUT_PULLUP here.pinMode(BUTTON_MODULE_PIN, INPUT);}voidloop() {int level = digitalRead(BUTTON_MODULE_PIN); // HIGH = pressed, LOW = releasedSerial.print("OUT pin level: ");Serial.print(level);if (level == HIGH)Serial.println(" (held down)");elseSerial.println(" (not touched)");delay(200); // slow down the printing a little}
Connect the module to the NodeMCU as listed in the wiring table. Double-check that VCC goes to 3V3.
Plug the ESP8266 NodeMCU into your computer with a USB cable.
Open Arduino IDE on your computer.
Select the board NodeMCU 1.0 (ESP-12E Module) and the COM port of your NodeMCU.
Paste the code above into a new sketch.
Click the Upload button and wait until the upload finishes.
Open the Serial Monitor at 9600 baud.
Leave the button alone for a moment, then hold it down for about a second, then let go.
The level switches from 0 to 1 while you hold the cap, and back to 0 when you release it:
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
Nodemcu 1.0 (ESP-12E Module)
Newbiely.ino
···
8Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'Nodemcu 1.0 (ESP-12E Module)' on 'COM15')
New Line
9600 baud
OUT pin level: 0 (not touched)
OUT pin level: 0 (not touched)
OUT pin level: 0 (not touched)
OUT pin level: 1 (held down)
OUT pin level: 1 (held down)
OUT pin level: 1 (held down)
OUT pin level: 1 (held down)
OUT pin level: 0 (not touched)
OUT pin level: 0 (not touched)
Ln 11, Col 1
Nodemcu 1.0 (ESP-12E Module) on COM15
2
If the level stays at 0 when you press, check the OUT wire. If it jumps between 0 and 1 with no press at all, check the GND wire.
ESP8266 NodeMCU Code for Button Module - Press and Release Events with delay()
Most projects do not need the level itself. They need to know the moment the user pushes the button, for example to toggle a relay or to send one message. This sketch remembers the last level. When a new reading is different, it waits 50 milliseconds for the bouncing to end, reads again, and reports the change only if it is still there.
/* * 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-module */#define BUTTON_MODULE_PIN D7 // ESP8266 pin D7 (GPIO13) connected to the OUT pin of the button module#define DEBOUNCE_WAIT 50 // milliseconds to wait for the contacts to settleint last_state = LOW; // the module idles LOW (its pull-down keeps OUT at 0V)voidsetup() {Serial.begin(9600);pinMode(BUTTON_MODULE_PIN, INPUT); // no INPUT_PULLUP: the module has a pull-down}voidloop() {int reading = digitalRead(BUTTON_MODULE_PIN);if (reading != last_state) { // something seems to have changeddelay(DEBOUNCE_WAIT); // wait until the bouncing is over (blocks the loop) reading = digitalRead(BUTTON_MODULE_PIN); // read again to confirmif (reading != last_state) { // the change is realif (reading == HIGH)Serial.println("The button is pressed");elseSerial.println("The button is released"); last_state = reading; // remember the new state } }}
Detailed Instructions
Do not change the wiring. OUT stays on D7.
Paste the code into a new sketch and click Upload.
Open the Serial Monitor (9600 baud).
Press the button three times, at any speed.
Each push gives exactly one pair of lines:
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
Nodemcu 1.0 (ESP-12E Module)
Newbiely.ino
···
8Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'Nodemcu 1.0 (ESP-12E Module)' on 'COM15')
New Line
9600 baud
The button is pressed
The button is released
The button is pressed
The button is released
The button is pressed
The button is released
Ln 11, Col 1
Nodemcu 1.0 (ESP-12E Module) on COM15
2
The trade-off is that delay() blocks the loop: for those 50 milliseconds the ESP8266 can do nothing else in your sketch. For a small test that is fine, but it adds up when the sketch also serves a web page or reads sensors.
ESP8266 NodeMCU Code for Button Module - Non-Blocking with ezButton
The ezButton library, written by ArduinoGetStarted.com, does the debounce by checking the time on each pass of loop(). Its loop() function never waits, so the rest of your code keeps running at full speed. The object is created with EXTERNAL_PULLDOWN, which tells the library that the module has its own pull-down resistor. With this option, HIGH counts as pressed. It needs ezButton version 1.0.6 or newer.
The sketch uses three functions after button.loop():
Button.isPressed() returns true once, right after a press.
Button.isReleased() returns true once, right after a release.
Button.getState() returns the debounced level (HIGH or LOW) at any time.
/* * 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-module */#include <ezButton.h>#define BUTTON_MODULE_PIN D7 // ESP8266 pin D7 (GPIO13) connected to the OUT pin of the button module// EXTERNAL_PULLDOWN tells ezButton that the module has its own pull-down resistor,// so HIGH means pressed and LOW means released (needs ezButton 1.0.6 or newer)ezButtonbutton(BUTTON_MODULE_PIN, EXTERNAL_PULLDOWN);int last_steady_state = -1; // used to print the steady state only when it changesvoidsetup() {Serial.begin(9600);button.setDebounceTime(50); // ignore bounces shorter than 50 milliseconds}voidloop() {button.loop(); // MUST be called first in loop(). It never blocks.if (button.isPressed())Serial.println("The button is pressed");if (button.isReleased())Serial.println("The button is released");int steady_state = button.getState(); // debounced level: HIGH = pressed, LOW = releasedif (steady_state != last_steady_state) {Serial.print("Steady state: ");Serial.println(steady_state == HIGH ? "PRESSED" : "RELEASED"); last_steady_state = steady_state; }// other work (WiFi, sensors, ...) can run here without being held up}
Detailed Instructions
Keep the same wiring.
In Arduino IDE, open the Libraries panel from the left sidebar.
Type "ezButton" in the search box and find the library by ArduinoGetStarted.com.
Click Install. If an older version is already installed, update it to 1.0.6 or newer.
Search for ezButton created by ArduinoGetStarted.com and click the Install button.
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
Nodemcu 1.0 (ESP-12E Module)
Library Manager
ezButton
Type:
All
Topic:
All
ezButtonby ArduinoGetStarted.com
Button library supports debounce, pressed/released events and the press counting. It is easy to use with multiple buttons. The library can be used for push-button, momentary switches, toggle switch, magnetic contact switch (door sensor)... It is designed for not only beginners but also experienced users.
More info
1.0.6
INSTALL
Newbiely.ino
···
1
voidsetup() {
Output
Serial Monitor
Ln 1, Col 1
Nodemcu 1.0 (ESP-12E Module) on COM15
1
Paste the code above into a new sketch and click Upload.
Open the Serial Monitor (9600 baud).
Give the button two quick taps, then one long press.
The event lines and the steady state both appear, with no doubles from bouncing:
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
Nodemcu 1.0 (ESP-12E Module)
Newbiely.ino
···
8Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'Nodemcu 1.0 (ESP-12E Module)' on 'COM15')
New Line
9600 baud
Steady state: RELEASED
The button is pressed
Steady state: PRESSED
The button is released
Steady state: RELEASED
The button is pressed
Steady state: PRESSED
The button is released
Steady state: RELEASED
The button is pressed
Steady state: PRESSED
The button is released
Steady state: RELEASED
Ln 11, Col 1
Nodemcu 1.0 (ESP-12E Module) on COM15
2
When you need more than one key, create one ezButton object per module, each on its own pin, and call loop() for every object.
Additional Knowledge
Button Module vs Bare Push Button on the ESP8266
Question
Button Module
Bare 4-Leg Push Button
Needs an external resistor?
No, a pull-down is on the board
Yes, or use INPUT_PULLUP
Pins easy to identify?
Yes, labeled VCC, OUT, GND
No, four legs in two connected pairs
Level when pressed
HIGH
LOW with INPUT_PULLUP (inverted logic)
pinMode() to use
INPUT
INPUT_PULLUP, or INPUT with your own resistor
Breadboard needed?
No, three jumper wires are enough
Usually yes
Bounces?
Yes, debounce in code
Yes, debounce in code
It is evident that the button module is the faster way to add a key to a NodeMCU project, and its pressed = HIGH logic reads more naturally. The bare button is still worth learning if you want to understand pull-up and pull-down resistors.
Ideas for Using the Button Module
WiFi doorbell: send a phone notification when a guest presses the button.
Mode key: each press moves to the next mode of a lamp or a display.
Start/stop key: start and pause a countdown timer.
Simple game pad: use the five colors as five answer keys for a quiz game.
Please feel free to share the link of this tutorial. However, Please do not use our content on any other websites. We invested a lot of effort and time to create the content, please respect our work!