ESP32 Digital Inputs & Digital Outputs – Arduino Tutorial

Previous Tutorial Previous Tutorial Tutorial 1 Next Tutorial Next Tutorial
ESP32 GPIO Tutorial (Inputs/Outputs) – Arduino
ESP32 Course Home Page 🏠


In this tutorial, you’ll learn about ESP32 GPIO and how to read digital inputs (e.g. a push-button), and control digital outputs (e.g. an LED) using Arduino Core in Arduino IDE. Let’s just start with the ESP32 GPIO hardware features, how it works, and then start implementing an LED control example LAB.

ESP32 Digital Input Read - Digital Output Write - GPIO Tutorial Arduino IDE

Requirements For This Tutorial

Prior Knowledge

  • Nothing

Software Tools

Hardware Components

You can either get the complete course kit for this series of tutorials using the link down below. Or just refer to the table for the exact components to be used in practical LABs for only this specific tutorial.

ESP32 GPIO Hardware Features


In this section, I’ll give you an introduction to the hardware capabilities for the ESP32 GPIO pins and how they work, and what kind of features that we can be used in the future in our favor. And let’s start with the most important feature that you must be aware of before hooking anything to ESP32 pins, the voltage level.

ESP32 GPIO Voltage Levels

The ESP32 GPIO pins are not 5v tolerant, they are 3.3v for logic HIGH (1). You just can’t directly use them with any 5v input source whether it’s an electronic sensor, module, or other microcontrollers (like an Arduino UNO, Microchip PIC, etc).

You need to have any sort of level-shifting to interface with any other 5v logic devices. A simple voltage divider network (2 resistors) would get the job done, but not for critical high-speed signal communications of course.

ESP32 IO Mux & GPIO Matrix

The GPIO pins in the ESP32 microcontroller are interconnected via a pretty complex GPIO matrix. This is basically a multiplexor (MUX) to enable the user (You, the programmer) of selecting which GPIO pins is routed to which peripheral’s signal internally.

With an option to just Bypass the GPIO Mux and have your signal directly connected to the peripheral, which is useful for High-Speed signal peripherals like UART, SPI, Ethernet, etc. Here is how it looks in the datasheet diagram down below.

ESP32 Inputs Outputs Pins Tutorial - GPIO Matrix

This feature is commonly referred to as PPS (peripheral pin select) in Microchip PIC Microcontrollers. It gives the designer the flexibility of changing the GPIO pin connection inside of the microcontroller itself and route it to any signal. This makes PCB designs a lot easier to re-configure without re-routing any tracks and things like that.

Any GPIO pin can be a PWM CH1, UART TX, RX, or just any other function. This implies the need to assert the GPIO pin to be in Input/Output mode if we want it to be just a normal input/output pin. And also to assign the pins to any peripheral we’re going to use in case we’re going to use them for special functions other than being inputs/outputs. We’ll detail this in the future tutorials of course.

This demo Diagram below may be a little bit clearer for many readers.

ESP32 Digital Inputs Outputs tutorial - GPIO Mux

ESP32 Pin State Hold Feature

The ESP32 digital pins have a very useful feature to hold the pin state value and latch it before a system core reset or during deep sleep mode. By activating the pin hold feature for a specific GPIO pin, this pin will preserve its state (HIGH or LOW) and stay the same during a reset maybe by a watchdog timer or something else like entering a deep sleep mode.

For digital pads (pins), to maintain the pad’s input/output status in Deep-sleep mode, you can set REG_DG_PAD_FORCE_UNHOLD to 0 before powering down. For digital pads, to disable the hold function after the chip is woken up, you can set REG_DG_PAD_FORCE_UNHOLD to 1. To maintain the hold function of the pad, you can change the corresponding bit in the register by setting RTC_CNTL_HOLD_FORCE_REG to 1.

ESP32 Digital Outputs Control


You can use the ESP32 GPIO pins in output mode just to control anything ranging from a small LED all the way up to high-power devices through relays, SSR, thyristors, etc. Let’s start with a simple example in which we’d like to control an LED to turn it ON & OFF.

First of all, you need to define the GPIO pin to operate in output mode in the setup() function, using pinMode() Arduino function as shown below.

pinMode(GPIO_pin, OUTPUT);

Then you can drive the pin HIGH or LOW to change the digital state of that pin. You can turn the LED ON by writing a HIGH or 1, they’re the same thing. And also for turning it OFF, you can write a LOW or 0. Using the Arduino digitalWrite() function as shown below.

digitalWrite(GPIO_pin, HIGH); // Turn ON

digitalWrite(GPIO_pin, LOW);  // Turn OFF

And that’s it. Now, you can define any GPIO pin to operate in the Output mode and command that pin to be driven HIGH or LOW. Just keep the following note in mind.

All ESP32 GPIO pins can operate in Input or Output modes. Except for the pins (34 to 39) those are input-only pins. You just can’t drive them HIGH or LOW. They’re used only in input mode. On our board, we’ve 4 of them namely (GPIO34 – GPIO35 – GPIO36 – GPIO39).


ESP32 Digital Inputs Read


ESP32 GPIO pins can be used in the digital input mode to read external digital signals with our microcontroller. Digital input signals can come from various sources like a small push button, digital proximity sensor, digital optical encoder, etc.

Just like in output mode, you need first to define the GPIO pin to operate in input mode in the setup() function, using pinMode() Arduino function as shown below.

pinMode(GPIO_pin, INPUT);

With that simple line of code we’ve configured the GPIO pin to be an input pin, now we can read the state of the pin with the digitalRead() Arduino function. BUT, it’s not recommended to do this before introducing a very important thing that needs to be done in the hardware setup. Which is input pull-down or pull-up.

You need to have all the digital input pins either in a pull-down or a pull-up configuration. Here is why and how to do this.

ESP32 Digital Inputs Outputs Arduino tutorial - Pull up and Pull down

Leaving the digital input pin floating as shown on the left-hand side is pretty bad practice, it’ll pick up a lot of noise and the GPIO digital logic read units won’t be sure if it’s a 0 or 1. Therefore, we need to do either a pull-up or a pull-down with a 10k resistor as shown on the right-hand side.

The only difference between the pull-up and the pull-down configuration is the logic polarity. But other than that, they’re essentially the same. Note the thin yellow arrow in both configurations. It shows you the dead short circuit path if we didn’t place the 10k resistors.

If somebody pressed the button without this resistor in place, it’ll be a dead short from Vcc to GND. Must it always be a 10k resistor? of course not! Just use any value to limit the current flow when the button is pressed.

Now, after being done with the button connection, let’s read the input pin (button) state in Arduino’s main function code.

BTN_State = digitalRead(GPIO_pin);

And that’s it! Let’s now combine both functions in a very simple example to switch an LED ON while a button is pressed and switch it OFF when the button is released.

Note: After being done with the pull-up & down configurations, you should also note that there still a source of noise in the input signal. This stems from the fact that the push button is a mechanical device and mechanical contacts do bounce! Read more about the bouncing issue and how to do proper debouncing. This article is for STM32, not ESP32, but the knowledge is applicable on any other platform.


Components For This Tutorial’s LABs


QTY. Component Name Buy Links
1 ESP32 Devkit v1 DOIT Board

or Any Other ESP32 Dev Board  –  –
2 BreadBoard – –
1 Resistors Kit /  –  –
1 Jumper Wires Pack – –
1 Push Buttons –  –
1 LEDs Kit – –
1 Micro USB Cable  – –

*Affiliate Disclosure: When you click on links in this section and make a purchase, this can result in this site earning a commission. Affiliate programs and affiliations include, but are not limited to, the eBay Partner Network (EPN) and, This may be one of the ways to support this free platform while getting your regular electronic parts orders as usual at no extra cost to you.

ESP32 Button & LED Example – LAB


PCBgogo Ad
LAB Number 1
LAB Name Button & LED
  • Define Input & Output pins
  • Read The input button pin
  • Write The button state to the LED output pin

Connection Diagram

ESP32 Digital Inputs Outputs Arduino tutorial - Connection Diagram

Hardware Connection

ESP32 Digital Inputs Read - Digital Output Control Tutorial Arduino IDE


ESP32 Button & LED Code Example

The code example down below defines 2 GPIO pins. GPIO4 For the Push Button input, and GPIO2 for the LED output.

We just read the input pin state and assign that value to the LED output pin. So that the LED is ON while the button is pressed and held, releasing the button will be read as a 0 which will be written to the LED so it goes OFF. And keep repeating in the loop() function!

#define LED_GPIO 2
#define BTN_GPIO 4

int BTN_State = 0; // Variable To Store Button State

void setup() 
  pinMode(LED_GPIO, OUTPUT);
  pinMode(BTN_GPIO, INPUT);

void loop() 
  // Read The Button State
  BTN_State = digitalRead(BTN_GPIO);
  // Assign The BTN State To The LED Pin
  digitalWrite(LED_GPIO, BTN_State);

Choose the board, COM port, hold down the BOOT button, click upload and keep your finger on the BOOT button pressed. When the Arduino IDE starts sending the code, you can release the button and wait for the flashing process to be completed. Now, the ESP32 is flashed with the new firmware.

Demo Video For The Result

ESP32 Digital Inputs Outputs Arduino tutorial - Example LAB

Click The image to watch the demo video on YouTube


Did you find this helpful? If yes, please consider supporting this work and sharing these tutorials!


Stay tuned for the upcoming tutorials and don’t forget to SHARE these tutorials. And consider SUPPORTING this work to keep publishing free content just like this!



ESP32 Course Home Page 🏠 
Previous Tutorial Previous Tutorial Tutorial 1 Next Tutorial Next Tutorial
Share This Page With Your Network!

Khaled Magdy

I'm an embedded systems engineer doing both Software & Hardware. I'm an EE guy who studied Computer Engineering, But I'm also passionate about Computer Science. I love reading, writing, creating projects and Technical training. A reader by day a writer by night, it's my lifestyle. You can view my profile or follow me via contacts.

You may also like...

Leave a Reply

%d bloggers like this: