ESP32 S3 UNO - Button

This ESP32 S3 Uno button tutorial shows you how to wire a push button and read it with Arduino code. A push button, also called a tactile button or momentary switch, looks simple, but floating inputs and contact bounce often confuse beginners. By the end, your ESP32 S3 Uno form board will print the button state and catch each press and release on the Serial Monitor.

In this tutorial, you will:

  1. Learn how a push button works and what its pins do
  2. Wire a push button to the ESP32 S3 Uno
  3. Use the internal pull-up resistor with pinMode(INPUT_PULLUP)
  4. Read the button state with digitalRead()
  5. Detect button press and release events in Arduino code
ESP32 S3 Uno button

※ NOTE THAT:

Two problems trip up almost every beginner who uses a button. Knowing them now saves you a lot of debugging later.

  1. The floating input problem. You wire the button to an input pin, but the value you read jumps between HIGH and LOW at random and does not follow the button. This happens because the pin has no pull-up or pull-down resistor. The fix is to add one, and this tutorial shows the easiest way to do it.
  2. The chattering problem. You press the button once, but your code sees several presses. This happens because the metal contacts inside the button bounce, so the pin flips between LOW and HIGH many times in a few milliseconds. The fix is called debouncing, and it is covered in the ESP32 S3 Uno - Button - Debounce tutorial.

Chattering only matters when your project must count presses exactly. For many other projects, you can ignore it.

Hardware Preparation

1×ESP32 S3 Uno-form Board
1×USB Cable Type-A to Type-C (for USB-A PC)
1×USB Cable Type-C to Type-C (for USB-C PC)
1×Breadboard-mount Button with Cap
1×Breadboard-mount Button Kit
1×Panel-mount Button
1×Push Button Module
1×Breadboard
1×Jumper Wires

Or you can buy the following kits:

1×DIYables Sensor Kit (18 sensors/displays)
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

A push button is the most common way to give a command to your board. It only connects its two sides while your finger holds it down, and it opens again as soon as you let go. That is why it is also called a momentary switch or tactile button.

You can find three common kinds. PCB-mount buttons are small and fit on a breadboard. Panel-mount buttons are bigger and are made to sit in the lid of a box. A button module puts a button and a resistor on a small board, ready to wire.

ESP32 S3 Uno Push button

Pinout

Each type of button has a different number of pins. Knowing which pins are joined inside helps you avoid a button that seems "always pressed".

The PCB-mount buttons usually have four pins.

Button Pinout

Inside the button, the four pins are joined in two pairs. You only need two pins, and they must be from different pairs. If you pick two pins from the same pair, the circuit is always closed.

The picture below shows the ways you can connect it. There are four options, but they really come down to two, because the pairs are the same.

How To Use Button

So why does the button have four pins if you only use two? The extra pins hold the button firmly on the PCB, so it does not move or break when you press it hard.

The panel-mount buttons usually have two pins.

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

These are easy. Use one pin for the board and the other for GND or VCC.

The push button module has a built-in pull-down resistor and three pins.

The resistor keeps the output LOW while nobody presses the button.

  1. GND goes to ground.
  2. VCC goes to a 3.3V or 5V supply. With the ESP32 S3 Uno, use 3.3V.
  3. OUT goes to a digital input pin on the ESP32 S3 Uno.

With this wiring, the module gives LOW when the button is released and HIGH when it is pressed.

How It Works

The idea is simple. While the button is up, pin A and pin B are not connected. When you press it, a small metal plate joins pin A and pin B.

How Button Works

ESP32 S3 Uno - Button

To read a button, you connect one of its pins to VCC or GND, and the other pin to an ESP32 S3 Uno pin. Then you set that pin as an input. Your code checks the pin state to know if the button is pressed or not.

Button State and Pressing State

The value you read does not always mean "HIGH = pressed". It depends on how you wire the button and how you set the pin. You can do it in two ways.

Option 1: button to VCC, with a pull-down resistor

Connect one button pin to 3.3V and the other to an ESP32 S3 Uno pin. Add a pull-down resistor from that pin to GND. The pin reads HIGH when you press the button and LOW when you release it. You need an external resistor for this.

Option 2: button to GND, with a pull-up resistor

Connect one button pin to GND and the other to an ESP32 S3 Uno pin with a pull-up resistor. The pin reads LOW when you press the button and HIGH when you release it. Here you can use an external resistor, or the internal pull-up resistor inside the ESP32 S3 Uno, which you turn on in code.

※ NOTE THAT:

Without a pull-up or pull-down resistor, the input pin is "floating" while the button is released. A floating pin picks up electrical noise, so it can read HIGH or LOW at random.

  • The worst choice: set the pin with pinMode(BUTTON_PIN, INPUT) and add no resistor at all.
  • The best choice: set the pin with pinMode(BUTTON_PIN, INPUT_PULLUP). This turns on the internal pull-up resistor, so you need no extra part.

This tutorial uses Option 2 with the internal pull-up resistor. It is the easiest setup for beginners. You only wire the button between the pin and GND, and the code does the rest.

ESP32 S3 Uno Pinout

The image below shows the pinout of the ESP32 S3 Uno form board. Use it to find the D7 header and its GPIO number before you wire the button.

ESP32 S3 Uno pinout diagram

Wiring Diagram

Wire one side of the button to the D7 header and the other side to GND. Pick the diagram that matches your button type.

  • Wiring diagram for the ESP32 S3 Uno and a PCB-mount button
The wiring diagram between ESP32 S3 Uno Button

This image is created using Fritzing. Click to enlarge image

  • Wiring diagram for the ESP32 S3 Uno and a panel-mount button
The wiring diagram between ESP32 S3 Uno two-pin push button

This image is created using Fritzing. Click to enlarge image

Button Pin ESP32 S3 Uno Pin
Pin A D7 (GPIO14)
Pin B GND

WARNING

If you use a button module, power it from the 3.3V pin, not 5V. The module's OUT pin gives the same voltage as its VCC, and ESP32 S3 Uno pins are NOT 5V tolerant. A 5V signal can damage GPIO14.

How To Program For Button

Reading a button takes just two functions. You set the pin mode once, then read the pin as often as you need.

  1. In setup(), turn D7 (GPIO14) into an input with the internal pull-up resistor by calling pinMode().
pinMode(14, INPUT_PULLUP);
  1. In loop(), read the pin with digitalRead().
int button_state = digitalRead(BUTTON_PIN);

※ NOTE THAT:

Most button projects follow one of two patterns:

  • Act on the level. While the input is HIGH, do one thing. While it is LOW, do the opposite.
  • Act on the change. When the input goes from LOW to HIGH (or HIGH to LOW), do something once.

Choose the one that fits your goal. For example, with a button and an LED:

  • If the LED should stay on only while you hold the button, use the first pattern.
  • If the LED should toggle on and off each time you press, use the second pattern.

ESP32 S3 Uno Code - Reading the state of button

This sketch reads the button on GPIO14 every half second and prints the value on the Serial Monitor. Because of the pull-up resistor, you see 1 while the button is released and 0 while you hold it down.

#define BUTTON_PIN 14 // The ESP32 S3 Uno pin connected to the button (D7) void setup() { // initialize serial communication at 9600 bits per second: Serial.begin(9600); // initialize the pushbutton pin as a pull-up input 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); delay(500); }

Detailed Instructions

Follow these steps in order:

  1. New to the ESP32 S3 Uno? Follow ESP32 S3 Uno - Getting Started first.
  2. Wire it up as shown in the diagram.
  3. Connect the board to your computer with a USB Type-C cable.
  4. Open Arduino IDE, choose the ESP32S3 Dev Module board and the correct COM port.
  5. Copy the code above and paste it into Arduino IDE.
  6. Upload the code by clicking the Upload button.
Arduino IDE - How to Upload Code
  1. Open the Serial Monitor and set the baud rate to 9600.
  2. Press and release the button a few times.
  3. Check the result on the Serial Monitor.
∞
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
ESP32S3 Dev Module
Newbiely.ino
···
8 Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'ESP32S3 Dev Module' on 'COM15')
New Line
9600 baud
1 1 1 0 0 0 0 0 0 1 1 1
Ln 11, Col 1
ESP32S3 Dev Module on COM15
2
  1. Tip: 1 means the button is released (OFF) and 0 means it is pressed (ON). If the values change without touching the button, check that one side of the button really goes to GND.

Code Explanation

Each line of the sketch has a comment that explains what it does. Read the comments in the code above to follow it step by step.

ESP32 S3 Uno Code - Detecting the button's press and release event

Often you do not care about the state itself, but about the moment it changes. This version saves the last state and compares it with the new one. When the pin goes from HIGH to LOW, it prints that the button is pressed. When it goes from LOW to HIGH, it prints that the button is released.

/* * This ESP32 S3 Uno code was developed by newbiely.com * * This ESP32 S3 Uno code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/esp32-s3-uno/esp32-s3-uno-button */ #define BUTTON_PIN 14 // The ESP32 S3 Uno pin connected to the button (D7) int button_state; // the current state of button int prev_button_state = LOW; // the previous state of button void setup() { // initialize serial communication at 9600 bits per second: Serial.begin(9600); // initialize the pushbutton pin as a pull-up input 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 last state prev_button_state = button_state; }

Detailed Instructions

  1. Copy the code above and paste it into Arduino IDE.
  2. Upload the code to the ESP32 S3 Uno by clicking the Upload button.
  3. Open the Serial Monitor at 9600 baud.
  4. Press and release the button once.
  5. Check the result on the Serial Monitor.
∞
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
ESP32S3 Dev Module
Newbiely.ino
···
8 Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'ESP32S3 Dev Module' on 'COM15')
New Line
9600 baud
The button is pressed The button is released
Ln 11, Col 1
ESP32S3 Dev Module on COM15
2
  1. Tip: If one press prints several lines, that is the chattering problem. It is normal for a button without debouncing.

※ NOTE THAT:

  • A single press and release can show up as many events on the Serial Monitor. This is called the "chattering phenomenon". Learn how to fix it in the ESP32 S3 Uno - Button Debounce tutorial.
  • If you use many buttons, the ezButton library makes the code much shorter. You can learn about the ezButton library here.
  • If you use the button module, set the pin with pinMode(BUTTON_PIN, INPUT). The module already has a pull-down resistor, so it gives LOW when released and HIGH when pressed.

Video Tutorial

Watch the video below to see this ESP32 S3 Uno project step by step.

FAQ

Why does the ESP32 S3 Uno read 1 when the button is not pressed?

The code uses INPUT_PULLUP, so the internal resistor pulls the pin up to 3.3V. When you press the button, it connects the pin to GND and the reading drops to 0. So 1 means released and 0 means pressed.

Can I connect the button to 5V on the ESP32 S3 Uno?

No. ESP32 S3 Uno pins are not 5V tolerant, unlike the UNO R4 pins. With the wiring in this tutorial, the button only connects the pin to GND, so no 5V is involved. If you use a button module, power it from 3.3V.

Which ESP32 S3 Uno pin should I use for a button?

Any normal digital header works, such as D7 (GPIO14) in this tutorial. Write the GPIO number in your code, not the header name. Avoid D0 and D1, which are used for USB serial. Also avoid D6 (GPIO3) and D9 (GPIO46) if you can, because they are boot strapping pins and a pressed button at startup can stop the board from booting.

Why does one press show up as many presses?

The metal contacts inside the button bounce for a few milliseconds, and the fast ESP32 S3 Uno sees each bounce. Add debouncing in code, or use the ezButton library, which handles it for you.

Do I need an external resistor for the button?

Not with this wiring. The ESP32 S3 Uno has internal pull-up resistors that you turn on with pinMode(pin, INPUT_PULLUP). You only need an external pull-down resistor if you wire the button to 3.3V instead of GND.

What if my project needs more pins than the Uno headers give?

The ESP32 S3 Uno has two extra rows of holes with more GPIOs. GPIO15 and GPIO16 support I/O, PWM and analog. GPIO45 and GPIO35 to GPIO42 support I/O and PWM. GPIO47 and GPIO48 are output only, with PWM. Solder pin headers to use them and write the GPIO number in your code. For extra buttons, GPIO35 to GPIO42 are a good choice. Never use GPIO47 or GPIO48 for a button, because they cannot be inputs. Keep two warnings in mind. First, GPIO47 and GPIO48 may run at 1.8V instead of 3.3V on some modules (especially ones with "V" in the name, like R8V or R16V), so 3.3V devices can be damaged or act strangely. Second, GPIO0, GPIO3 (D6), GPIO45 and GPIO46 (D9) are boot strapping pins, and a wrong connection can stop the board from booting or uploading code. Use the other extra pins first.

Troubleshooting

Problem Possible Cause Solution
No COM port shows up in Arduino IDE USB driver missing or board not in upload mode Install the CP210x or CH340 driver, use a data USB cable, or hold BOOT while pressing RESET
Nothing prints on the Serial Monitor Wrong baud rate Set the Serial Monitor to 9600 baud
Value changes at random without pressing Floating input or loose wire Use INPUT_PULLUP and check the wire from the button to GND
Value is always 0 Two pins from the same pair used on a 4-pin button Turn the button 90 degrees or use pins from different pairs
Value never changes when pressed Button on the wrong header or wrong GPIO in code Wire the button to D7 and use GPIO14 in the code
One press prints several events Contact bounce (chattering) Add debouncing or use the ezButton library
Button module reads the opposite way Module has a pull-down resistor Use INPUT instead of INPUT_PULLUP and expect HIGH when pressed

※ 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!