The standard ESP32 DevKit (typically based on the ESP32-WROOM-32 module) exposes 38 physical header pins, but only 25 are safely usable as general-purpose I/O. Misinterpreting the esp32dev pinout leads to boot loops, fried silicon, and WiFi dropouts. Below is the definitive reference for mapping physical headers to silicon functions, navigating manufacturer variants, and avoiding the most common hardware traps.

The Complete ESP32 DevKit Pinout Reference Table

Read this table by matching the GPIO number (used in your Arduino/ESP-IDF code) to the Physical Pin printed on your board's silkscreen. Constraints dictate whether a pin can be used for your specific application.

GPIOPhysical LabelI/O TypeSpecial Functions & Constraints
0GPIO0I/OStrapping Pin. PWM. Must be HIGH to boot normally; LOW enters flash mode.
1TX0 / U0TXDOutputDefault UART0 TX. Do not use if Serial monitor is active.
2GPIO2I/OStrapping Pin. PWM. Connected to onboard LED. Must be LOW or floating to boot.
3RX0 / U0RXDInputDefault UART0 RX. HIGH at boot.
4GPIO4I/OTouch0, ADC2_CH0, PWM. Safe for general use.
5GPIO5I/OStrapping Pin. VSPI CS. PWM. Outputs PWM signal at boot.
6-11GPIO6-11N/ADANGER: Connected to internal SPI flash. Using these will crash the ESP32.
12GPIO12I/OStrapping Pin. Touch5, ADC2_CH5. Boot fails if pulled HIGH (selects 1.8V flash).
13GPIO13I/OTouch4, ADC2_CH4, PWM. Safe for general use.
14GPIO14I/OTouch6, ADC2_CH6, PWM. Outputs PWM at boot.
15GPIO15I/OStrapping Pin. Touch3, ADC2_CH3, PWM. Outputs PWM at boot.
16GPIO16I/OU0RTS, RX2. Safe for general use (no Touch/ADC).
17GPIO17I/OU0CTS, TX2. Safe for general use.
18GPIO18I/ODefault VSPI SCK (SPI Clock). PWM.
19GPIO19I/ODefault VSPI MISO (SPI Master In). Safe for general use.
21GPIO21I/ODefault I2C SDA (Data). Safe for general use.
22GPIO22I/ODefault I2C SCL (Clock). Safe for general use.
23GPIO23I/ODefault VSPI MOSI (SPI Master Out). PWM.
25GPIO25OutputDAC1 (Digital to Analog). ADC2_CH8. Safe for analog out.
26GPIO26OutputDAC2 (Digital to Analog). ADC2_CH9. Safe for analog out.
27GPIO27I/OTouch7, ADC2_CH7. Safe for general use.
32GPIO32I/OXTAL_32K_P, Touch9, ADC1_CH4. Safe for use with WiFi.
33GPIO33I/OXTAL_32K_N, Touch8, ADC1_CH5. Safe for use with WiFi.
34GPIO34Input OnlyADC1_CH6. No internal pull-up resistor. Requires external pull-up.
35GPIO35Input OnlyADC1_CH7. No internal pull-up resistor.
36VP / GPIO36Input OnlySensor_VP, ADC1_CH0. No internal pull-up.
39VN / GPIO39Input OnlySensor_VN, ADC1_CH3. No internal pull-up.

Board Variants, Silkscreen Standards, and Faded Markings

Unlike household AC wiring governed by NEC or IEC 60446 color codes, embedded development boards lack a universal physical layout standard. The 'esp32dev pinout' varies wildly depending on the manufacturer. Here is how to interpret the standards that do apply, and how to read a board when the silkscreen fails.

Manufacturer Variants: V1 vs V4 vs NodeMCU

The original Espressif ESP32-DevKitC V4 exposes all 38 pins of the WROOM-32 module. However, the ubiquitous DOIT DevKit V1 and NodeMCU-32S clones only expose 30 pins, omitting GPIO 6-11 (the flash pins) and sometimes GPIO 20 (which is internally grounded). If your code references GPIO 20 on a 30-pin board, you will read a permanent LOW or cause a short.

Logic Level Standards (LVCMOS33)

The ESP32 operates on the LVCMOS33 logic standard. The absolute maximum voltage on any GPIO is 3.6V. Connecting a standard 5V Arduino sensor directly to an ESP32 input will degrade the silicon over time or instantly destroy the ESD protection diodes. Use a bidirectional logic level converter (like the BSS138-based modules) or a simple resistor voltage divider (2kΩ and 3.3kΩ) for 5V-to-3.3V translation.

Safe Interpretation When Markings are Faded or Missing

Cheap clone boards often suffer from illegible silkscreen printing. If you cannot read the pin labels, use these physical landmarks to re-establish your pinout map:

  • The EN Pin: On almost all DevKitC and DOIT layouts, the pin immediately adjacent to the EN (Enable) pin on the top-left side (USB port facing down) is GPIO 36 (VP).
  • The Square Pad: Flip the board over. Pin 1 of the header is almost always indicated by a square solder pad rather than a round one.
  • Continuity Tracing: Set your multimeter to continuity mode. Probe the exposed ground plane on the metal RF shield of the WROOM module to identify all GND header pins. Then, reference the official ESP32 datasheet to trace the module pads to the headers.
Wiring Color Code Best Practice: While the board lacks color codes, your bench wiring shouldn't. Adopt IEC 60446-inspired DC standards for your jumper wires: Black for GND, Red for 3.3V, Orange for 5V (if using a level shifter), Yellow for I2C SDA, and Green for I2C SCL. This prevents catastrophic 5V-to-GND shorts when debugging densely wired breadboards.

The 'Rows People Get Wrong' Trap Guide

Even with the table above, experienced makers routinely fall into specific ESP32 hardware traps. Here are the rows that cause the most grief, and why.

The TrapThe SymptomThe Physics / Firmware Reason
Using GPIO 6-11 ESP32 fails to boot; serial monitor shows 'flash read err' or infinite reboot loop. These pins are hardwired to the internal SPI flash memory chip. Toggling them corrupts the firmware fetch process.
Pulling GPIO 12 HIGH at Boot Board boots, but immediately brownouts or throws a 'flash voltage mismatch' error. GPIO 12 is a strapping pin that dictates the internal flash voltage regulator (1.8V vs 3.3V). Pulling it HIGH forces 1.8V, starving a 3.3V flash chip.
Using ADC2 with WiFi analogRead() on GPIO 25-27 or 12-15 returns 0 or erratic garbage when WiFi connects. The ESP32 WiFi driver claims exclusive hardware access to the ADC2 peripheral. You must use ADC1 pins (GPIO 32-39) for analog readings in IoT projects.
Expecting Pull-ups on GPIO 34-39 Floating input pins read random noise; INPUT_PULLUP in code does nothing. GPIO 34-39 are input-only and physically lack internal pull-up/pull-down resistors on the silicon die. You must solder external 10kΩ resistors.

ESP32 DevKit Pinout FAQ

Why does my ESP32 DevKit fail to boot when GPIO 12 is connected to a relay?

GPIO 12 is a critical strapping pin. During the boot sequence, the ESP32 ROM bootloader reads the state of GPIO 12 to determine the required voltage for the internal SPI flash. If your relay module has an internal pull-up resistor or defaults HIGH during the first 500ms of power-on, the ESP32 configures the flash regulator to 1.8V. Since the WROOM-32 uses 3.3V flash, the chip starves and crashes. The fix: Use GPIO 13, 14, or 27 for relays, or add a 10kΩ pull-down resistor to GPIO 12 if you absolutely must use it.

Can I use 5V sensors directly on the ESP32 DevKit GPIO pins?

No. The ESP32 operates at 3.3V logic (LVCMOS33). While some clones have 5V-tolerant pins due to manufacturing quirks, the official Espressif specification caps GPIO voltage at 3.6V. Feeding 5V into GPIO 34, for example, will forward-bias the internal ESD protection diode, routing 5V directly into the 3.3V VDD rail and potentially frying the entire module. Always use a logic level shifter or a voltage divider for 5V outputs.

Which pins should I use for I2C and SPI by default?

For I2C, the Arduino core defaults to GPIO 21 (SDA) and GPIO 22 (SCL). For VSPI (the primary hardware SPI bus used for SD cards and TFT displays), the defaults are GPIO 18 (SCK), GPIO 19 (MISO), GPIO 23 (MOSI), and GPIO 5 (CS). While you can remap these in software using the GPIO matrix, sticking to the hardware defaults ensures maximum bus speed and frees up CPU cycles.

How do I identify pins on a clone ESP32 board with completely blank headers?

If the silkscreen is missing, orient the board with the USB port facing down and the metal RF shield at the top. The bottom-left pin is almost always EN, and the pin immediately to its right is VP (GPIO 36). The bottom-right pin is typically GND, and the one to its left is VN (GPIO 39). For absolute certainty, use a multimeter in continuity mode to find the GND pins (they will beep when touched to the USB port's metal shell), then count upward using the standard 38-pin WROOM-32 footprint map.