Plus facile à lire avec un fond crème, une teinte, plus de contraste ou un texte plus grand ? Choisissez vos couleurs et votre texte, une fois pour toutes les pages.

Leçon gratuite

Scrutation ou interruption : lire un bouton

Après cette leçon: Je peux expliquer la scrutation et l’interruption, et filtrer le rebond d’un bouton.

Leçon de 60 min2 commandesLab de systèmes embarqués : registres, broches, PWM et interruptions sur une puce simulée

Comment une puce remarque un appui ?

La scrutation (en anglais polling) consiste à lire une broche sans arrêt pour voir si elle a changé. Une interruption fait l’inverse : c’est la puce qui prévient le programme au moment du changement.

Comme avec une sonnette. On peut ouvrir la porte toutes les minutes pour voir si quelqu’un est là, ou attendre qu’elle sonne. Un bouton ajoute un piège : il rebondit.

À la fin de cette leçon

Remarque

Je peux expliquer la scrutation et l’interruption, et filtrer le rebond d’un bouton.

Mots-clés

MotCe que ça veut dire
Scrutationlire une broche en boucle pour voir si elle change
Interruptionun signal qui fait appeler une fonction par la puce
Gestionnairela fonction que la puce appelle à une interruption
Front montantle passage d’une broche de 0 à 1
Rebondles allers-retours très rapides d’un bouton qui vient de bouger
Anti-rebondle filtre qui ignore ces allers-retours

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

La scrutation lit la broche à chaque tour

Le programme lit la broche à chaque tour de boucle. Il garde la valeur précédente. Quand la valeur était 0 et qu’elle vaut maintenant 1, c’est un front montant : un appui.

Le défaut : le programme ne fait rien d’autre pendant qu’il surveille, et s’il lit trop rarement il rate un appui bref.

Exemple : un seul appui vu tick par tick

Tick012345678910
Niveau de la broche00101111110
Front montant ?ouioui

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

Les scripts du labo parlent anglais

La puce est un simulateur d’une puce inventée. Dans ce labo, le bouton est relié à la broche 2. Son signal est écrit à l’avance dans le script : tout le monde voit la même chose.

Les scripts affichent des mots anglais : tick, pin et press seen?. La colonne yes marque un front montant.

Compter les appuis par scrutation

Commande
docker exec jupyter python3 steps/poll.py

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Une interruption appelle un gestionnaire

Sur cette puce, le registre IFR contient un drapeau : il passe à 1 quand le bouton monte. Si le bit d’autorisation IE est à 1 dans TCCR, la puce efface le drapeau et appelle le gestionnaire.

Le programme n’a plus besoin de lire la broche sans cesse. Il fait autre chose, et la puce l’interrompt au bon moment.

Compter les appels du gestionnaire

Commande
docker exec jupyter python3 steps/interrupt.py

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Une erreur fréquente

Attention

On croit souvent qu’une interruption supprime le rebond. Ce n’est pas vrai : le gestionnaire a été appelé pour chaque front, deux fois pour un seul appui. L’interruption évite seulement de scruter. Le rebond reste dans le signal : le code doit le filtrer.

Un délai ignore les fronts trop proches

Pour filtrer le rebond, on garde un front, puis on ignore ceux qui suivent de moins de quelques ticks. Avec un délai de 3, un front au tick 4 est ignoré si le dernier gardé était au tick 2.

Choisir le délai demande un compromis : trop court, le rebond passe ; trop long, deux vrais appuis rapides n’en font plus qu’un.

Filtrer le rebond en Python

Code: python
# Un bouton de portail : un appui, plusieurs rebonds. On ignore un front trop proche du dernier gardé.
releves = [0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0]
delai = 3
precedent = 0
derniers_gardes = []
for tick in range(len(releves)):
    if releves[tick] == 1 and precedent == 0:
        if len(derniers_gardes) == 0 or tick - derniers_gardes[-1] > delai:
            derniers_gardes.append(tick)
    precedent = releves[tick]
print("appuis gardés aux ticks :", derniers_gardes)
# Mettez le délai à 1 puis relancez : combien d’appuis restent ?

À propos de ce labo et de sa source: Lab de systèmes embarqués : registres, broches, PWM et interruptions sur une puce simulée

Vous enseignez à une classe ? Proposez ce module à vos étudiants avec un guide de l'enseignant, des devoirs corrigés et un laboratoire pour chaque étudiant.