3.10. GPIO bemenet

Egy kapcsoló (vagy bármilyen digitális jel) olvasása egy GPIO lábról ismét a machine.Pin osztályon keresztül történik, ezúttal bemenetként konfigurálva. A felület szimmetrikus a kimenettel: állítsd be a módot, majd vagy kérdezd le a láb értékét a fő hurokban, vagy regisztrálj egy megszakításkezelőt, amely az érték megváltozásakor lép működésbe.

3.10.1. Bemenet konfigurálása

Add át a Pin.IN értéket a konstruktornak, és opcionálisan egy felhúzó vagy lehúzó ellenállást:

from machine import Pin

button = Pin("P0", Pin.IN, Pin.PULL_UP)

Ez a P0 lábat bemenetként konfigurálja az MCU belső felhúzó ellenállásával engedélyezve. Ha semmi sincs a lábhoz kötve, a felhúzó magas szinten tartja; egy kapcsoló zárása a lábról a földre alacsonyra húzza.

3.10.2. Az érték olvasása

A value() argumentumok nélkül az aktuális állapotot adja vissza – 0 alacsonyhoz, 1 magashoz:

if button.value() == 0:
    print("button pressed")
else:
    print("button released")

A fő hurok mintájában a lekérdezés így néz ki:

while True:
    if button.value() == 0:
        do_action()
    time.sleep_ms(50)

Az 50 ms-os alvás megakadályozza, hogy a hurok teljes CPU-terheléssel fusson.

3.10.3. Megszakítás-vezérelt bemenet

A lekérdezés működik, de a fő hurok minden iterációja CPU-időbe kerül. A ritkán változó bemenetekhez – egy percenkénti gombnyomás, egy riasztási jel – a irq() regisztrál egy kezelőt, amely csak akkor fut, amikor a láb megváltozik.

A kezelő megszakítási kontextusban fut, ami korlátozza, hogy mit tehet:

  • Nincs memóriafoglalás. Új objektumok létrehozása – listák, sztringek, kivételek, formázott sztringek – egy ISR-en belül sikertelen lehet, mert a heap zárolva van. Foglalj le előre minden puffert, amelyre a kezelőnek szüksége van, modulszinten.

  • Nincs hosszan futó munka. A kezelőnek át kell adnia a munkát és vissza kell térnie. Valódi idő eltöltése egy ISR-en belül mindent mást késleltet (más megszakításokat, a fő hurkot, az USB-forgalmat).

  • Nincs nyomtatás egy szoros ISR-ben. A print() memóriát foglal, blokkol a UART-on, és az egyik legköltségesebb dolog, amit egy kezelő tehet.

A szokásos minta az, hogy az ISR ütemezze a valódi munkát a micropython.schedule() segítségével, amely sorba állít egy függvényt, hogy a fő kontextusban fusson a következő biztonságos pontnál:

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)

Az ISR egyetlen sor: sorba állítja a visszahívást és visszatér. A handle_press ezután normál kontextusban fut, ahol a memóriafoglalás, a print() és a lassú I/O ismét mind biztonságos.

A trigger argumentum választja ki, hogy melyik él lép működésbe: