🛠 Bouton poussoir avec anti-rebond
Objectives
Read a push button on PA0 and control the LED on PC13 by toggling its state on each press, filtering mechanical bounce in software (time-based debouncing). You will learn how to configure an input, the active-HIGH logic of a button wired with a pull-down resistor, and the limitations of millis-based debouncing when handling rapid presses.
Hardware
- GD32F103C8T6 / GD32F103CBT6 board compatible with Blue Pill
- Push button between 3.3 V and PA0, with a pull-down resistor to ground (the verified pinout uses PA0; press = HIGH level) >
- On-board LED on PC13 (active-LOW)
- 3.3 V power supply (the circuit operates between 2.6 V and 3.6 V)
Complete Code
// bouton_antirebond.ino — GD32F103C8, core CommunityGD32Cores
#include <Arduino.h>
const uint8_t BTN = PA0; // appui = HIGH (pull-down externe)
const unsigned long DEBOUNCE_MS = 50;
bool etatStable = false; // état filtré du bouton
bool dernierLu = false; // dernière lecture brute
unsigned long dernierChangement = 0;
bool ledAllumee = false;
void setup {
pinMode(BTN, INPUT_PULLDOWN); // pull-down interne : pas obligatoire si R externe
pinMode(PC13, OUTPUT);
digitalWrite(PC13, HIGH); // LED éteinte (active-LOW)
}
void loop {
bool brut = digitalRead(BTN);
unsigned long maintenant = millis;
if (brut != dernierLu) {
dernierChangement = maintenant; // le signal bouge : on repart
dernierLu = brut;
} else if (maintenant - dernierChangement >= DEBOUNCE_MS
&& brut != etatStable) {
etatStable = brut; // état confirmé après 50 ms stables
if (etatStable) { // front montant = appui
ledAllumee = !ledAllumee;
}
}
digitalWrite(PC13, ledAllumee ? LOW : HIGH);
}
Expected Verification
A firm press turns the LED on (if it was off), a second press turns it off, with only one state change per press. When gently shaking the button, the LED should not "flicker": the debouncing is working. You can add a Serial output to count the presses and verify that there are never two counts for a single action.
Common Errors
- Button counting 2 to 5 presses: debouncing is missing or too short; 30 to 50 ms is a good range for a mechanical button.
- Inverted logic: without a pull-down (internal or external), the PA0 input floats and the state changes randomly; add
INPUT_PULLDOWNor a 10 kΩ resistor to ground. - Pin confusion: the verified documentation lists the button on PA0; if your board has its user button on PA1 (classic Blue Pill wiring), adapt the pin. >
millis"overflow": always compare usingnow - lastChange >= Dand notnow >= lastChange + D, which breaks upon overflow after 49 days.- Forgetting the active-LOW LED: writing HIGH to turn the LED on leaves it off.
Other tutorials for this board
Code examples for this board
clignotante.inoArduinobouton-led.inoArduinorespiration.inoArduinopotentiometre.inoArduinopont-uart.inoArduinooled-i2c.inoArduino