ESP32 MicroPython Button Module

This tutorial instructs you how to use the button module with the ESP32 and MicroPython, step by step in Thonny. In detail, we will learn:

ESP32 MicroPython and button module

Overview of Button Module

Think of the button module as a push button that brings its own resistor. The tactile switch, its colored cap and a pull-down resistor all sit on one small board, so the ESP32 always reads a clean 0 when nobody touches it and a 1 while a finger holds it down. One thing every switch still does: the metal contacts bounce for a few milliseconds when they close or open. To the ESP32, one press can look like two or three quick presses, which is why this tutorial shows two ways to clean that up. The modules come in a pack of five cap colors: red, yellow, green, blue and white.

Button Module
Switch type momentary tactile push button with colored cap
Operating voltage 3.3V to 5V DC
Onboard parts pull-down resistor on the OUT line
Output when released LOW (0)
Output when pressed HIGH (1), equal to the VCC voltage
Header 3 pins, 2.54mm, labeled VCC, OUT, GND

Pinout

Button Module Pinout
image source: diyables.io

The header has three pins, labeled in this order:

  • VCC pin: connect to the 3.3 volts pin of the ESP32. Do not use the VIN or 5V pin (see the warning below).
  • OUT pin: connect to a GPIO pin of the ESP32. It reads 0 when the button is up and 1 when the button is down.
  • GND pin: connect to GND (0 volts) of the ESP32.

※ NOTE THAT:

When you press the button, the OUT pin passes the VCC voltage straight to the ESP32 pin. The ESP32 GPIO pins are made for 3.3 volts only. If VCC is on VIN or 5V, every press pushes 5 volts into GPIO21, and that can damage the ESP32. Always power the module from 3.3V.

How is this different from a bare 4-leg push button? With the bare button, you must find out which legs are joined inside and add a pull-up or pull-down resistor (or turn on Pin.PULL_UP, which flips the logic so pressed reads 0). The module has labeled pins and its own pull-down, so pressed simply reads 1. For the same reason, do not turn on Pin.PULL_UP for this module: it would pull against the resistor on the board.

Wiring Diagram

Three jumper wires are enough. The OUT pin goes to GPIO21, the same pin the other ESP32 MicroPython button tutorials on this site use.

The wiring diagram between ESP32 MicroPython button module

This image is created using Fritzing. Click to enlarge image

Button Module Pin ESP32 Pin
VCC 3.3V (never VIN or 5V)
OUT GPIO21
GND GND

ESP32 MicroPython Code - Read the Button Module State

Let's start with the simplest check: does the ESP32 see the button at all? This script sets GPIO21 as a plain input with Pin(21, Pin.IN). No pull resistor is turned on, because the module already has one. Five times per second, the script reads the pin with value() and prints the number together with a word, so a 1 shows as "pressed" and a 0 as "released".

""" This ESP32 MicroPython code was developed by newbiely.com This ESP32 MicroPython code is made available for public use without any restriction For comprehensive instructions and wiring diagrams, please visit: https://newbiely.com/tutorials/esp32-micropython/esp32-micropython-button-module """ from machine import Pin import time BUTTON_MODULE_PIN = 21 # The ESP32 pin GPIO21 connected to the OUT pin of the button module # Plain input mode. The module has its own pull-down resistor, # so no internal pull-up or pull-down is needed here. button_module = Pin(BUTTON_MODULE_PIN, Pin.IN) while True: level = button_module.value() # 1 = pressed, 0 = released if level == 1: print("OUT pin:", level, "-> pressed") else: print("OUT pin:", level, "-> released") time.sleep_ms(200) # Print 5 times per second, so the Shell is easy to read

Detailed Instructions

Here's instructions on how to set up and run your MicroPython code on the ESP32 using Thonny IDE:

  • Check that Thonny IDE is on your computer and that your ESP32 already runs MicroPython firmware.
  • Never done this before? Follow the ESP32 MicroPython Getting Started guide first.
  • Wire the button module to the ESP32 like the diagram above. Double-check that VCC goes to 3.3V.
  • Plug the ESP32 into your computer with the USB cable, then start Thonny.
  • Open Tools Options, go to the Interpreter tab and pick MicroPython (ESP32).
  • Pick the port if Thonny does not find it by itself (for example COM7 on Windows or /dev/ttyUSB0 on Linux).
  • Paste the code above into a new editor tab in Thonny.
  • Store it on the board:
    • Press Ctrl+S or click the Save button.
    • Select MicroPython device when Thonny asks where to save.
    • Enter main.py as the file name.
  • Press F5 or click the green Run button.
  • Leave the button alone for a second, hold it down for about one second, then let go.
  • The Shell at the bottom of Thonny shows the change:
Shell x
>>> %Run -c $EDITOR_CONTENT
MPY: soft reboot MPY: soft reboot OUT pin: 0 -> released OUT pin: 0 -> released OUT pin: 0 -> released OUT pin: 1 -> pressed OUT pin: 1 -> pressed OUT pin: 1 -> pressed OUT pin: 1 -> pressed OUT pin: 0 -> released OUT pin: 0 -> released
MicroPython (ESP32) • CP2102 USB To UART Bridge Controller @ COM12 ≡

If you name your script main.py and save it to the MicroPython device, it will run automatically every time the ESP32 is powered on.

If the Shell shows 1 while you are not pressing, or the numbers jump around, look at the GND wire and the OUT wire first. A loose GND is the usual cause.

ESP32 MicroPython Code - Press and Release Events with a Delay

A level that stays at 1 is useful for "hold to run" jobs, but most projects want to know the moment something happens: a doorbell rings once per press, a game counts each tap. This script keeps the last level in last_level. When a new reading is different, it does not trust it right away. It sleeps 50 ms with time.sleep_ms(50), reads GPIO21 again, and only reports the change if it is still there. That second look hides the contact bounce. The cost is that sleep_ms() blocks: for those 50 ms, the loop cannot do anything else.

""" This ESP32 MicroPython code was developed by newbiely.com This ESP32 MicroPython code is made available for public use without any restriction For comprehensive instructions and wiring diagrams, please visit: https://newbiely.com/tutorials/esp32-micropython/esp32-micropython-button-module """ from machine import Pin import time BUTTON_MODULE_PIN = 21 # The ESP32 pin GPIO21 connected to the OUT pin of the button module SETTLE_TIME_MS = 50 # Time to wait for the contacts to stop bouncing button_module = Pin(BUTTON_MODULE_PIN, Pin.IN) # The module's pull-down keeps OUT at 0 when released last_level = button_module.value() # Remember the level we saw last time while True: level = button_module.value() if level != last_level: # The level changed. Wait a moment, then read again to be sure. # Note: sleep_ms() blocks, so nothing else runs during these 50 ms. time.sleep_ms(SETTLE_TIME_MS) level = button_module.value() if level != last_level: # The change is still there, so it is real if level == 1: print("The button is pressed") else: print("The button is released") last_level = level

Detailed Instructions

Keep the same wiring.

  • Click the red Stop button in Thonny to end the first script.
  • Replace the code in the editor with the code above.
  • Save it again to the MicroPython device as main.py.
  • Press F5 to run it.
  • Tap the button three times, quickly and then slowly.
  • Each tap gives exactly two lines in the Shell:
Shell x
>>> %Run -c $EDITOR_CONTENT
MPY: soft reboot MPY: soft reboot The button is pressed The button is released The button is pressed The button is released The button is pressed The button is released
MicroPython (ESP32) • CP2102 USB To UART Bridge Controller @ COM12 ≡

Do you still see a double "pressed" now and then? Your button bounces longer than usual. Raise SETTLE_TIME_MS to 80 or 100.

ESP32 MicroPython Code - Button Module with the DIYables Library

The pause in the last script is fine for a small test. In a real project, the ESP32 often has other work in the same loop, such as reading a sensor or updating a display, and a blocked loop makes that work late. The DIYables-MicroPython-Button library solves this. It records the time of each change and only accepts a new level after it has stayed the same for the debounce time, so button.loop() returns at once and never sleeps.

The code creates the button with Button(21, Pin.PULL_DOWN). The Pin.PULL_DOWN mode tells the library that 1 means pressed, which matches the resistor on the module. After button.set_debounce_time(50), every pass of the while loop calls button.loop() first. Then:

  • button.is_pressed() is True once, right after a press.
  • button.is_released() is True once, right after a release.
  • button.get_state() gives the steady, debounced level (1 or 0).
""" This ESP32 MicroPython code was developed by newbiely.com This ESP32 MicroPython code is made available for public use without any restriction For comprehensive instructions and wiring diagrams, please visit: https://newbiely.com/tutorials/esp32-micropython/esp32-micropython-button-module """ from DIYables_MicroPython_Button import Button from machine import Pin BUTTON_MODULE_PIN = 21 # The ESP32 pin GPIO21 connected to the OUT pin of the button module # Pin.PULL_DOWN tells the library that 1 means pressed, # which matches the pull-down resistor on the button module. button = Button(BUTTON_MODULE_PIN, Pin.PULL_DOWN) button.set_debounce_time(50) # Ignore bounces shorter than 50 milliseconds last_state = button.get_state() while True: button.loop() # Must be called first in every loop. It never blocks. if button.is_pressed(): print("The button is pressed") if button.is_released(): print("The button is released") state = button.get_state() # The debounced (steady) level: 1 or 0 if state != last_state: print("Steady state is now:", state) last_state = state

Detailed Instructions

  • In Thonny, open Tools Manage packages.
  • Type DIYables-MicroPython-Button in the search box and search.
  • Click DIYables-MicroPython-Button by DIYables in the results, then click the Install button.
ESP32 MicroPython Button library
  • Close the package window, then put the library code above into Thonny's editor.
  • Save it to the MicroPython device as main.py.
  • Press F5 to run it.
  • Press the button once and hold it a moment, then press it once more.
  • The Shell shows each event and the new steady level:
Shell x
>>> %Run -c $EDITOR_CONTENT
MPY: soft reboot MPY: soft reboot The button is pressed Steady state is now: 1 The button is released Steady state is now: 0 The button is pressed Steady state is now: 1 The button is released Steady state is now: 0
MicroPython (ESP32) • CP2102 USB To UART Bridge Controller @ COM12 ≡

Want to see more ways to use this library, like several buttons at once? Read the ESP32 MicroPython Button Debounce tutorial. To make the module switch a light, see the ESP32 MicroPython Button LED tutorial. Just remember to use Pin.PULL_DOWN (or Pin.IN with no pull) for the module, since those pages use bare buttons with a pull-up.

Project Ideas

A button module on the ESP32 makes a good input for:

  • A WiFi doorbell that sends a message to your phone each time the button is pressed.
  • A mode button that steps through display pages or LED colors, one step per press.
  • A start/stop button for a timer or a data logger.
  • A small game pad: give each player a button module in a different color and see who presses first.

Video Tutorial

※ OUR MESSAGES

  • As freelancers, We are AVAILABLE for HIRE. See how to outsource your project to us
  • 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!