🛠 Multitâche non bloquant : heartbeat + bouton avec debounce
Objectifs
Sortir du séquentiel delay : exécuter deux tâches indépendantes dans loop grâce à millis — un battement de LED à 500 ms et un bouton avec anti-rebond logiciel à 30 ms. C'est la compétence qui sépare le débutant de l'intermédiaire sur microcontrôleur nu (pas d'OS sur l'UNO, juste un bootloader).
Matériel
- 1 Arduino UNO R3 + câble USB-B
- 1 bouton poussoir entre la pin 2 et GND (pull-up interne)
- 1 LED + 330 Ω sur la pin 13 (ou la LED intégrée « L »)
Code complet
// Deux tâches sans delay : heartbeat 500 ms + toggle par bouton (debounce 30 ms).
const uint8_t LED = 13;
const uint8_t BTN = 2;
bool ledOn = false;
bool dernierEtatBtn = HIGH;
uint32_t dernierBlink = 0, dernierChangementBtn = 0;
void setup {
pinMode(LED, OUTPUT);
pinMode(BTN, INPUT_PULLUP);
Serial.begin(9600);
}
void loop {
uint32_t maintenant = millis;
// Tâche 1 : heartbeat non bloquant.
if (maintenant - dernierBlink >= 500) {
dernierBlink = maintenant;
digitalWrite(LED, !digitalRead(LED));
}
// Tâche 2 : bouton avec anti-rebond de 30 ms, front d'appui.
bool btn = digitalRead(BTN);
if (btn != dernierEtatBtn && maintenant - dernierChangementBtn >= 30) {
dernierChangementBtn = maintenant;
dernierEtatBtn = btn;
if (btn == LOW) { // appuyé (actif-bas)
ledOn = !ledOn;
Serial.print(F("toggle -> ")); Serial.println(ledOn);
}
}
digitalWrite(LED, ledOn ? HIGH : LOW);
}
Vérification attendue
La LED pulse en continu ; chaque appui (un seul, même si le bouton claque) bascule l'état affiché dans le Moniteur série. Testez la différence : sans la fenêtre de 30 ms, un appui unique déclenche 3 à 10 toggles visibles dans le Moniteur — le rebond mécanique est réel.
Erreurs fréquentes
- Comparaison millis < précédent : le débordement de millis arrive après ~50 jours ; la soustraction non signée (maintenant - précédent >= X) est la seule forme correcte.
- Mettre à jour le timestamp seulement quand l'état est stable : la fenêtre de debounce ne se referme jamais.
- Mélanger le flag ledOn et le heartbeat sur la même LED sans comprendre qui écrit en dernier (ici digitalWrite final gagne).
- Vouloir « vraiment » du multitâche : au-delà de quelques tâches, regardez le port officiel FreeRTOS AVR plutôt que d'empiler des if millis.
- Oublier que loop doit rester court : aucun calcul long (capteur 1-Wire, attente I²C) ne doit bloquer le heartbeat.
Autres tutoriels pour cette carte
Exemples de code pour cette carte
clignotante.inoArduinobouton-poussoir.inoArduinopwm-fade.inoArduinocapteur-lumiere-ldr.inoArduinoservo-balayage.inoArduinoruban-neopixel.inoArduino