A push button is the simplest input, but on the C3 the pin choice matters more than usual: three of the SuperMini’s pins are strapping pins, and one of them already has the BOOT button on it.
Wire the button between GPIO4 and GND and let the internal pull-up do the rest. The sketch counts debounced presses and also accepts the on-board BOOT button, which is handy for a SuperMini sealed in a box.
Wiring
| ESP32-C3 SuperMini | Push button (6 mm tactile switch) | Wire | Notes |
|---|---|---|---|
| 4 | 1 | yellow | Internal pull-up: idle HIGH, pressed LOW. |
| GND | 2 | black | Use diagonal legs on a 4-leg tactile switch. |
No supply — passive switch part, 3.3 V board. Wire the button between a GPIO and GND and use the internal pull-up. Never connect a button between a GPIO and 5 V on a 3.3 V board.
Board quirks
- Never wire a button to GND on GPIO2, GPIO8 or GPIO9. If it is pressed during reset the C3 boots wrongly — GPIO9 LOW at reset is exactly how the BOOT button enters download mode.
- The BOOT button itself is free to use once your sketch is running: the sketch reads it on GPIO9 alongside the external button.
- No external resistor needed:
INPUT_PULLUPenables the C3’s internal pull-up (about 45 kΩ). On long wires add a 10 kΩ external pull-up to 3V3. - The sketch debounces in software (30 ms) and lights the SuperMini’s LED (GPIO8, LOW = on) while the button is held.
Code
// Push button on an ESP32-C3 SuperMini — external button on GPIO4, plus the on-board BOOT button.
// Button leg 1 → GPIO4, leg 2 → GND. The internal pull-up holds GPIO4 HIGH; pressed = LOW.
// The BOOT button on GPIO9 can be read too once the sketch is running (pressed = LOW),
// but never hold it during reset — that is how you enter download mode.
constexpr uint8_t BUTTON_PIN = 4;
constexpr uint8_t BOOT_BTN = 9; // the core also calls this BOOT_PIN
constexpr uint8_t LED_PIN = 8; // on-board blue LED, inverted (LOW = on)
bool lastStable = HIGH, lastRead = HIGH;
uint32_t changedAt = 0;
uint32_t presses = 0;
void setup() {
Serial.begin(115200);
delay(1500); // let the native USB serial port enumerate
pinMode(BUTTON_PIN, INPUT_PULLUP);
pinMode(BOOT_BTN, INPUT_PULLUP);
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, HIGH);
Serial.println("Press the button on GPIO4 (or BOOT)");
}
void loop() {
bool r = digitalRead(BUTTON_PIN) && digitalRead(BOOT_BTN); // either button pressed → LOW
if (r != lastRead) {
lastRead = r;
changedAt = millis();
}
if (millis() - changedAt > 30 && r != lastStable) { // 30 ms debounce
lastStable = r;
if (r == LOW) Serial.printf("Pressed (%lu)\n", (unsigned long)++presses);
digitalWrite(LED_PIN, r); // LED on while held
}
}// Push button on an ESP32-C3 SuperMini — external button on GPIO4, plus the on-board BOOT button.
// Button leg 1 → GPIO4, leg 2 → GND. The internal pull-up holds GPIO4 HIGH; pressed = LOW.
// The BOOT button on GPIO9 can be read too once the sketch is running (pressed = LOW),
// but never hold it during reset — that is how you enter download mode.
constexpr uint8_t BUTTON_PIN = 4;
constexpr uint8_t BOOT_BTN = 9; // the core also calls this BOOT_PIN
constexpr uint8_t LED_PIN = 8; // on-board blue LED, inverted (LOW = on)
bool lastStable = HIGH, lastRead = HIGH;
uint32_t changedAt = 0;
uint32_t presses = 0;
void setup() {
Serial.begin(115200);
delay(1500); // let the native USB serial port enumerate
pinMode(BUTTON_PIN, INPUT_PULLUP);
pinMode(BOOT_BTN, INPUT_PULLUP);
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, HIGH);
Serial.println("Press the button on GPIO4 (or BOOT)");
}
void loop() {
bool r = digitalRead(BUTTON_PIN) && digitalRead(BOOT_BTN); // either button pressed → LOW
if (r != lastRead) {
lastRead = r;
changedAt = millis();
}
if (millis() - changedAt > 30 && r != lastStable) { // 30 ms debounce
lastStable = r;
if (r == LOW) Serial.printf("Pressed (%lu)\n", (unsigned long)++presses);
digitalWrite(LED_PIN, r); // LED on while held
}
}Expected serial output
Press the button on GPIO4 (or BOOT)
Pressed (1)
Pressed (2)
Pressed (3)Press the button on GPIO4 (or BOOT) Pressed (1) Pressed (2) Pressed (3)
Common errors
One press counts as several
Contact bounce. Increase the 30 ms debounce time.
Board goes into download mode when powered with the button held
The button is on GPIO9 (or 8/2). Move it to GPIO4 or another non-strapping pin.