ESP32 GPIO Tutorial: A Complete Beginner’s Guide
One of the first things you’ll learn when working with an ESP32 is how to use its GPIO pins. GPIO stands for General Purpose Input/Output and these pins allow the ESP32 to communicate with the outside world.
Whether you want to blink an LED, read a push button, control a relay, or connect sensors, you’ll use GPIO pins in almost every ESP32 project.
In this beginner-friendly tutorial, you’ll learn what GPIO pins are, how they work, which pins are safe to use, and how to control them using Arduino IDE.
What are GPIO Pins?
GPIO stands for General Purpose Input/Output.
These are programmable pins available on the ESP32 board. Depending on your program, each GPIO pin can either:
- Read signals from sensors and buttons (Input)
- Send signals to LEDs, relays, buzzers, or motors (Output)
Think of GPIO pins as communication ports between the ESP32 and external electronic components.
Why are GPIO Pins Important?
Without GPIO pins, the ESP32 cannot interact with external devices.
GPIO pins allow you to:
- Turn LEDs ON and OFF
- Read push buttons
- Control relays
- Drive servo motors
- Connect LCD and OLED displays
- Read temperature and humidity sensors
- Measure analog voltages
- Generate PWM signals
- Build IoT applications
Almost every ESP32 project uses GPIO pins in some way.
Understanding GPIO Pin Numbers
Unlike Arduino Uno, the ESP32 has many GPIO pins.
For example:
GPIO2
GPIO4
GPIO5
GPIO12
GPIO13
GPIO14
GPIO15
GPIO16
GPIO17
GPIO18
GPIO19
GPIO21
GPIO22
GPIO23
GPIO25
GPIO26
GPIO27
GPIO32
GPIO33
When programming, always use the GPIO number—not the physical pin position on the board.
For example:
const int ledPin = 2;
Here, 2 refers to GPIO2.
GPIO Pin Modes
Every GPIO pin works in a specific mode.
The three most commonly used modes are:
INPUT
Reads data from buttons, switches, and sensors.
pinMode(4, INPUT);
OUTPUT
Controls LEDs, relays, and other devices.
pinMode(2, OUTPUT);
INPUT_PULLUP
Enables the ESP32’s internal pull-up resistor, making button circuits simpler.
pinMode(15, INPUT_PULLUP);
Safe GPIO Pins for Beginners
The following GPIO pins are generally safe for most beginner projects:
- GPIO2
- GPIO4
- GPIO5
- GPIO16
- GPIO17
- GPIO18
- GPIO19
- GPIO21
- GPIO22
- GPIO23
- GPIO25
- GPIO26
- GPIO27
- GPIO32
- GPIO33
These pins work well for LEDs, sensors, and many other components.
GPIO Pins to Use Carefully
Some GPIO pins have special functions during the ESP32 boot process.
Examples include:
- GPIO0
- GPIO2
- GPIO12
- GPIO15
Using these pins incorrectly may prevent the ESP32 from starting properly.
As a beginner, it’s best to avoid these pins until you’re familiar with bootstrapping pins.
Input-Only GPIO Pins
Some ESP32 pins can only read signals.
These include:
- GPIO34
- GPIO35
- GPIO36
- GPIO39
These pins cannot control LEDs or relays because they support input only.
They’re commonly used with sensors.
Your First GPIO Output Example

Let’s blink an LED using GPIO2.
Components Required
- ESP32 Development Board
- USB Cable
- Arduino IDE
Circuit
Most ESP32 boards already have an onboard LED connected to GPIO2.
No external wiring is required.
Code
const int ledPin = 2; void setup() { pinMode(ledPin, OUTPUT); } void loop() { digitalWrite(ledPin, HIGH); delay(1000); digitalWrite(ledPin, LOW); delay(1000); }
Understanding the Code
Declare the GPIO Pin
const int ledPin = 2;
This tells the ESP32 to use GPIO2.
Configure the Pin
pinMode(ledPin, OUTPUT);
The GPIO becomes an output pin.
Turn LED ON
digitalWrite(ledPin, HIGH);
HIGH means the pin outputs approximately 3.3V.
The LED turns ON.
Turn LED OFF
digitalWrite(ledPin, LOW);
LOW means 0V.
The LED turns OFF.
Delay
delay(1000);
Waits one second before the next instruction.
Reading a Push Button
GPIO pins can also read inputs.
Let’s connect a push button.
Components Required
- ESP32
- Push Button
- Breadboard
- Jumper Wires
Connection
- One side of the button → GPIO15
- Other side → GND
Enable the internal pull-up resistor in software.
Code const int buttonPin = 15; void setup() { Serial.begin(115200); pinMode(buttonPin, INPUT_PULLUP); } void loop() { if (digitalRead(buttonPin) == LOW) { Serial.println("Button Pressed"); } delay(100); }
Upload the code, open the Serial Monitor, and press the button. You should see the message “Button Pressed” each time the button is pressed.
Understanding digitalRead()
The digitalRead() function reads the current state of a GPIO pin.
Example:
int state = digitalRead(15);
If the pin is HIGH, the variable stores HIGH.
If the pin is LOW, the variable stores LOW.
This is how ESP32 detects button presses and switch positions.
Understanding digitalWrite()
The digitalWrite() function changes the state of an output pin.
Example:
digitalWrite(2, HIGH);
This turns the output ON.
Example:
digitalWrite(2, LOW);
This turns the output OFF.
It is one of the most commonly used functions in ESP32 programming.
Common GPIO Functions
Here are some functions you’ll use frequently.
| Function | Purpose |
|---|---|
pinMode() |
Configure a GPIO pin |
digitalRead() |
Read a digital input |
digitalWrite() |
Control a digital output |
analogRead() |
Read analog values |
ledcWrite() |
Generate PWM signals |
These functions form the foundation of most ESP32 projects.
Recommended GPIO Pins
These GPIO pins are suitable for most beginner projects.
| GPIO Pin | Common Use |
|---|---|
| GPIO2 | Onboard LED, General Output |
| GPIO4 | LED, Sensor |
| GPIO5 | Relay, Output |
| GPIO16 | UART, Digital I/O |
| GPIO17 | UART, Digital I/O |
| GPIO18 | SPI Clock |
| GPIO19 | SPI MISO |
| GPIO21 | I2C SDA |
| GPIO22 | I2C SCL |
| GPIO23 | SPI MOSI |
| GPIO25 | DAC, Output |
| GPIO26 | DAC, Output |
| GPIO27 | Digital I/O |
| GPIO32 | ADC, PWM |
| GPIO33 | ADC, PWM |
These pins are widely used and are safe for most beginner projects.
Understanding Digital GPIO

Digital GPIO pins work with only two values.
- HIGH
- LOW
HIGH means the pin outputs approximately 3.3V.
LOW means the pin outputs 0V.
Digital GPIO pins are commonly used for:
- LEDs
- Push buttons
- Relays
- Buzzers
- Digital sensors
Understanding Analog GPIO (ADC)
Unlike digital pins, analog pins can read different voltage levels.
The ESP32 includes a built-in Analog-to-Digital Converter (ADC).
Instead of reading only HIGH or LOW, it measures voltage between approximately 0V and 3.3V.
Common analog sensors include:
- Potentiometer
- LDR (Light Sensor)
- Soil Moisture Sensor
- Gas Sensor
- Joystick Module
Reading an Analog Sensor
Suppose you connect a potentiometer to GPIO34.
Code const int sensorPin = 34; void setup() { Serial.begin(115200); } void loop() { int sensorValue = analogRead(sensorPin); Serial.println(sensorValue); delay(500); }
Open the Serial Monitor.
Rotate the potentiometer.
You’ll notice the analog value changing continuously.
Understanding analogRead()
The function
analogRead(pin);
reads the voltage on an analog pin.
Example:
int value = analogRead(34);
Typical values range between:
0 to 4095
Higher values indicate higher voltage.
PWM on ESP32
PWM stands for Pulse Width Modulation.
PWM allows you to simulate analog output using digital pins.
Instead of simply turning an LED ON or OFF, PWM lets you:
- Control LED brightness
- Adjust motor speed
- Control servo movement
- Fade lights smoothly
ESP32 supports multiple PWM channels, making it much more powerful than many beginner boards.
LED Brightness Control Using PWM
The following example gradually increases and decreases LED brightness.
const int ledPin = 2; const int channel = 0; const int frequency = 5000; const int resolution = 8; void setup() { ledcSetup(channel, frequency, resolution); ledcAttachPin(ledPin, channel); } void loop() { for(int dutyCycle=0; dutyCycle<=255; dutyCycle++){ ledcWrite(channel,dutyCycle); delay(10); } for(int dutyCycle=255; dutyCycle>=0; dutyCycle--){ ledcWrite(channel,dutyCycle); delay(10); } }
This creates a smooth fading LED effect.
Understanding PWM Functions
ledcSetup()
Creates a PWM channel.
ledcSetup(channel, frequency, resolution);
ledcAttachPin()
Assigns the PWM channel to a GPIO pin.
ledcAttachPin(pin, channel);
ledcWrite()
Changes the PWM duty cycle.
ledcWrite(channel, value);
Higher values produce brighter LEDs.
Touch Sensor GPIO Pins
One unique feature of the ESP32 is its built-in touch sensor support.
You don’t need additional hardware.
Simply touch a conductive object connected to a touch pin.
Popular touch pins include:
- GPIO4
- GPIO12
- GPIO13
- GPIO14
- GPIO15
- GPIO27
- GPIO32
- GPIO33
These pins are useful for:
- Touch switches
- Smart locks
- Home automation
- Interactive projects
Reading a Touch Sensor
Example code:
void setup() { Serial.begin(115200); } void loop() { Serial.println(touchRead(4)); delay(300); }
Touch the connected wire.
The displayed value changes when touched.
GPIO Pins for Communication
Many ESP32 projects communicate with external devices.
Different communication protocols use different GPIO pins.
I2C
Common pins:
- SDA → GPIO21
- SCL → GPIO22
Used for:
- OLED Displays
- RTC Modules
- Environmental Sensors
SPI
Common pins:
- MOSI → GPIO23
- MISO → GPIO19
- SCK → GPIO18
- CS → GPIO5
Used for:
- SD Card Modules
- TFT Displays
- RFID Modules
UART
Common pins:
- TX → GPIO17
- RX → GPIO16
Used for:
- GPS Modules
- GSM Modules
- Serial Communication
GPIO Pins Best Suited for Different Projects
| Project | Recommended GPIO |
|---|---|
| LED | GPIO2 |
| Relay | GPIO5 |
| Push Button | GPIO15 |
| Potentiometer | GPIO34 |
| OLED Display | GPIO21, GPIO22 |
| RFID | GPIO18, GPIO19, GPIO23 |
| Servo Motor | GPIO18 |
| DHT11 Sensor | GPIO4 |
| Ultrasonic Sensor | GPIO5, GPIO18 |
Choosing the right GPIO pin makes your project more reliable.
GPIO Best Practices
Follow these simple guidelines.
- Always use 3.3V logic.
- Never apply 5V directly to GPIO pins.
- Double-check your wiring before powering the board.
- Avoid using boot pins unless necessary.
- Use external resistors when recommended.
- Disconnect power before changing connections.
- Label wires to avoid confusion.
These habits help prevent hardware damage.
Common GPIO Mistakes
Many beginners encounter the same problems.
Using the Wrong GPIO
Always verify the GPIO number before uploading code.
Supplying 5V to GPIO Pins
ESP32 GPIO pins are not 5V tolerant.
Applying 5V directly may permanently damage the board.
Using Input-Only Pins as Outputs
GPIO34, GPIO35, GPIO36, and GPIO39 cannot control LEDs or relays.
Use them only for reading inputs.
Incorrect Wiring
Loose jumper wires are one of the most common causes of project failures.
Always check every connection carefully.
Mini Project: Control an LED with a Push Button
Let’s combine both input and output.
Components
- ESP32
- LED
- 220Ω Resistor
- Push Button
- Breadboard
- Jumper Wires
Connections
- LED → GPIO2
- Push Button → GPIO15
- Common GND
Code
const int ledPin = 2; const int buttonPin = 15; void setup() { pinMode(ledPin, OUTPUT); pinMode(buttonPin, INPUT_PULLUP); } void loop() { if(digitalRead(buttonPin)==LOW){ digitalWrite(ledPin,HIGH); } else{ digitalWrite(ledPin,LOW); } }
When the button is pressed, the LED turns ON.
When released, the LED turns OFF.
This simple project demonstrates how GPIO input and output work together in real-world applications.
Understanding GPIO Interrupts

Until now, you’ve learned how to continuously check a GPIO pin using the digitalRead() function. This method works well for simple projects, but constantly checking a pin can be inefficient.
An interrupt allows the ESP32 to immediately respond when a specific event occurs, such as pressing a button, without repeatedly checking the pin inside the loop() function.
Interrupts are commonly used in:
- Push buttons
- Motion sensors
- Rotary encoders
- Door sensors
- Pulse counters
Using interrupts makes your programs faster and more responsive.
GPIO Interrupt Example
The following example turns the onboard LED ON or OFF whenever a button is pressed.
Components Required
- ESP32 Development Board
- Push Button
- Breadboard
- Jumper Wires
Connections
- LED → GPIO2 (Onboard LED)
- Push Button → GPIO15
- Other side of the button → GND
Code
const int ledPin = 2; const int buttonPin = 15; volatile bool ledState = false; void IRAM_ATTR buttonPressed() { ledState = !ledState; } void setup() { pinMode(ledPin, OUTPUT); pinMode(buttonPin, INPUT_PULLUP); attachInterrupt(digitalPinToInterrupt(buttonPin), buttonPressed, FALLING); } void loop() { digitalWrite(ledPin, ledState); }
How It Works
- The button is connected to GPIO15.
- Every time the button is pressed, an interrupt is triggered.
- The interrupt changes the LED state.
- The LED turns ON and OFF without constantly checking the button inside the
loop()function.
GPIO Functions You Should Know
As you build more ESP32 projects, you’ll frequently use the following GPIO-related functions.
| Function | Description |
|---|---|
pinMode() |
Sets a GPIO pin as INPUT, OUTPUT, or INPUT_PULLUP |
digitalRead() |
Reads the state of a digital pin |
digitalWrite() |
Sets a digital pin HIGH or LOW |
analogRead() |
Reads analog values from ADC pins |
touchRead() |
Reads values from touch-enabled pins |
attachInterrupt() |
Attaches an interrupt to a GPIO pin |
detachInterrupt() |
Removes an interrupt |
ledcWrite() |
Generates PWM output |
Learning these functions will help you create most beginner and intermediate ESP32 projects.
GPIO Applications
GPIO pins are used in almost every ESP32 application.
Some common examples include:
- Home automation
- Smart lighting
- Security systems
- Weather stations
- Robotics
- Smart irrigation
- IoT devices
- Industrial monitoring
- Data logging
- Bluetooth projects
- Wi-Fi-enabled sensors
- OLED display projects
No matter what you build with ESP32, you’ll almost always use one or more GPIO pins.
Tips for Beginners
If you’re just starting with ESP32, these tips can save you time and prevent common mistakes.
- Start with LED projects before using sensors.
- Read the ESP32 pinout diagram before wiring.
- Use high-quality USB data cables.
- Label jumper wires while building circuits.
- Keep your wiring neat.
- Test one component at a time.
- Save working code before making changes.
- Read compiler error messages carefully.
- Always disconnect power before changing connections.
- Practice with small projects before moving to IoT applications.
Consistent practice is the fastest way to become comfortable with ESP32 programming.
Troubleshooting Common GPIO Problems
Even simple GPIO projects can sometimes fail due to small mistakes. Here are some common problems and their solutions.
Problem: LED Doesn’t Turn On
Possible causes:
- Incorrect GPIO number
- LED connected in reverse
- Loose jumper wire
- Missing resistor (for external LEDs)
Solution: Check the wiring and verify that the GPIO number in your code matches your circuit.
Problem: Button Doesn’t Respond
Possible causes:
- Incorrect wiring
- Missing
INPUT_PULLUP - Faulty push button
Solution: Recheck the circuit and ensure the button is connected correctly to the GPIO pin and GND.
Problem: Analog Values Don’t Change
Possible causes:
- Sensor connected to a digital-only GPIO
- Incorrect sensor wiring
- Faulty sensor
Solution: Use one of the ADC-capable GPIO pins such as GPIO32, GPIO33, GPIO34, GPIO35, GPIO36, or GPIO39.
Problem: ESP32 Doesn’t Boot
Possible causes:
- Using a bootstrapping pin incorrectly
- Short circuit
- Insufficient power
Solution: Disconnect external components and verify that GPIO0, GPIO2, GPIO12, and GPIO15 are not preventing the ESP32 from starting.
Best Beginner Projects Using GPIO
Once you’re comfortable with GPIO programming, try building these beginner-friendly projects.
- Blink an LED
- Push Button Controlled LED
- Traffic Light Simulation
- RGB LED Controller
- Buzzer Alarm
- Temperature Monitoring using DHT11
- Automatic Night Lamp using LDR
- Soil Moisture Monitoring
- Motion Detection using PIR Sensor
- OLED Display with Sensor Data
- Servo Motor Control
- Relay-Based Home Automation
Each project helps you understand how different GPIO modes work in real-world applications.
ESP32 GPIO vs Arduino Uno GPIO
Many beginners wonder how ESP32 compares with the Arduino Uno.
| Feature | ESP32 | Arduino Uno |
|---|---|---|
| Operating Voltage | 3.3V | 5V |
| Wi-Fi | Built-in | External Module Required |
| Bluetooth | Built-in | Not Available |
| GPIO Pins | More than 30 | 14 Digital |
| Analog Inputs | Multiple | 6 |
| PWM Pins | Multiple | 6 |
| Processor Speed | Up to 240 MHz | 16 MHz |
| Memory | Much Higher | Limited |
For IoT and modern embedded projects, the ESP32 provides significantly more features than the Arduino Uno.
Conclusion
GPIO pins are one of the most important features of the ESP32. They allow the board to communicate with LEDs, sensors, buttons, displays, relays, motors, and many other electronic components.
In this tutorial, you learned what GPIO pins are, how digital and analog GPIO work, how to configure pin modes, use PWM, read touch sensors, communicate using I2C, SPI, and UART, and even respond to button presses with interrupts.
The best way to master ESP32 GPIO programming is by building small projects. Start with simple examples like blinking an LED or reading a button, then gradually move on to more advanced projects involving sensors, displays, and IoT applications.
As your confidence grows, you’ll be able to create smarter and more powerful ESP32-based systems.
Frequently Asked Questions (FAQs)
What does GPIO stand for?
GPIO stands for General Purpose Input/Output. These programmable pins allow the ESP32 to interact with external hardware such as LEDs, sensors, switches, and relays.
How many GPIO pins does the ESP32 have?
Most ESP32 development boards expose more than 30 GPIO pins, although some are reserved for special purposes or are input-only.
Can every GPIO pin be used as an output?
No. GPIO34, GPIO35, GPIO36, and GPIO39 are input-only pins and cannot be used to drive LEDs, relays, or other output devices.
Can ESP32 GPIO pins handle 5V?
No. ESP32 GPIO pins operate at 3.3V and are generally not 5V tolerant. Applying 5V directly to a GPIO pin can damage the board.
Which GPIO pins are best for beginners?
GPIO2, GPIO4, GPIO5, GPIO16, GPIO17, GPIO18, GPIO19, GPIO21, GPIO22, GPIO23, GPIO25, GPIO26, GPIO27, GPIO32, and GPIO33 are commonly recommended for beginner projects.
What is the difference between digital and analog GPIO?
Digital GPIO pins read or output only HIGH and LOW states, while analog-capable GPIO pins can measure varying voltage levels using the ESP32’s built-in ADC.
Can I use Arduino IDE to program ESP32 GPIO pins?
Yes. Arduino IDE is one of the easiest and most popular ways to program ESP32 GPIO pins, making it an excellent choice for beginners.
Suggested Reading
Continue learning ESP32 with these beginner-friendly tutorials:
- Getting Started with ESP32: A Complete Beginner’s Guide
- ESP32 Pinout Explained
- How to Install ESP32 Board in Arduino IDE
- ESP32 LED Blink Tutorial
- ESP32 Push Button Tutorial
- ESP32 PWM Tutorial
- ESP32 ADC Tutorial
- ESP32 Touch Sensor Tutorial
- ESP32 Wi-Fi Tutorial
- ESP32 Bluetooth (BLE) Tutorial
- ESP32 Web Server Tutorial
- ESP32 DHT11 Temperature Sensor Tutorial
- ESP32 Relay Module Tutorial
- ESP32 OLED Display Tutorial
