ESP32: the boot button and boot pins, what they actually do
The BOOT button on most ESP32 boards is not a reset button. It puts the chip in download mode. Here is what that means and why you keep needing it.
The first time an ESP32 sketch will not upload, the fix is to hold BOOT, press RESET, release RESET, release BOOT. The second time, you forget which order. The third time, you hold both buttons for the entire upload. The fourth time, you google it again.
This tutorial is the one I wish I had read first. It is what the BOOT button actually does, why some sketches need it and others do not, and the exact sequence to put the chip in download mode without wanting to throw it out the window.
What the BOOT button is
On most ESP32 dev boards, there is a button labeled BOOT or IO0 (they are usually the same thing). It connects GPIO 0 to ground when pressed.
GPIO 0 is a special pin on the ESP32. During reset, the chip checks its state:
- GPIO 0 LOW (button pressed): boot into download mode. The chip waits for new firmware over the serial port.
- GPIO 0 HIGH (button released): boot normally. The chip runs whatever firmware is in flash.
That is the entire job of the BOOT button. It is not a reset button. It is a “tell the chip to listen for new firmware” button. Pressing it does not reset the ESP32; it just holds GPIO 0 low during the next reset.
What the RESET button is
The RESET button (sometimes labeled EN or RST) actually resets the chip. It pulls the EN pin low briefly, which causes a normal restart.
The standard sequence for upload when the auto-upload fails:
- Hold BOOT (GPIO 0 is now LOW).
- Press and release RESET (chip restarts, sees GPIO 0 LOW, enters download mode).
- Release BOOT.
- Click Upload in the IDE.
The ESP32 is now in download mode and the upload will succeed. After the upload, the chip automatically restarts into the new firmware.
Some boards do not have a separate RESET button. The ESP32-S3, for example, has a single button that does both BOOT and RESET. Press it for 1 second, release, then click Upload. Check your board’s pinout.
When you need the manual sequence
The Arduino IDE normally resets the ESP32 automatically before uploading. It uses the serial port’s DTR and RTS pins to do this. On most boards, this works.
It does not work when:
- The USB-serial chip is missing or broken.
- The board’s auto-reset circuit has a wrong resistor value (rare, but common on cheap clones).
- The previous sketch crashed the USB stack so badly that the auto-reset cannot talk to the chip.
- The GPIO 0 pin is being held low by something else (e.g. a button you wired up without thinking about the boot implications).
In all those cases, the manual sequence saves you.
The boot pins you need to know about
The ESP32 has a few pins that do special things during reset. Use them carefully.
| GPIO | During reset | Notes |
|---|---|---|
GPIO 0 | LOW = download mode | The BOOT button pin |
GPIO 2 | Must be floating or LOW | Often has onboard LED; careful with that |
GPIO 12 | Selects flash voltage (LOW = 1.8V, HIGH = 3.3V) | Affects boot behavior; tie high for normal use |
GPIO 15 | Must be HIGH during boot | Often has a pulldown on dev boards; usually OK to use |
The rules for the data pins (GPIO 4, GPIO 5, GPIO 13, etc.) are simpler: avoid them only if you have a specific reason. GPIO 34, 35, 36, 39 are input-only; do not try to drive them as outputs.
If you wire a button or LED to GPIO 2 and it does not work, that is why. GPIO 2 must be in a specific state during reset for the chip to boot normally. Many dev boards put the onboard LED on GPIO 2 because it is convenient; the LED is OK because it is just an LED and does not hold the pin in a weird state.
What happens when an upload fails
When the IDE tries to upload and the ESP32 is not in download mode:
- The IDE sends the “enter download mode” sequence over serial.
- The ESP32 ignores it (it is running user firmware).
- The IDE times out and prints “Failed to connect to ESP32: Timed out waiting for packet header.”
That error message means “the chip is not in download mode.” The fix is almost always the BOOT + RESET sequence.
The exception: ESP32-S2 and ESP32-S3
The newer ESP32 variants have USB-OTG built in. They do not need a USB-serial chip; the USB connector plugs directly into the ESP32.
The download mode procedure is different:
- ESP32-S2: hold BOOT, press RESET, release RESET, release BOOT.
- ESP32-S3: press and hold the single button (it does both BOOT and RESET in one), release after 1 second.
Otherwise the same pattern applies: BOOT during reset = download mode.
How to make the BOOT button useful
On most boards, the BOOT button is on the top side and easy to hit accidentally. A 10-second accidental press can put the chip into a state where your project does not boot.
Two fixes:
- Read the pin before booting up. Add this to
setup():
pinMode(0, INPUT_PULLUP);
if (digitalRead(0) == LOW) {
Serial.println("BOOT held at startup, entering config mode");
// do whatever your config mode does
}
- Disable GPIO 0 as a usable pin in your firmware. Just leave it as the BOOT pin and never wire anything to it. That way an accidental press cannot put your project into a broken state.
What you learned
The BOOT button is GPIO 0 held low during reset, which puts the ESP32 into download mode. The RESET button (or EN) restarts the chip. The manual upload sequence is BOOT + RESET + release BOOT. The boot pins (GPIO 0, GPIO 2, GPIO 12, GPIO 15) do special things at reset, so be careful wiring things to them.
This is one of those tutorials that does not feel important until the day your upload silently fails. Then it is the most important thing you have ever read.
When something breaks
- Upload fails after working yesterday. You changed a pin assignment and started driving GPIO 2 or GPIO 12 weirdly. Check what is wired to those pins.
- The chip will not boot at all. GPIO 0 is stuck LOW (maybe a wire is shorting it to ground, or a button you added is latched). Find and remove the short.
- The chip boots but the sketch does not run. The watchdog is
firing. Add
disableCore0WDT()or extend the timeout. (More on this in a separate tutorial.) - You need to reflash but cannot get into download mode. Some boards have a “flash” or “prog” button that is different from BOOT. Check the silkscreen. Some clones also have weird reset circuits.
What to build next
- The GPIO basics tutorial covers digital read, digital write, and the internal pull-up trick. Most projects start there.
- The deep sleep tutorial uses the boot pins implicitly because it controls what runs after wake-up.