3.10. Entrée GPIO¶
La lecture d’un interrupteur (ou de tout signal numérique) depuis une broche GPIO passe de nouveau par machine.Pin, cette fois configurée en entrée. L’interface est symétrique de la sortie : configurez le mode, puis scrutez la valeur de la broche dans la boucle principale ou enregistrez un gestionnaire d’interruption qui se déclenche lorsque la valeur change.
3.10.1. Configurer une entrée¶
Passez Pin.IN au constructeur, et éventuellement une résistance de tirage :
from machine import Pin
button = Pin("P0", Pin.IN, Pin.PULL_UP)
Cela configure P0 comme entrée avec la résistance de tirage interne du microcontrôleur activée. Sans rien de connecté à la broche, le tirage la maintient à l’état haut ; fermer un interrupteur de la broche vers la masse la tire à l’état bas.
3.10.2. Lire la valeur¶
value() sans argument renvoie l’état actuel – 0 pour l’état bas, 1 pour l’état haut :
if button.value() == 0:
print("button pressed")
else:
print("button released")
Dans le motif de la boucle principale, la scrutation ressemble à ceci :
while True:
if button.value() == 0:
do_action()
time.sleep_ms(50)
Le sommeil de 50 ms empêche la boucle de tourner à plein régime du CPU.
3.10.3. Entrée pilotée par interruption¶
La scrutation fonctionne, mais chaque itération de la boucle principale consomme du temps CPU. Pour les entrées qui changent rarement – un appui sur un bouton une fois par minute, un signal d’alarme – irq() enregistre un gestionnaire qui s’exécute uniquement lorsque la broche change.
Le gestionnaire s’exécute en contexte d’interruption, ce qui restreint ce qu’il peut faire :
Aucune allocation de mémoire. La création de nouveaux objets – listes, chaînes, exceptions, chaînes formatées – peut échouer à l’intérieur d’une ISR car le tas est verrouillé. Pré-allouez au niveau du module tous les tampons dont le gestionnaire a besoin.
Aucun travail de longue durée. Le gestionnaire doit déléguer et retourner. Passer un temps réel à l’intérieur d’une ISR retarde tout le reste (autres interruptions, boucle principale, trafic USB).
Aucune impression dans une ISR serrée.
print()alloue, se bloque sur l’UART, et constitue l’une des opérations les plus coûteuses qu’un gestionnaire puisse effectuer.
Le motif standard consiste à ce que l’ISR planifie le travail réel via micropython.schedule(), qui met une fonction en file d’attente pour qu’elle s’exécute de nouveau dans le contexte principal au prochain point sûr :
import micropython
def handle_press(pin):
print("button pressed")
def on_press(pin):
micropython.schedule(handle_press, pin)
button.irq(handler=on_press, trigger=Pin.IRQ_FALLING)
L’ISR tient en une ligne : mettre la fonction de rappel en file d’attente et retourner. handle_press s’exécute ensuite en contexte normal, où l’allocation, print() et les E/S lentes sont de nouveau toutes sûres.
L’argument trigger sélectionne le front qui déclenche :
Pin.IRQ_FALLING– 1 vers 0.Pin.IRQ_RISING– 0 vers 1.Pin.IRQ_FALLING|Pin.IRQ_RISING– les deux fronts.