Understanding the ESP32 Pin Numbering System
The ESP32’s GPIO numbering can initially confuse beginners because the chip-level GPIO numbers do not always match the silkscreen labels on popular development boards. Every GPIO is identified by a number from 0 to 39, and Espressif’s datasheets and Arduino API functions always refer to these numbers — not D0, D1-style aliases. On the 38-pin DevKitC board, most silkscreen labels print the GPIO number directly, making it one of the cleaner boards to use. Always cross-reference the GPIO number printed on the board edge with the functional table below before wiring.
There are 34 GPIO pins in total (GPIO 0–33 plus GPIO 34–39 as input-only). GPIO 6 through 11 are internally connected to the SPI flash memory chip that stores your firmware — connecting anything to these pins will corrupt flash access and cause resets. This leaves 28 usable general-purpose GPIO on most 38-pin boards.
Power Pins
Before touching any GPIO, understand the power rails. The 38-pin DevKitC exposes: 3V3 (3.3 V regulated output, up to ~600 mA depending on the board’s LDO), 5V / VIN (5 V input from USB or external supply — do not use as a regulated output), GND (two or more ground pins), and EN (chip enable — pulling low resets the chip). The 3V3 pin can power external sensors and modules rated for 3.3 V. Never connect 5 V peripherals directly to GPIO without level shifting.
GPIO 0–5: Boot-Sensitive Multi-Function Pins
GPIO 0 doubles as a boot-mode selector. It must be pulled high through its internal pull-up during normal boot. Espressif’s DevKit boards include a 10 kΩ pull-up resistor on this pin plus a BOOT button that grounds it. You can use GPIO 0 as output after boot, but be careful not to ground it externally during power-up.
GPIO 1 (TX0) and GPIO 3 (RX0) are UART0 — the serial port used by the USB-to-serial chip for programming and the Arduino Serial monitor. Avoid using these for user purposes when you need the serial console. Output on GPIO 1 can be seen in the Serial Monitor.
GPIO 2 is another boot-strapping pin (must be low or floating for normal boot on some modules). The blue LED on the DevKitC is connected to GPIO 2. It is also an ADC1 channel (ADC1_CH2) and a touch pin (T2). After boot it can be used freely.
GPIO 4 is a safe general-purpose pin with no boot constraints. It supports ADC2 (not recommended with Wi-Fi), PWM, I²C SDA, and touch sensing.
GPIO 5 must be high during boot (another boot-strapping pin controlling the SD0 startup behaviour). It is connected to an onboard LED on some clone boards. After boot it is a safe GPIO with SPI-CS capability.
GPIO 6–11: Never Use — Flash SPI Pins
GPIO 6 (CLK), 7 (SD0/MISO), 8 (SD1/MOSI), 9 (SD2), 10 (SD3), and 11 (CMD) are the six lines of the internal quad-SPI interface that communicates with the external flash chip holding your firmware. Attempting to use any of these pins in your sketch will cause the ESP32 to crash or fail to program. Consider them permanently reserved. On the 38-pin DevKitC they are physically absent from the pin header.
GPIO 12–15: JTAG and Boot-Sensitive
GPIO 12 (TDI) is a boot-strapping pin that sets the flash voltage level. If it reads high during boot, the chip selects a 1.8 V flash supply instead of 3.3 V. Most modules (WROOM-32, WROVER) have the flash strapped for 3.3 V, making GPIO 12 safe after boot — but connecting a pull-up resistor to 3.3 V before boot can prevent the chip from starting. The safest practice: use GPIO 12 only as an input without pull-up, or as an output driven after boot.
GPIO 13 (TCK), GPIO 14 (TMS), GPIO 15 (TDO) are the remaining JTAG pins. They can be remapped for general use. GPIO 15 also controls boot log printing: when low, the ROM bootloader suppresses startup messages on UART0. After boot all four JTAG pins are available as regular GPIOs with ADC2 capability.
GPIO 16–23: Most Reliable General-Purpose Pins
This range contains the most reliable pins for beginners. GPIO 16 (RX2) and GPIO 17 (TX2) are the default UART2 hardware serial port — safe for RS232 adapters, GPS modules, and other UARTs. GPIO 18 is the default SPI clock (SCK), GPIO 19 the SPI data input (MISO), GPIO 21 the default I²C data (SDA), GPIO 22 the I²C clock (SCL), and GPIO 23 the SPI data output (MOSI). These functions are defaults only — the GPIO matrix lets you remap any peripheral to any pin, so you are not forced to use these specific pins.
GPIO 20 is not exposed on the standard 38-pin DevKitC. GPIO 22 is useful for I²C SCL but shares with an onboard LED on some development boards — check your board’s schematic.
GPIO 25–27: ADC2, DAC, and General Use
GPIO 25 and GPIO 26 are the two true 8-bit Digital-to-Analog Converter (DAC) outputs. Use dacWrite(25, value) where value is 0–255, corresponding to 0–3.3 V. These are the only pins that can output an arbitrary analog voltage without PWM filtering. They are ideal for driving audio amplifiers or generating simple waveforms. Both pins are also ADC2 channels, but since they are shared with Wi-Fi radio circuitry, they should not be used for analogRead() while Wi-Fi is active.
GPIO 27 is a general GPIO with ADC2 and touch pin capability (T7). It has no special constraints after boot.
GPIO 32–33: ADC1 and Touch Pins
GPIO 32 (ADC1_CH4, T9) and GPIO 33 (ADC1_CH5, T8) are part of the ADC1 group, making them safe for analog reads even when Wi-Fi is running. Both also support capacitive touch sensing and 32.768 kHz crystal input for the RTC clock. These are among the most versatile pins on the board for sensor projects.
GPIO 34–39: Input Only
GPIO 34, 35, 36, and 39 have no output driver circuit and no internal pull-up or pull-down resistors. They can only be configured as digital inputs or ADC inputs. GPIO 36 (SVP, ADC1_CH0) and GPIO 39 (SVN, ADC1_CH3) are the most common choices for voltage monitoring because they belong to ADC1 and work reliably with Wi-Fi active. Use these pins for reading analog sensors, voltage dividers, and light-dependent resistors.
PWM: Anywhere You Need It
Unlike AVR-based Arduinos where PWM is limited to specific marked pins, the ESP32 LEDC peripheral provides 16 PWM channels that can be routed to any output-capable GPIO. In Arduino IDE use ledcSetup(channel, frequency, resolution) and ledcAttachPin(pin, channel) to assign a PWM channel to a pin. Common frequencies: 5 kHz for motor control, 1 kHz for LED dimming, 38 kHz for IR transmission. Resolution up to 20 bits (1,048,576 steps), though 8-bit (255 steps) is standard for simple dimming.
I²C: Flexible Remapping
The ESP32 has two hardware I²C controllers. Wire (I²C bus 0) defaults to GPIO 21 (SDA) and GPIO 22 (SCL). Wire1 (I²C bus 1) can be assigned to any pins. Initialise with Wire.begin(sda, scl) to override defaults. The standard 100 kHz and 400 kHz clock speeds are supported; some libraries push to 800 kHz or 1 MHz. The ESP32 can host up to 112 I²C devices on a single bus (7-bit addressing), though bus capacitance limits practical numbers to 20–30 devices in typical wiring setups.
SPI: Multiple Buses
The ESP32 has four SPI controllers (SPI0 and SPI1 reserved for flash, HSPI and VSPI for user code). HSPI defaults to GPIO 14 (CLK), 12 (MISO), 13 (MOSI), 15 (CS). VSPI defaults to GPIO 18 (CLK), 19 (MISO), 23 (MOSI), 5 (CS). Both can be remapped. You can drive two independent SPI devices simultaneously on the two buses, which is useful for projects combining an SD card reader with an SPI display.
Quick Reference Table
| GPIO | Key Functions | Notes |
|---|---|---|
| 0 | Boot mode, ADC2_CH1, Touch T1 | Boot-strapping — must be high on boot |
| 1 | UART0 TX | USB serial TX — avoid for user IO |
| 2 | ADC2_CH2, Touch T2, Blue LED | Boot-strapping (low or float) on some modules |
| 3 | UART0 RX | USB serial RX — avoid for user IO |
| 4 | ADC2_CH0, Touch T0 | Safe general IO |
| 5 | SPI CS, VSPI default CS | Boot-strapping — must be high on boot |
| 6–11 | Flash SPI (CLK, MISO, MOSI…) | NEVER USE in user sketches |
| 12 | TDI, ADC2_CH5, Touch T5 | Flash voltage strapping — no pull-up |
| 13 | TCK, ADC2_CH4, Touch T4 | Safe after boot; JTAG |
| 14 | TMS, ADC2_CH6, HSPI CLK, Touch T6 | Safe after boot |
| 15 | TDO, ADC2_CH3, HSPI CS, Touch T3 | Boot log pin |
| 16 | UART2 RX | Safe, recommended UART2 RX |
| 17 | UART2 TX | Safe, recommended UART2 TX |
| 18 | VSPI CLK | SPI clock default |
| 19 | VSPI MISO | SPI data in default |
| 21 | I²C SDA | Wire default SDA |
| 22 | I²C SCL | Wire default SCL |
| 23 | VSPI MOSI | SPI data out default |
| 25 | DAC1, ADC2_CH8 | True analog output |
| 26 | DAC2, ADC2_CH9 | True analog output |
| 27 | ADC2_CH7, Touch T7 | Safe general IO |
| 32 | ADC1_CH4, Touch T9, XTAL | Safe; ADC1 works with Wi-Fi |
| 33 | ADC1_CH5, Touch T8, XTAL | Safe; ADC1 works with Wi-Fi |
| 34 | ADC1_CH6 | Input only, no pull resistors |
| 35 | ADC1_CH7 | Input only, no pull resistors |
| 36 (VP) | ADC1_CH0 | Input only — good for analog |
| 39 (VN) | ADC1_CH3 | Input only — good for analog |
Voltage and Current Limits
Every GPIO pin on the ESP32 operates at 3.3 V logic. The absolute maximum input voltage is 3.6 V — exceeding this even briefly risks electrostatic damage to the input protection circuit. Maximum current per GPIO output pin is 40 mA source or sink. Always use a current-limiting resistor for LEDs: for a standard 20 mA LED with 2.0 V forward voltage on a 3.3 V supply, a 68 Ω resistor is the minimum (3.3 − 2.0 ÷ 0.02 = 65 Ω). A 100 Ω or 220 Ω resistor reduces brightness slightly and extends LED life.
The onboard 3V3 LDO regulator on typical DevKit boards supplies 600–800 mA maximum. If you are powering multiple servos, LCD modules, or a large LED strip from the board, power them from an external 3.3 V supply instead of from the 3V3 pin to avoid brownout resets.
Practical Wiring Tips
Use breadboard-friendly 30 AWG solid wire for short jumper connections and keep wire lengths under 20 cm for SPI and I²C to minimise signal reflections. Add 100 nF decoupling capacitors across the 3V3 and GND pins near sensitive analog sensors — even a small ceramic capacitor reduces ADC noise significantly. When reading capacitive touch pins, avoid running wires parallel to power or motor drive lines as they couple noise into the touch measurement.
For prototyping, number your GPIOs with sticky tape labels on the breadboard. The DevKitC’s two rows of pins bridge the breadboard centre rails, leaving only one column of holes on each side. Consider a 30 AWG wire extension that breaks the pin rows out to a more accessible position for complex builds.