logo sheen.bot

← Perspectives

Pourquoi un bouton Arduino enregistre-t-il cinq appuis au lieu d'un seul ?

21 oct. 2026·Sheen Robotics
Pourquoi un bouton Arduino enregistre-t-il cinq appuis au lieu d'un seul ?

Les boutons-poussoirs n'établissent pas un contact parfait : le métal sous tension rebondit physiquement pendant plusieurs millisecondes, générant de multiples transitions sur un microcontrôleur rapide. Voici comment fonctionne le rebond et comment le corriger sans utiliser delay().

Lorsqu'un Arduino enregistre cinq ou six appuis après une simple pression sur un bouton, votre microcontrôleur n'est pas en panne et votre code n'est pas ensorcelé. Le bouton rebondit physiquement. Un bouton-poussoir tactile contient deux fines lamelles métalliques élastiques qui s'entrechoquent lorsqu'on appuie dessus. À l'échelle humaine, le clic semble instantané. À l'échelle d'un microcontrôleur — où un ATmega328P standard à 16 MHz exécute environ seize instructions par microseconde —, les lames de contact entrent en collision, rebondissent, se reconnectent et se stabilisent sur une fenêtre de deux à vingt millisecondes. Pour l'Arduino, ce cliquetis mécanique ressemble à cinq appuis distincts.

Ce à quoi ressemble réellement le rebond mécanique

Dans un circuit classique sur plaque d'essai (breadboard) utilisant une résistance de rappel vers le bas (pull-down) externe ou la résistance de rappel vers le haut interne INPUT_PULLUP, la broche du microcontrôleur surveille une transition de tension entre 0 V et 5 V. Si votre code interroge la broche dans un void loop() rapide à l'aide d'une simple condition :

if (digitalRead(buttonPin) == LOW) {
  pressCount++;
}

deux problèmes distincts surviennent simultanément :

  • Détection de niveau contre détection de front : le code comptabilise un appui à chaque exécution de la boucle tant que le bouton reste enfoncé. Si votre boucle s'exécute en 200 microsecondes, maintenir le bouton enfoncé pendant une demi-seconde comptabilisera 2 500 appuis.
  • Rebond des contacts : même si vous relâchez le commutateur instantanément, la tension oscille entre l'état haut et l'état bas à plusieurs reprises pendant 5 à 15 millisecondes, le temps que les lamelles métalliques se stabilisent. Le processeur est largement assez rapide pour enregistrer chaque rebond individuel comme une transition valide.

Le réflexe classique du débutant consiste à utiliser delay(). Cela fonctionne lors d'un test élémentaire, mais dans n'importe quel projet réel, cela engendre des problèmes bien plus graves que celui qu'il prétend résoudre.

Pourquoi delay(50) dégrade catastrophiquement les performances de votre robot

Si vous ordonnez à l'Arduino d'attendre cinquante millisecondes immédiatement après la détection d'un appui — delay(50); —, le contact a fini de rebondir avant que le microcontrôleur n'interroge à nouveau la broche. Le compteur s'incrémente alors proprement d'une unité.

Cependant, delay() est une fonction bloquante. Elle interrompt totalement le traitement des instructions. Pendant que la puce est bloquée dans cette pause de 50 ms, elle ne peut pas mettre à jour la modulation de largeur d'impulsion (PWM) des moteurs, elle ne peut pas interroger la broche d'écho d'un capteur à ultrasons, elle ne peut pas lire les impulsions d'un encodeur et elle ne peut pas décoder les commandes série entrantes issues d'un ESP32 ou d'un module Bluetooth. Sur un compteur fixe, un délai bloquant passe presque inaperçu. Sur un robot à roues ou une barrière levante automatisée, un gel de 50 ms à chaque déclenchement d'un capteur de fin de course entraîne des repères manqués, des à-coups moteurs et une navigation erratique.

L'anti-rebond matériel — l'ajout d'un condensateur céramique de 100 nF aux bornes du bouton ou l'utilisation d'un filtre passe-bas RC associé à un trigger de Schmitt — nettoie le signal avant qu'il n'atteigne le microcontrôleur. Cette solution est élégante sur le plan électrique, mais elle nécessite du matériel supplémentaire en réserve, encombre la plaque d'essai ou impose des soudures, tout en augmentant le coût des composants dans une classe de 30 élèves. Dans presque tous les contextes scolaires, le suivi d'état logiciel est la réponse appropriée.

La solution propre : détection de front et millis()

Résoudre ce problème proprement dans le code exige deux étapes logiques distinctes : détecter le moment où l'état change (détection de front) et vérifier qu'un délai suffisant s'est écoulé depuis la dernière transition avant d'en valider une nouvelle (temporisation d'anti-rebond).

Cela nécessite trois variables :

  • La lecture actuelle de la broche.
  • La lecture précédente de la broche lors de l'itération passée de la boucle.
  • Une horodate (timestamp) de type unsigned long enregistrant le moment où l'état a changé pour la dernière fois.

Une implémentation robuste et non bloquante se présente ainsi :

const int buttonPin = 2;
int buttonState = HIGH;
int lastButtonState = HIGH;
unsigned long lastDebounceTime = 0;
const unsigned long debounceDelay = 40; // millisecondes
int counter = 0;

void setup() {
  pinMode(buttonPin, INPUT_PULLUP);
  Serial.begin(9600);
}

void loop() {
  int reading = digitalRead(buttonPin);

  // Vérifier si l'état de la broche a changé en raison d'un rebond ou d'un appui physique
  if (reading != lastButtonState) {
    lastDebounceTime = millis();
  }

  // N'évaluer l'état que s'il est resté stable plus longtemps que notre délai de verrouillage
  if ((millis() - lastDebounceTime) > debounceDelay) {
    // Si l'état validé a changé
    if (reading != buttonState) {
      buttonState = reading;
      
      // Déclencher uniquement lors de l'appui (front descendant pour INPUT_PULLUP)
      if (buttonState == LOW) {
        counter++;
        Serial.print("Appuis valides : ");
        Serial.println(counter);
      }
    }
  }

  lastButtonState = reading;
  // Le reste de loop() s'exécute sans interruption ni délai
}

Dans cette architecture, millis() agit comme une horloge non bloquante. Le code inspecte continuellement la broche, réinitialise une horodate de référence dès qu'une oscillation survient, et n'accepte un changement d'état que lorsque la broche reste stable pendant 40 millisecondes consécutives. Le processeur reste disponible à 100 % entre les vérifications pour exécuter des calculs PID ou surveiller des arrêts d'urgence.

Comment enseigner cela au tableau blanc en dix minutes

Les élèves peinent à comprendre l'anti-rebond lorsqu'il est introduit sous la forme d'un mur de structures conditionnelles. Pour l'enseigner efficacement, séparez le fonctionnement mécanique de la syntaxe en vous appuyant sur une analogie simple :

  1. La porte qui claque : dessinez une lourde porte en bois qui claque. Elle ne s'immobilise pas net contre le chambranle ; elle vibre dans la gâche pendant une fraction de seconde. Expliquez qu'un bouton-poussoir est constitué de ressorts en laiton ou en acier qui font exactement la même chose.
  2. L'agent de sécurité ultra-rapide : demandez à la classe : « Si un agent de sécurité compte chaque personne qui franchit une porte et ne cligne des yeux qu'une fois toutes les cinq minutes, que se passe-t-il ? » Il rate du monde. « Et si l'agent pouvait vérifier la porte seize mille fois par seconde ? » Il compterait chaque infime vibration du loquet comme l'entrée d'une nouvelle personne. C'est exactement ce que fait un Arduino exécutant digitalRead().
  3. État ou front : écrivez les mots « EST » et « DEVIENT » au tableau. Montrez-leur que leur premier code demandait : « Le bouton est-il enfoncé ? » (Vrai pendant 200 000 cycles). Le nouveau code doit demander : « Vient-il de devenir enfoncé ? »
  4. La règle des 40 ms : expliquez qu'au lieu de fermer les yeux (delay), l'agent regarde sa montre (millis). Si la porte vibre, on réinitialise un court minuteur de 40 millisecondes. On ne note un visiteur que lorsque la porte est restée parfaitement immobile pendant quarante battements.

Si vous équipez un laboratoire scolaire ou si vous introduisez l'informatique physique en classe de Senior Phase, des packs pédagogiques structurés et des kits de composants validés sont disponibles sur la boutique Sheen Robotics, spécialement conçus pour éliminer les composants de prototypage peu fiables qui compliquent inutilement le dépannage mécanique.

Dès lors que les élèves comprennent que les commutateurs sont des dispositifs mécaniques imparfaits interagissant avec des ordinateurs ultra-rapides, l'anti-rebond cesse de ressembler à un bug logiciel mystérieux et devient leur première véritable leçon d'ingénierie des systèmes embarqués.

#arduino#électronique#robotique#programmation#enseignement

Plus de Perspectives