3.11. Anti-rebond¶
Un interrupteur est représenté comme un contact parfait, ouvert ou fermé, mais les contacts d’un interrupteur réel ne basculent pas proprement entre les deux états. Ils rebondissent – établissent et rompent le contact électrique plusieurs fois en quelques millisecondes avant de se stabiliser. Une entrée GPIO qui lit la broche perçoit cela comme une rafale de fronts ; une boucle de scrutation négligente compte plusieurs « appuis » pour un seul appui réel, et un gestionnaire d’interruption s’exécute plusieurs fois par appui effectif.
Un interrupteur qui rebondit produit une rafale de transitions rapides avant de se stabiliser.¶
L”anti-rebond est la pratique consistant à filtrer ces rebonds afin que chaque appui physique soit enregistré comme un événement unique. Deux approches résolvent ce problème – logicielle (une règle temporelle dans le micrologiciel) ou matérielle (un petit filtre sur le fil). Elles ne s’excluent pas mutuellement.
3.11.1. Anti-rebond logiciel¶
L’idée consiste à mémoriser le moment où l’entrée a changé pour la dernière fois et à rejeter tout changement ultérieur survenant dans une courte fenêtre suivant cet horodatage. Le rebond des contacts dure généralement moins de 10 ms ; un appui réel prend 50 – 100 ms ; une fenêtre de 30 – 50 ms capture tous les rebonds sans bloquer les appuis réels.
Dans une boucle de scrutation, lisez la broche, comparez-la à la dernière valeur stable, et n’acceptez un changement qu’une fois la fenêtre d’anti-rebond écoulée :
import time
from machine import Pin
button = Pin("P0", Pin.IN, Pin.PULL_UP)
last_state = 1
last_change = 0
DEBOUNCE_MS = 50
while True:
now = time.ticks_ms()
state = button.value()
if state != last_state and time.ticks_diff(now, last_change) > DEBOUNCE_MS:
last_change = now
last_state = state
if state == 0:
do_action()
time.sleep_ms(10)
Pour les lectures pilotées par interruption, appliquez la même règle temporelle à l’intérieur du gestionnaire, puis transmettez l’appui réel au contexte principal via micropython.schedule() (voir Entrée GPIO) :
import time
import micropython
from machine import Pin
button = Pin("P0", Pin.IN, Pin.PULL_UP)
last_irq = 0
DEBOUNCE_MS = 50
def handle_press(pin):
do_action()
def on_press(pin):
global last_irq
now = time.ticks_ms()
if time.ticks_diff(now, last_irq) < DEBOUNCE_MS:
return
last_irq = now
micropython.schedule(handle_press, pin)
button.irq(handler=on_press, trigger=Pin.IRQ_FALLING)
L’ISR filtre les rebonds par horodatage et met la fonction de rappel en file d’attente ; handle_press s’exécute de nouveau dans le contexte principal, où l’allocation et les E/S lentes sont sûres.
3.11.2. Anti-rebond matériel¶
L’anti-rebond matériel filtre les rebonds électriquement, avant même qu’ils n’atteignent la broche. L’outil standard est un condensateur.
Un condensateur est un composant à deux bornes qui stocke une charge électrique. Physiquement, il s’agit de deux plaques conductrices maintenues à faible distance l’une de l’autre, séparées par un isolant (le diélectrique).
Un condensateur à plaques parallèles : deux conducteurs séparés par une couche isolante.¶
L’application d’une tension à ses bornes provoque l’accumulation de charges égales et opposées sur les deux plaques ; la relation est
Q = C × V
où Q est la charge stockée (coulombs), V est la tension aux bornes du condensateur, et C est sa capacité (farads). La capacité est fixée par la construction du composant ; une capacité plus élevée signifie davantage de charge stockée à tension égale.
La conséquence : un condensateur ne peut pas changer sa tension instantanément. La charge qui entre ou sort doit traverser la résistance présente sur le trajet, et cette résistance détermine la vitesse à laquelle la tension peut varier.
3.11.2.1. Constante de temps RC¶
Charger un condensateur à travers une résistance produit une montée exponentielle progressive vers la tension d’alimentation, et non un échelon. Le temps caractéristique de cette montée est la constante de temps RC :
τ = R × C
Au bout d’un τ, le condensateur a atteint environ 63 % de la tension d’alimentation. Au bout de 5 τ, il dépasse 99 % – « complètement chargé » en pratique.
Un condensateur se charge le long d’une courbe exponentielle. τ = RC est le temps nécessaire pour atteindre 63 % de la tension finale.¶
La décharge à travers une résistance suit l’image miroir : la tension décroît exponentiellement depuis sa valeur initiale vers zéro, tombant à 37 % de la tension de départ au bout d’un τ, et à moins de 1 % au bout de 5 τ.
Un condensateur se décharge le long d’une décroissance exponentielle. τ = RC est le temps nécessaire pour tomber à 37 % de la tension de départ.¶
3.11.2.2. Le circuit d’anti-rebond¶
Un condensateur placé entre une broche d’entrée et la masse, alimenté à travers une résistance série, forme un filtre passe-bas. Les pics rapides n’ont pas le temps de charger ou décharger le condensateur à travers cette résistance ; la broche reste proche de la tension à laquelle elle se trouvait avant le pic. Les changements lents – un appui délibéré – chargent ou déchargent le condensateur et la lecture suit.
R1 tire le côté haut de l’interrupteur vers Vcc, produisant un signal d’interrupteur brut qui rebondit. R2 et C filtrent ensuite ce signal en passe-bas vers la broche :
Anti-rebond matériel : R2 et C filtrent en passe-bas le signal brut de l’interrupteur avant qu’il n’atteigne la broche.¶
Valeurs typiques : R1 = 10 kΩ (tirage), R2 = 10 kΩ (série), C = 100 nF.
Lorsque l’interrupteur est ouvert, le courant circule Vcc → R1 → R2 → condensateur (en série), chargeant le condensateur à Vcc avec τ_charge = (R1 + R2) × C = 2 ms.
Lorsque l’interrupteur se ferme, le nœud de l’interrupteur est ramené à la masse et le condensateur se décharge à travers R2 seul vers cette masse avec τ_discharge = R2 × C = 1 ms.
Les deux fronts sont filtrés par le RC. Comme le condensateur se trouve sur son propre nœud, en aval de R2 par rapport à l’interrupteur, il oscille proprement entre Vcc (ouvert) et 0 V (fermé) – aucun courant n’a à circuler à travers R1 en régime permanent dans l’un ou l’autre cas.
3.11.3. Choisir entre les deux¶
Le logiciel est l’option par défaut. Il ne coûte rien en composants, le seuil est facile à régler, et il fonctionne sur n’importe quelle broche lue par le CPU.
Le matériel vaut la dépense en composants lorsque le rebond atteint autre chose que le code de scrutation du CPU – une interruption qui ne doit pas se déclencher deux fois, un compteur matériel, un périphérique dépourvu de son propre filtre.
L’anti-rebond logiciel et matériel coexistent également en bonne entente : un petit filtre RC supprime les pics les plus marqués, et une fenêtre d’anti-rebond logiciel couvre ce qui reste.