Boards · 7 min read

ESP32 GPIO Pinout: Which Pins Are Actually Safe to Use?

The DevKitC exposes 30-odd pins and roughly a third of them have traps: pins that brick your boot, pins wired to the flash chip, pins that can only listen. This is the map we wish someone had handed us first.

In short

Safe for almost anything: GPIO 4, 16, 17, 18, 19, 21, 22, 23, 25, 26, 27, 32, 33. Input-only (no internal pull-ups): 34, 35, 36, 39. Handle with care (boot strapping): 0, 2, 5, 12, 15. Never touch: 6–11 (connected to the SPI flash — using them crashes the chip) and 1, 3 (USB serial).

The full traffic-light table (DevKitC V4)

GPIO Verdict Why
4, 16, 17, 18, 19, 21, 22, 23, 25, 26, 27, 32, 33 🟢 Safe Free pins. 21/22 double as the default I2C bus (SDA/SCL), 18/19/23 as SPI.
34, 35, 36, 39 🟡 Input only Great for sensors and buttons, but no output drive and no internal pull-up/down — add a physical 10kΩ resistor.
0, 2, 5, 12, 15 🟠 Strapping pins Their level at boot configures the chip. Fine to use after boot if your circuit doesn’t force them high/low at power-on.
1, 3 🔴 Avoid UART0 TX/RX — wired to the USB bridge. Use them and serial monitor / flashing breaks.
6, 7, 8, 9, 10, 11 🔴 Never Connected to the internal SPI flash. Driving them = instant crash, every boot.
13, 14 🟢 Mostly safe Free, but 14 and 15 emit brief PWM noise at boot — irrelevant for LEDs, annoying for servos.

Why strapping pins bite beginners

The classic failure: a button wired between GPIO 0 and GND looks innocent — but if that button is pressed (or your sensor holds the line low) while the board boots, the ESP32 enters flashing mode instead of running your sketch. “My program doesn’t start unless I unplug the sensor” is the signature. GPIO 12 is sneakier: pulled high at boot on some boards, it sets the flash voltage wrong and the chip won’t run at all.

The fix is rarely a circuit change — just move the offending wire to a green pin and keep strapping pins for things that are high-impedance at boot. Our Blink LED example walks through this gotcha live in the simulator, where you can watch it happen without risking a real board.

The 60-second pin check

  1. Is it on the green list? Use it. Done.
  2. Is it 34–39? Input only, and budget a physical pull-up resistor.
  3. Is it a strapping pin? Ask: “does anything force this pin’s level at power-on?” If yes, pick another pin.
  4. Analog? Use ADC1 pins (32–39) — ADC2 (0, 2, 15, 13, 12…) is unusable while Wi-Fi is on.
// Safe defaults on a DevKitC:
#define PIN_BUTTON   4   // green pin, has internal pull-up
#define PIN_SENSOR   34  // input-only, add external 10k pull-up
#define PIN_I2C_SDA  21  // the standard I2C pair
#define PIN_I2C_SCL  22
#define PIN_LED      2   // strapping pin — OK here, nothing drives it at boot

See the pins, don’t just read about them

Reading pin behavior off a datasheet works until it doesn’t — the day you need to watch eight lines during boot, you want a logic analyzer. Our Logic Analyzer Rig captures 8 channels at 24MHz into the ESP32 and decodes live in your browser, which is exactly the tool for “what is this pin actually doing at power-on.”

More in the Knowledge Base: ESP32 vs S3 vs C3 · BME280 Wiring & Code · All guides →