Introduction
Understanding the ESP32 pinout is essential before building any project.
Each pin has a specific function, and using the wrong pin can:
- ❌ Damage your components
- ❌ Break your WiFi connection
- ❌ Cause your code to fail silently
- ❌ Waste hours of debugging
In this complete pinout guide, I'll show you:
- Detailed pinout diagram
- What each pin does
- Which pins to use and which to avoid
- Pin specifications and limits
- Real project examples
By the end, you'll confidently use any ESP32 pin!
ESP32 Board Overview
The ESP32 comes in different variants:
| Variant | Pins | Size | Most Common |
|---|---|---|---|
| ESP32 Dev Module | 30 pins | Standard | ✓ Yes |
| ESP32 WROOM-32 | 38 pins | Larger | Industrial |
| ESP32-S3 | 48 pins | Newer | Latest |
| ESP32-C3 | 22 pins | Tiny | IoT focused |
This guide focuses on the most popular: ESP32 Dev Module (30 pins)
ESP32 Pinout Diagram
Top Row (Left to Right)
GND | D35 | D34 | D39 | D36 | D3 | D1 | D22 | D21 | GND
↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓
[==================ESP32 DEV MODULE==================]
↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑
D23 | D19 | D18 | D5 | D17 | D16 | D4 | D0 | D2 | GND
Complete Pinout List
| Pin | Name | Function | Notes |
|---|---|---|---|
| 1 | GND | Ground | Connect to negative |
| 2 | D35 | Input only | ADC, cannot use as output |
| 3 | D34 | Input only | ADC, cannot use as output |
| 4 | D39 | Input only | ADC, cannot use as output |
| 5 | D36 | Input only | ADC, cannot use as output |
| 6 | D3 | GPIO | Can be used as input/output |
| 7 | D1 | GPIO | Also TX0 (debugging) |
| 8 | D22 | GPIO | Can be used freely |
| 9 | D21 | GPIO | Can be used freely |
| 10 | GND | Ground | Connect to negative |
| 11 | D23 | GPIO | Can be used freely |
| 12 | D19 | GPIO | SPI pins (be careful) |
| 13 | D18 | GPIO | SPI pins (be careful) |
| 14 | D5 | GPIO | Can be used freely |
| 15 | D17 | GPIO | I2C SDA pin |
| 16 | D16 | GPIO | I2C SCL pin |
| 17 | D4 | GPIO | Can be used freely |
| 18 | D0 | GPIO | Strapping pin (careful) |
| 19 | D2 | GPIO | Can be used freely |
| 20 | GND | Ground | Connect to negative |
| 21 | D32 | ADC | Can be input only |
| 22 | D33 | ADC | Can be input only |
| 23 | D25 | DAC | Can output analog voltage |
| 24 | D26 | DAC | Can output analog voltage |
| 25 | D27 | GPIO | Can be used freely |
| 26 | D14 | GPIO | ADC pin |
| 27 | D12 | GPIO | ADC pin (careful) |
| 28 | GND | Ground | Connect to negative |
| 29 | D13 | GPIO | ADC pin |
| 30 | D15 | GPIO | Can be used freely |
Pin Types Explained
GPIO Pins (General Purpose Input/Output)
What they are: Pins you can control freely for digital signals
Safe GPIO pins to use:
- D0, D2, D4, D5, D15, D16, D17, D18, D19, D21, D22, D23, D25, D26, D27, D32, D33
Example:
const int LED_PIN = 5; // Use D5 for LED
void setup() {
pinMode(LED_PIN, OUTPUT);
}
void loop() {
digitalWrite(LED_PIN, HIGH);
delay(1000);
digitalWrite(LED_PIN, LOW);
delay(1000);
}
ADC Pins (Analog Digital Conversion)
What they are: Pins that read analog voltages (0-3.3V)
ADC pins available:
- A0 (D36), A3 (D39), A4 (D32), A5 (D33)
- A6 (D34), A7 (D35)
- A10 (D4), A11 (D0), A12 (D2)
- A13 (D15), A14 (D13), A15 (D12), A16 (D14)
Example:
const int SENSOR_PIN = A4; // D32
void setup() {
Serial.begin(115200);
}
void loop() {
int sensorValue = analogRead(SENSOR_PIN);
Serial.println(sensorValue); // 0-4095
delay(100);
}
DAC Pins (Digital Analog Conversion)
What they are: Pins that output analog voltages (0-3.3V)
DAC pins available:
- D25 (DAC1)
- D26 (DAC2)
Example:
const int DAC_PIN = 25;
void setup() {
pinMode(DAC_PIN, OUTPUT);
}
void loop() {
analogWrite(DAC_PIN, 128); // 0-255, outputs ~1.65V
delay(1000);
}
Input-Only Pins
What they are: Pins that can ONLY read, not write
Input-only pins:
- D34, D35, D36, D39
Problem: These pins have no output capability
Solution: Use only as inputs
const int BUTTON_PIN = 34;
void setup() {
pinMode(BUTTON_PIN, INPUT);
}
void loop() {
int buttonState = digitalRead(BUTTON_PIN);
Serial.println(buttonState);
}
Strapping Pins (Avoid or Use Carefully)
What they are: Pins used for boot mode detection
Strapping pins:
- D0 (pulls HIGH to run normally)
- D2 (pulls LOW to run normally)
- D5 (pulls HIGH to run normally)
- D12 (pulls LOW to run normally)
Problem: Pulling them wrong during boot can prevent program upload
Solution: Avoid using them, or use only as OUTPUT after boot
// Avoid:
const int BAD_PIN = 0;
// Better:
const int GOOD_PIN = 22;
Pins to AVOID
| Pin | Reason | Risk |
|---|---|---|
| D6-D11 | Flash memory | Program gets corrupted |
| D37-D38 | USB JTAG | Debugging gets broken |
| EN | Reset pin | Can't upload code |
| GND | Ground | Shorts circuit |
| 5V | Power | Can burn board |
Power Pins
| Pin | Voltage | Purpose |
|---|---|---|
| 3V3 | 3.3V | Power input (up to 500mA) |
| GND | 0V | Ground (negative) |
| 5V | 5V | Power input (from USB) |
| EN | Reset | Press to restart |
Important: ESP32 runs on 3.3V, NOT 5V!
Never connect 5V sensors directly to GPIO pins.
Pin Functions Reference
UART Pins (Serial Communication)
TX0 = D1 (transmit)
RX0 = D3 (receive)
Use for debugging:
Serial.begin(115200);
Serial.println("Hello!");
SPI Pins (High-Speed Communication)
MOSI = D23
MISO = D19
SCK = D18
CS = D5 (configurable)
Use with SD card, displays:
// Usually configured automatically
// by library
I2C Pins (Sensor Communication)
SDA = D21 (data)
SCL = D22 (clock)
Use with sensors:
#include <Wire.h>
void setup() {
Wire.begin(21, 22); // SDA, SCL
}
PWM Pins (Pulse Width Modulation)
All GPIO pins support PWM for:
- LED brightness control
- Motor speed control
- Servo control
const int LED_PIN = 5;
const int PWM_CHANNEL = 0;
const int FREQUENCY = 5000;
const int RESOLUTION = 8;
void setup() {
ledcSetup(PWM_CHANNEL, FREQUENCY, RESOLUTION);
ledcAttachPin(LED_PIN, PWM_CHANNEL);
}
void loop() {
// Brightness from 0-255
for(int i = 0; i < 256; i++) {
ledcWrite(PWM_CHANNEL, i);
delay(10);
}
}
Real Wiring Examples
Example 1: LED Connection
ESP32 D5 ──[220Ω]──[LED+]
LED- ──GND
Code:
const int LED_PIN = 5;
void setup() {
pinMode(LED_PIN, OUTPUT);
}
void loop() {
digitalWrite(LED_PIN, HIGH);
delay(1000);
digitalWrite(LED_PIN, LOW);
delay(1000);
}
Example 2: Button Connection
ESP32 D4 ──[10kΩ]──3.3V
ESP32 D4 ──[Button]──GND
Code:
const int BUTTON_PIN = 4;
void setup() {
pinMode(BUTTON_PIN, INPUT);
}
void loop() {
if(digitalRead(BUTTON_PIN) == LOW) {
Serial.println("Button pressed!");
}
delay(100);
}
Example 3: Temperature Sensor (I2C)
Sensor VCC ──3.3V
Sensor GND ──GND
Sensor SDA ──D21
Sensor SCL ──D22
Code:
#include <Wire.h>
void setup() {
Wire.begin(21, 22);
}
void loop() {
// I2C communication
}
Example 4: Analog Sensor
Sensor OUT ──D32 (ADC)
Sensor VCC ──3.3V
Sensor GND ──GND
Code:
const int ANALOG_PIN = 32;
void loop() {
int value = analogRead(ANALOG_PIN); // 0-4095
float voltage = value * 3.3 / 4095;
Serial.println(voltage);
}
ESP32 Pin Specifications
Electrical Ratings
| Spec | Value |
|---|---|
| Operating Voltage | 3.3V |
| Input Voltage | 5-6V (via USB) |
| GPIO Output Current | 40mA per pin |
| GPIO Input Current | None |
| Digital Output Range | 0-3.3V |
| Analog Input Range | 0-3.3V |
| ADC Resolution | 12-bit (0-4095) |
| DAC Resolution | 8-bit (0-255) |
Maximum Current Limits
Single pin: 40 mA max
All pins total: 1200 mA max
3.3V regulator: 600 mA max
⚠️ Warning: Don't exceed these limits or you'll damage the ESP32!
Pin Selection Guide
For LEDs
- Best: D2, D4, D5, D22, D23, D27
- Avoid: Input-only pins, D0, D12
For Buttons
- Best: D4, D14, D15, D32, D33
- Avoid: Strapping pins
For Sensors (I2C)
- Fixed: D21 (SDA), D22 (SCL)
- Don't change these
For Analog Sensors
- Best: D32, D33, D34, D35, D36, D39
- Note: Last 4 are input-only
For PWM (Motor, Servo)
- Best: D2, D4, D5, D14, D15, D32, D33, D27
- Note: All pins support PWM
For SPI Communication
- Fixed: D18, D19, D23 (+ CS pin)
- Don't change these
Troubleshooting Pin Problems
| Problem | Cause | Solution |
|---|---|---|
| Code won't upload | Strapping pin shorted | Remove wires, upload, reconnect |
| GPIO doesn't work | Using input-only pin | Switch to D0-D5, D14-D27, D32-D33 |
| Analog reading wrong | Not using ADC pin | Use D32, D33, D34-D36, D39 |
| WiFi stops working | Pin conflict | Check if using GPIO used by WiFi |
| LED too bright | Current limiting | Add 220Ω resistor |
Quick Pin Reference Table
SAFE TO USE: AVOID:
D0 ✓ D6-D11 ✗ (Flash)
D2 ⚠ (Strapping) D37-D38 ✗ (JTAG)
D4 ✓ 5V ✗ (Logic only)
D5 ⚠ (Strapping)
D14 ✓
D15 ✓
D16 ✓ (I2C)
D17 ✓ (I2C)
D18 ✓ (SPI)
D19 ✓ (SPI)
D21 ✓ (I2C)
D22 ✓ (I2C)
D23 ✓ (SPI)
D25 ✓ (DAC)
D26 ✓ (DAC)
D27 ✓
D32-36 ✓ (ADC)
D39 ✓ (ADC input)
GND ✓ (Ground)
3V3 ✓ (Power)
Best Practices
- Always use a GPIO pinout diagram while wiring
- Double-check pin numbers before connecting
- Use resistors for LEDs (220Ω minimum)
- Use pull-up resistors for buttons (10kΩ)
- Check voltage before connecting sensors
- Never exceed current limits per pin
- Use breadboard for testing (no soldering)
- Add bypass capacitors near power pins (0.1μF)
FAQ
Q: Can I use D6-D11? A: No. These are connected to flash memory and will corrupt your program.
Q: Why is my WiFi weak? A: D19 and D18 are used by WiFi. Don't use them for other things.
Q: Can I power an LED directly from a GPIO pin? A: Maybe, but add a resistor (220Ω) to protect the pin.
Q: What's the difference between GPIO and ADC pins? A: GPIO reads digital (HIGH/LOW), ADC reads analog (0-4095).
Q: Can I use multiple I2C sensors? A: Yes! Same pins (D21, D22) with different I2C addresses.
Summary
You now know:
✓ Complete ESP32 pinout diagram ✓ What each pin type does ✓ Which pins are safe to use ✓ Which pins to avoid ✓ Real wiring examples ✓ Pin specifications and limits
Save this guide! Bookmark it for every project.
Related Guides
- ESP32 WiFi Setup
- ESP32 Analog Reading
- ESP32 I2C Communication
- ESP32 SPI Communication
- ESP32 PWM Control
Last Updated: June 2026 Verified: ESP32 Dev Module
