ESP32 Deep Dive · #14 of 52

ESP32 Pins: Strapping Pins, Input-Only, Boot Traps

Reset-Time Ownership, Module Constraints, and Pin Assignments That Survive Layout

An ESP32-WROOM-32 development board.
A development board makes the ESP32 approachable, but the header labels hide reset-time, programming and module-level constraints. · Ubahnverleih, CC0

The robot hand team has outgrown jumper wires. They are making a small controller PCB around an ESP32 module. The firmware already works on a dev board, so the first draft of the schematic feels easy: copy the GPIO numbers from the prototype and route them to sensors, buttons, LEDs, motor enables and a debug connector.

Then the first board arrives. It programs once, boots sometimes, and refuses to start when a limit switch is held. The bug is not in the application. It happened before the application had a chance to run.

An ESP32 pin is not just a numbered solder pad. It may be a boot-mode input during reset, a flash-memory bus line inside the module, a UART console pin during download, an ADC input during measurement, a wake source during sleep, or an ordinary GPIO only after all of that is finished. The craft is to decide who owns the pin at each moment.

By the end, you can

  1. Separate a microcontroller GPIO number from the module pad and the development-board header
  2. Explain why strapping pins can change boot mode before firmware starts
  3. Avoid flash-bus pads, console pins and boot pins unless the schematic explicitly allows the use
  4. Use GPIO34-39 as inputs only, with external bias when the signal needs a defined idle state
  5. Build a pin-assignment table that records reset state, runtime function, sleep behavior and fallback debug access
  6. Power-cycle a design in worst-case external states to prove it still boots

The pin number is the last thing you choose

When a schematic says GPIO25, it is tempting to treat that as a free software constant. In reality, the physical path has layers:

  1. The silicon pad inside the ESP32.
  2. The module routing from silicon to package edge.
  3. Any flash, antenna, crystal or RF constraints inside the module.
  4. The carrier board's USB bridge, buttons, LEDs, pull resistors and headers.
  5. The product circuit attached to the pin.
A stylized ESP32 board with pin groups color-coded by risk: flexible GPIO, boot straps, input-only pins, flash pins, and UART0 console pins.
Do not start pin planning by asking what numbers are free. Start by asking which pins are already owned at reset, boot, programming, runtime and sleep. · TooFoo original SVG

The exact list changes across ESP32, ESP32-S2, ESP32-S3, ESP32-C3 and board variants. This lesson uses the classic ESP32-WROOM family as the mental model because it is common and full of teachable traps. For a product, the final authority is the module datasheet and the development board or carrier-board schematic.

Close-up photo of an Espressif ESP-WROOM-32 module.
A module is not bare silicon. It already contains RF layout, flash memory, shielding choices and edge pads with constraints. · Brian Krent, CC BY-SA 4.0

The module view matters because several pins are not available in the way a bare microcontroller table suggests. On common ESP32-WROOM modules, the SPI flash is already connected. Pins used by that flash bus are not a place for your status LED, button or sensor. They may appear in a datasheet table, but the module has already spent them.

An ESP32 development board mounted above a breadboard.
A dev board adds another ownership layer: regulator, USB bridge, boot/reset buttons, pull resistors and sometimes LEDs. · Edwiyanto, CC BY-SA 4.0

You copied a working ESP32 dev-board prototype to a custom PCB. Which document should settle whether a GPIO is truly available?

Reset time belongs to the boot ROM

Before your firmware starts, the ESP32 has to decide how to boot. It samples a small set of strapping pins during reset release. Those sampled levels tell the chip things such as normal boot versus serial download mode and, on older module combinations, flash-voltage selection.

Timeline showing reset held, reset released, strapping pin sampling, and firmware startup.
Firmware can reconfigure a pad later, but it cannot rewrite the boot decision that happened while reset was being released. · TooFoo original SVG

This is why a button on the wrong pin can make a board fail only in a very specific human state. A bench test that power-cycles the board with no buttons held might pass. The same board can fail in the product when a user holds a button while inserting a battery, or when a sensor output is low during a cold start.

Front side of an ESP32-WROOM-32 module with the RF shield can visible.
The shield can hides the silicon, but it does not hide the reset rules. The carrier board must respect the module's required strap states. · Ubahnverleih, CC0

GPIO0 is the most famous example. On many ESP32 boards, pulling GPIO0 low during reset selects the serial bootloader. That is useful when you intentionally press a BOOT button to program the chip. It is a trap when a product button or external circuit can hold the same pin low during power-up.

GPIO12 is the scarier classic trap. On many ESP32 modules, its reset-time level can affect flash-voltage configuration. A board that accidentally pulls it high can look dead because the CPU is trying to boot from flash under the wrong electrical condition.

Back side of an ESP32-WROOM-32 module.
The back of the module is a reminder that the easy header view is only one side of the actual electrical object. · Ubahnverleih, CC0
Practice 1 warm-up

A product button pulls GPIO0 to ground when pressed. The firmware plans to use the button only after boot. What failure can happen if the user holds the button while inserting the battery?

Show worked solution

The chip can sample GPIO0 low at reset and enter serial download mode instead of normal firmware. The fix is not a firmware delay; the reset-time circuit must be changed or the button moved to a pin that is not a boot strap.

Input-only pins are not almost-outputs

GPIO34 through GPIO39 on classic ESP32 are useful, but they are only inputs. They cannot drive an LED, MOSFET gate, enable pin, chip select or bus line. They also do not provide the internal pull-up and pull-down resistors many beginner examples rely on.

Circuit diagram showing GPIO34 used as an input with an external pull-up resistor and a switch to ground.
An input-only pin can be a clean button or sensor input, but the board must provide the bias network when the signal needs a defined idle state. · TooFoo original SVG

This distinction is easy to miss because a firmware API may let you write code that looks symmetrical:

pinMode(34, INPUT) feels like the same kind of statement as pinMode(25, OUTPUT).

Electrically, they are different promises. GPIO34 can observe. GPIO25 can observe and drive. If your schematic needs a line to source or sink current, do not assign it to an input-only pad.

Close-up of castellated holes on an ESP32-WROOM module edge.
Each castellated edge pad is a physical contract. The pin table tells you what the pad can actually do. · Ubahnverleih, CC0

Input-only pins are still excellent for the right jobs: battery voltage sense through a divider, an analog sensor output, a wake input with an external pull, or a read-only fault line from another device. They become bad pins when the schematic secretly asks them to drive.

Use a pin planner before layout

The planner below is not a substitute for a datasheet. It is a habit-building filter: choose a pin, choose the intended job, state the reset pull, and mark whether the external circuit can drive the net while reset is active.

review result

A reasonable first choice after checking the exact board schematic.

    Try these moves:

    1. Choose GPIO25 as an output. It should look like a reasonable first choice.
    2. Change the pin to GPIO34 while keeping the use as output or PWM. The result should become a hard rejection.
    3. Choose GPIO0, set the reset pull to down, and mark the external circuit active at reset. That is the bootloader trap.
    4. Choose GPIO12, set the reset pull to up, and mark the external circuit active at reset. That is the flash-voltage trap.
    5. Choose GPIO34 as analog with an external pull. That is a reasonable read-only use.
    An ESP32-C3 board with GPIO labels visible next to a small traffic-light module.
    Labels are useful, but they are the beginning of pin planning, not the end. Variants such as ESP32-C3 do not share every classic ESP32 constraint. · DavesCodeMusings, CC0

    Which pin assignment deserves the strongest objection?

    The assignment table is part of the design

    For a serious board, the pin assignment table should exist before the PCB is routed. It is not paperwork. It is a way to catch conflicts while they are still cheap.

    For each signal, record:

    1. GPIO number and physical module pad.
    2. Runtime function: input, output, ADC, I2C, SPI, UART, PWM, wake source.
    3. Reset state: floating, pulled up, pulled down, driven by another IC, or connected to a button.
    4. Boot role: strap, console, flash bus, ordinary GPIO, or variant-specific special function.
    5. Sleep role: wake source, retained state, high impedance, or powered-off external circuit.
    6. Fallback plan: how the board can still be programmed and debugged if firmware is broken.
    A pin-assignment table showing signal name, GPIO, reset state, boot owner, runtime function and fallback.
    A pin table catches conflicts that a neat schematic page can hide. Reset state and fallback access belong beside the runtime function. · TooFoo original SVG

    The fallback plan matters more than it sounds. If you spend UART0 pins on unrelated signals and remove the auto-program circuit, a board can become hard to recover after one bad firmware image. If you put a high-current load on a strap pin, the boot state can depend on whether an external device is powered first. If you choose input-only pins for a bus, the compiler may not save you before the PCB is manufactured.

    A practical ESP32 pin-review loop

    Read the module datasheet, the board schematic, and the silicon technical reference in that order. Mark flash pins and strap pins in red. Mark console/programming pins in a different color. Reserve clean general-purpose pins for signals that must drive loads. Then run the physical test: power-cycle the actual board while every external signal is forced into its worst reset-time state.

    Key takeaways

    • A GPIO assignment is a timing question: reset, boot ROM, firmware, sleep and debug can all care about the same pad.
    • Strapping pins are sampled before your code runs, so firmware cannot fix a bad reset-time circuit.
    • GPIO34-39 are useful input and ADC pins, but they cannot drive and they need external bias when a defined idle state matters.
    • Flash-bus pins and console pins may appear in tables, but the module or board may already own them.
    • A pin-assignment table and worst-case power-cycle test are cheaper than a PCB respin.

    The lesson is not "never use special pins." Engineers use special pins all the time. The lesson is to stop pretending all pin numbers are equal. A good ESP32 schematic knows which pins are safe, which pins are conditional, and which pins are already spoken for before the first line of user firmware executes.

    full glossary →