Build log · ESP32
Half your ESP32 pins have a second job
The ESP32 microcontroller has ~30 GPIOs. Maybe 15 of them are actually "free."
The rest have a second job at boot. GPIO0, GPIO2, GPIO5, GPIO12 and GPIO15 (on the original ESP32; other variants use different pins) get sampled the instant the chip powers up, to decide things like boot mode and flash voltage.
Wire the wrong LED or button to one of these and you don't get a bug. You get a board that boots fine 95% of the time and refuses to start the other 5%, for no reason anyone on the bench can see.
How I found out
I hit this on a recent build: a set of nodes sampling individual solar panel floating voltages and reporting each panel's output over ESP-NOW to a central node. I put a status LED on GPIO2, and on certain power-on sequences the board wouldn't boot at all.
I moved it two pins over, and the problem vanished.
The fix
The fix is boring but effective. Before you assign a single GPIO, not after the board comes back from fab, map out:
- Every strapping pin: the ones sampled at power-up.
- Every flash-bus pin: the ones already wired to the flash chip.
- The ADC1/ADC2 split: ADC2 shares hardware with Wi-Fi and goes unreliable the second the radio's active. ESP-NOW counts as the radio being active.
- Strapping, avoid or use with care
- GPIO 0, 2, 5, 12, 15
- Flash bus, don't use
- GPIO 6–11
- Input only, no pull-ups
- GPIO 34–39
- ADC2, not with Wi-Fi or ESP-NOW
- GPIO 0, 2, 4, 12–15, 25–27
- ADC1, safe with the radio on
- GPIO 32–39
S3, C3, C5 and C6 chips use different pins. The ESP32 pin planner checks all five for you and writes the MicroPython pin map.
Cheap lesson to learn on a schematic.
Expensive one to learn on a shipped batch.
Bullet dodged… 😉