This applies to the original ESP32. Other variants have different pin maps; use the GPIO page for your chip (linked in the sources).
Symptoms
- Board doesn't boot, or only boots when a sensor is unplugged.
- Crashes or flash errors as soon as a certain GPIO is touched.
- A pin configured as output does nothing; internal pull-up "doesn't work".
analogRead()returns garbage or fails once Wi-Fi is connected.
The pins
| Pins | Why they're special | Rule |
|---|---|---|
| GPIO0, 2, 5, 12, 15 | strapping pins: sampled at reset to choose boot mode and other settings | don't let external circuits pull them to the wrong level at boot; avoid for buttons/sensors with pull-ups/downs unless you know the required level |
| GPIO6–11, 16–17 | usually wired to the module's SPI flash and PSRAM | don't use |
| GPIO34–39 | input-only, no software pull-up/pull-down | inputs only, add external resistors |
| GPIO1, 3 | UART0 TX/RX, used for flashing and the serial console | avoid unless you give up serial logs |
| GPIO12–15 | JTAG | avoid if you debug over JTAG |
| ADC2 pins | ADC2 is shared with the Wi-Fi driver and cannot be used while Wi-Fi is active | use ADC1 channels for analog inputs in Wi-Fi projects |
GPIO12 deserves special mention: it is a strapping pin that selects flash voltage on many modules. A pull-up on GPIO12 at boot is a classic cause of boot loops. Keep it free or low at reset.
Checklist before routing a PCB
- Put buttons, relays and sensors on "boring" GPIOs first.
- Analog sensors on ADC1 only if Wi-Fi is used.
- Anything with a pull-up or pull-down on a strapping pin: check the boot-mode table in the datasheet.
- Keep GPIO0 accessible (BOOT button) for recovering a board that won't flash.