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 :