🛠 Lire le bouton BOOT sur GPIO0 sans se piéger
Objectives
Learn how to read a digital input on the ESP32-S3 using the BOOT button (GPIO0), while understanding why this pin is special: GPIO0 is a strapping pin that determines the boot mode (flash or execution). You will write a program that detects button presses with software debouncing, and you will understand the golden rule: never force GPIO0 to a LOW state during power-up, otherwise the board will think you want to flash it.
Hardware
- 1 ESP32-S3 board (the BOOT button is present on all of them: DevKitC-1, XIAO, T-Display-S3)
- 1 USB data cable
- Optional: 1 external push button between GPIO1 and GND for comparison
Complete code
// GPIO0 = bouton BOOT embarque (vers GND), pull-up interne obligatoire
// GPIO1 = bouton externe optionnel, entre GPIO1 et GND
const uint8_t BTN_BOOT = 0;
const uint8_t BTN_EXT = 1;
unsigned long dernierAppui = 0;
const unsigned long ANTI_REBOND = 60; // ms
void setup {
Serial.begin(115200);
pinMode(BTN_BOOT, INPUT_PULLUP);
pinMode(BTN_EXT, INPUT_PULLUP);
}
void loop {
if (digitalRead(BTN_BOOT) == LOW && millis - dernierAppui > ANTI_REBOND) {
dernierAppui = millis;
Serial.println("Bouton BOOT (GPIO0) presse !");
}
if (digitalRead(BTN_EXT) == LOW && millis - dernierAppui > ANTI_REBOND) {
dernierAppui = millis;
Serial.println("Bouton externe (GPIO1) presse !");
}
delay(5);
}
Expected verification
Open the serial monitor at 115200 bauds: each press of the BOOT button prints a single line, without duplicates due to bouncing. The second button (if wired between GPIO1 and GND) behaves identically. The board restarts normally after a reset: GPIO0 was never held LOW during power-up.
Common errors
- Floating input: forgetting INPUT_PULLUP and reading random states; the S3 has internal pull-up/pull-down resistors, use them.
- Wiring a load to GPIO0: if this pin is pulled LOW during power-up, the board enters download mode and appears "dead"; this is the classic pitfall of strapping pins (GPIO0, GPIO3, GPIO45, GPIO46).
- Confusing press and hold: the code above detects the level, not the edge; for strict counting, remember the previous state.
- Debounce too short: below 30 ms, mechanical bouncing creates ghost presses; 50 to 60 ms is a good compromise.
Other tutorials for this board
Code examples for this board
clignotante.inoArduinobouton-led.inoArduinorespiration.inoArduinodht22.inoArduinooled-i2c.inoArduinoserveur-web.inoArduino