P2E-Input-DEBOUNCE-FR

De MCHobby - Wiki
Sauter à la navigation Sauter à la recherche

Introduction

Dans le tutoriel sur les entrées numériques nous avons vu comment détecter la pression d'un bouton.

Ce que ce tutoriel ne nous à pas enseigné, c'est qu'un bouton ne dispose pas de contacts parfait!

Le contact n'est donc pas instantané et présente une série de "rebonds" comme l'indique la capture ci-dessous.

Switchbounce.jpg

Cette période transitoire perdure, tout au plus, 10 millisecondes! Cependant, étant donné la rapidité des microcontrôleurs actuels, 10 millisecondes représente une éternité.

Ainsi, durant cette période transitoire, un microcontrôleur sera capable de détecter plusieurs pressions sur le bouton.

Ce comportement peu avoir des impacts négatifs sur un projet:

  • démarrage/arrêt par à-coups, ce qui peut être néfaste aussi bien électriquement que mécaniquement.
  • incrémenter/décrémenter un compteur de consigne de plusieurs unités en une seule pression.
  • créer des comportements intempestifs et inattendus dans le logiciel.

Ce tutoriel démontrera l'impact des rebonds sur un compteur puis présentera une solution de déparasitage logiciel.

Cas pratique

L'exemple ci-dessous utilise le bouton Btn 1 pour incrémenter un compteur et en afficher la valeur dans la session REPL à l'aide de la fonction print().

Branchement simplifié

Réaliser le branchement entre GP10 et le contact Btn1.
La carte prend en charge les autres détails du raccordement.

Le bouton permet de raccorder la broche sur la masse lorsque celui-ci est pressé.

P2E-digital-input.png

Code sans déparasitage

Le code ci-dessous peut être saisi dans une session REPL ou dans Thonny IDE.

En pressant le bouton, on pourra remarquer que, de temps à autre, le bouton incrémente plusieurs fois le compteur. Cela est causé par un phénomène de rebond.

Cet exemple est également disponible dans le dépôt sous le nom nodebounce.py .

 1 from machine import Pin
 2 
 3 counter = 0
 4 last_counter = 0
 5 
 6 p_in = Pin( 10, Pin.IN, Pin.PULL_UP )
 7 last_state = p_in.value()
 8 while True:
 9     state = p_in.value()
10     if state!=last_state:
11         if state == 0:
12             counter += 1
13         last_state = state
14         continue
15     
16     if counter != last_counter:
17         print( counter )
18         last_counter = counter

Voici quelques explications:

  • Lignes 3 et 4: counter est incrémenté à chaque pression du bouton. last_counter contient la dernière valeur connue du compteur (celle qui a été affichée dans REPL pour la dernière fois).
  • ligne 6: déclaration de p_in, broche en entrée avec résistance pull-up. Quand le bouton est pressé, le signal passe au niveau bas. Quand il est relâché, il passe au niveau haut.
  • Ligne 7: initialisation de last_state, dernier état connu du signal d'entrée.
  • Ligne 8: boucle infinie effectuant une lecture de l'état du bouton, incrémentation du compteur counter et affichage de la valeur.
  • Ligne 9: lecture de l'état sur la broche d'entrée (variable state).
  • Ligne 10: si l'état state à changé depuis le dernier état connu last_state.
  • Lignes 11 et 12: si le nouvel état est un niveau bas (le bouton est pressé) alors nous venons de détecter un flan descendant et le compteur counter est incrémenté de 1 unité.
  • Lignes 13 et 14: mémorisation de l'état state comme dernier état connu last_state. Cela permettra la détection du flan montant lorsque le bouton sera relâché. L'instruction continue redémarre la boucle while immédiatement (le but est ici de maximiser les chances de capturer un rebond).
  • Ligne 16: Celle ligne est exécutée s'il aucun changement d'état a été détecté dans les lignes 9 à 14. Le test vérifie si la valeur du compteur counter a changé depuis le dernier affichage de celui-ci (valeur stockée dans last_counter).
  • Lignes 17 à 18: affichage de la valeur du compteur dans la session REPL -puis- mémorise dans last_counter la dernière valeur envoyée dans REPL.

Un problème?

Pas de multiple comptage en appuyant sur le bouton:

  1. Le bouton est neuf, cela arrive plus rarement. Soyez très attentif pour en pas rater l'occurrence.
  2. N'hésitez pas a faire de nombreuses tentatives.
  3. Essayez de monter un bouton "plus vieux" sur le breadboard. Le matériel ayant déjà servi présente de l'oxydation sur le contact ou une usure de surface (cela améliore les chances de rebonds).


Code avec déparasitage

Pour déparasiter l'entrée, il suffit de revérifier l'état de l'entrée après la période de rebonds.

Donc, lorsque le signal change d'état sur la broche:

  1. attendre 10ms,
  2. relire une 2ieme fois l'état de la broche,
  3. SI ces 2 états sont identiques ALORS il y a bien changement d'état et plus de rebond SINON ignorer (parce qu'on est encore dans une période transitoire.

Ci-dessous, le code correspondant à cette description. Il est également disponible dans le dépôt sous le nom debounce.py .

 1 from machine import Pin
 2 import time
 3 
 4 counter = 0
 5 last_counter = 0
 6 
 7 p_in = Pin( 10, Pin.IN, Pin.PULL_UP )
 8 last_state = p_in.value()
 9 while True:
10     state = p_in.value()
11     if state!=last_state:
12         time.sleep_ms(10)
13         state2 = p_in.value()
14         if state != state2:
15             continue
16         if state == 0:
17             counter += 1
18         last_state = state
19         continue
20     
21     if counter != last_counter:
22         print( counter )
23         last_counter = counter

Voici quelques explications:

  • Ligne 11: détection d'un changement d'état.
  • Ligne 12: pause de 10ms pour attendre la fin des rebonds
  • Ligne 13: relecture de l'état de l'entrée.
  • Lignes 14 et 15: si la seconde lecture d'état est différent de celui lu en ligne 11 (10ms plus tôt) alors nous sommes encore en pleine période de rebond! Il faut redémarrer la détection.



Traduction augmentée réalisée par Meurisse. D pour shop.MCHobby.be - Licence CC-BY-SA.


MCHobby investit du temps et de l'argent dans la réalisation de traduction et/ou documentation. C'est un travail long et fastidieux réalisé dans l'esprit Open-Source... donc gratuit et librement accessible.
SI vous aimez nos traductions et documentations ALORS aidez nous à en produire plus en achetant vos produits chez MCHobby.