The ESP32-WROOM-32 is the workhorse of modern IoT, but its physical carrier boards hide severe I/O traps. Below is the master ESP32 pinout mapping for the standard 30-pin NodeMCU-style DevKit V1, detailing native GPIO, Arduino core aliases, and hardware-level restrictions. If you are using the 38-pin variant or a different software core, see the standard variants section immediately following the table.

The Master ESP32 Pinout Reference Table

This table maps the physical silkscreen on the ubiquitous 30-pin DevKit V1 to the internal Espressif GPIO numbers and the Arduino-ESP32 core aliases. Read the Boot/Strapping and Restrictions columns carefully; ignoring them is the primary cause of boot loops and bricked peripherals.

GPIO # Silkscreen (30-Pin) Arduino Alias Primary Function Boot/Strapping Status Restrictions & Notes
GPIO 0 D0 / 0 0 ADC2_CH1, Touch1 Must be HIGH to boot normal. LOW enters flash mode. Outputs PWM on boot. Do not use for relays.
GPIO 2 D2 / 2 2 ADC2_CH2, Touch2 Must be LOW or floating to boot. Connected to onboard LED. ADC2 conflicts with WiFi.
GPIO 4 D4 / 4 4 ADC2_CH0, Touch0 Safe (No strapping) ADC2 conflicts with WiFi. Safe for general I/O.
GPIO 5 D5 / 5 5 SPI (VSPI SS) Safe (Outputs PWM on boot) Standard Chip Select for SPI displays/SD cards.
GPIO 12 D12 / 12 12 ADC2_CH5, Touch5, MTDI CRITICAL: Must be LOW at boot. If HIGH at boot, selects 1.8V flash. Will brownout 3.3V module.
GPIO 13 D13 / 13 13 ADC2_CH4, Touch4 Safe ADC2 conflicts with WiFi.
GPIO 14 D14 / 14 14 ADC2_CH6, Touch6, SPI CLK Safe (Outputs PWM on boot) Default VSPI SCK pin.
GPIO 15 D15 / 15 15 ADC2_CH3, Touch3, MTDO Safe (Outputs PWM on boot) ADC2 conflicts with WiFi.
GPIO 16 D16 / 16 16 UART2 RX Safe No ADC or Touch. Excellent for pure digital I/O.
GPIO 17 D17 / 17 17 UART2 TX Safe No ADC or Touch. Excellent for pure digital I/O.
GPIO 25 D25 / 25 25 DAC1, ADC2_CH8 Safe True analog output (DAC). ADC2 conflicts with WiFi.
GPIO 26 D26 / 26 26 DAC2, ADC2_CH9 Safe True analog output (DAC). ADC2 conflicts with WiFi.
GPIO 27 D27 / 27 27 ADC2_CH7, Touch7 Safe ADC2 conflicts with WiFi.
GPIO 32 D32 / 32 32 ADC1_CH4, Touch9 Safe Safe for ADC with WiFi active (Uses ADC1).
GPIO 33 D33 / 33 33 ADC1_CH5, Touch8 Safe Safe for ADC with WiFi active (Uses ADC1).
GPIO 34 D34 / 34 34 ADC1_CH6 Safe INPUT ONLY. No internal pull-up/pull-down.
GPIO 35 D35 / 35 35 ADC1_CH7 Safe INPUT ONLY. No internal pull-up/pull-down.
GPIO 36 VP / 36 36 ADC1_CH0 Safe INPUT ONLY. No internal pull-up/pull-down.
GPIO 39 VN / 39 39 ADC1_CH3 Safe INPUT ONLY. No internal pull-up/pull-down.
5V Tolerance Warning: The ESP32-WROOM-32 is a strict 3.3V logic device. While the DevKit V1 board has an onboard 5V-to-3.3V LDO regulator allowing you to power the board via the 5V or VIN pin, none of the GPIO pins are 5V tolerant. Feeding 5V into any GPIO will permanently destroy the silicon. Always use a logic level shifter (like the TXS0108E) or a simple voltage divider when interfacing with 5V sensors like the HC-SR04.

Standard Variants: Physical Carriers and Software Cores

Unlike mains wiring where NEC and IEC dictate regional color codes, the "standards" in the ESP32 ecosystem are split across physical board layouts and software abstraction layers. Misaligning your physical board variant with your software core is the equivalent of wiring a 240V European appliance to a 120V US outlet.

Physical Carrier Variants (30-Pin vs. 38-Pin)

The table above assumes the 30-pin DevKit V1 (commonly manufactured by NodeMCU, HiLetgo, and KeeYees). However, many vendors ship a 38-pin variant. If your board has 38 pins, the physical silkscreen shifts. The 38-pin boards break out GPIO 35, 36, and 39 on the top right, and often duplicate GND and 3V3 pins. The internal ESP32-WROOM-32 module remains identical; only the carrier routing changes. Always count your physical pins and verify the silkscreen against the official Espressif WROOM-32 datasheet before soldering.

Software Core Variants (IDF vs. Arduino vs. MicroPython)

How you call these pins in code depends entirely on your framework:

  • ESP-IDF (Native): Uses strict GPIO_NUM_X macros. You must configure the pin matrix and GPIO matrix manually via the ESP-IDF GPIO API.
  • Arduino-ESP32 Core: Allows you to use the raw integer (e.g., pinMode(2, OUTPUT);) or the D2 alias if defined in your specific board variant file. The Arduino core handles the pin matrix routing under the hood.
  • MicroPython: Uses the machine.Pin class. You must pass the raw integer (e.g., Pin(2, Pin.OUT)). MicroPython does not recognize D2 aliases natively without custom wrapper libraries.

Rows People Get Wrong (And How to Avoid Bricking Your Board)

The ESP32 pinout is notorious for silent failures. Here are the three most common traps that burn out hardware or cause endless boot loops.

1. The GPIO 12 Flash Voltage Trap

GPIO 12 (MTDI) is a strapping pin that dictates the internal flash voltage regulator. On the WROOM-32, the flash runs at 3.3V. If GPIO 12 is pulled HIGH during boot (e.g., you wired a sensor that defaults HIGH, or you attached a pull-up resistor), the ESP32 switches the internal regulator to 1.8V. The 3.3V flash chip will fail to read, resulting in a continuous brownout reset loop. Rule: Never attach external pull-up resistors to GPIO 12, and ensure any connected device defaults to LOW or high-impedance on startup.

2. The ADC2 vs. WiFi Conflict

If you are building a WiFi-connected sensor node and your analogRead() returns 0 or random noise, check your pin choice. The ESP32's WiFi radio shares hardware resources with ADC2. When WiFi is active, ADC2 pins (GPIO 0, 2, 4, 12, 13, 14, 15, 25, 26, 27) are completely disabled for analog reading. Fix: Move all analog sensors to ADC1 pins (GPIO 32, 33, 34, 35, 36, 39), which remain fully functional while WiFi is transmitting.

3. Input-Only Pins Without Pull-ups

GPIO 34, 35, 36, and 39 are physically disconnected from the output driver and the internal pull-up/pull-down resistor matrix. If you wire a simple pushbutton to GPIO 34 and use INPUT_PULLUP in your code, the pin will float wildly, triggering hundreds of false interrupts. You must solder an external 10kΩ pull-up or pull-down resistor to the breadboard when using these four pins.

Safe Interpretation When Silkscreen Markings Fade

Cheap clone boards from bulk marketplace orders frequently suffer from poor QC, resulting in silkscreen text that rubs off after a few weeks of bench use, or boards that ship with no markings at all. If you have an unmarked ESP32 DevKit, do not guess the pinout. Use a digital multimeter (DMM) to map the carrier board safely.

  1. Find Ground (GND): Set your DMM to continuity mode (the diode/beep setting). Place the black probe on the metal shield of the micro-USB port. Probe the header pins with the red probe. Any pin that beeps is GND. You will usually find 3 to 4 GND pins on a 30-pin board.
  2. Find the Power Rails (3V3 and 5V): Power the board via USB. Set the DMM to DC Voltage. Place the black probe on a known GND pin. Probe the remaining pins. You will find exactly one pin reading ~4.8V to 5.1V (this is 5V/VIN) and one or two pins reading exactly 3.3V (this is the 3V3 rail).
  3. Identify EN and BOOT (GPIO 0): With the board unpowered, switch back to continuity or resistance mode. The EN (Enable) pin and GPIO 0 (Boot) pin are both tied to the 3V3 rail via 10kΩ resistors on the carrier board. Probe for a ~10kΩ resistance between the 3V3 pin and the header pins. The two pins that show this resistance are EN and GPIO 0. To distinguish them: EN is usually located physically closer to the 3V3/5V power cluster at the top of the board, while GPIO 0 is grouped with the digital I/O.
  4. Identify TX and RX (GPIO 1 and 3): Power the board and set the DMM to DC Voltage. The UART TX pin (GPIO 1) will pulse or sit at ~3.3V as the bootloader prints to the serial monitor on startup. RX (GPIO 3) will sit near 0V or float slightly until data is sent to it.
Safety Note on Probing: Never use your DMM in current mode (Amps) to probe unknown header pins. If you accidentally bridge 3V3 to GND in current mode, you will blow the multimeter's internal fuse or instantly destroy the ESP32's onboard LDO regulator. Always measure voltage and continuity.

By treating the ESP32 pinout as a strict hardware contract rather than a generic microcontroller layout, you eliminate 90% of the boot failures and peripheral conflicts that plague embedded projects. Map your physical board variant, respect the strapping pins, and always verify your analog channels against the WiFi radio state.