3.10. GPIO-Eingang¶
Das Lesen eines Schalters (oder eines beliebigen digitalen Signals) von einem GPIO-Pin läuft wieder über machine.Pin, diesmal als Eingang konfiguriert. Die Schnittstelle ist symmetrisch zum Ausgang: Konfigurieren Sie den Modus und fragen Sie dann entweder den Wert des Pins in der Hauptschleife ab oder registrieren Sie einen Interrupt-Handler, der bei einer Wertänderung auslöst.
3.10.1. Einen Eingang konfigurieren¶
Übergeben Sie Pin.IN an den Konstruktor und optional einen Pull-Widerstand:
from machine import Pin
button = Pin("P0", Pin.IN, Pin.PULL_UP)
Das konfiguriert P0 als Eingang mit aktiviertem internem Pull-up-Widerstand des MCU. Ist nichts mit dem Pin verbunden, hält der Pull-up ihn High; das Schließen eines Schalters vom Pin zur Masse zieht ihn Low.
3.10.2. Den Wert lesen¶
value() ohne Argumente liefert den aktuellen Zustand zurück – 0 für Low, 1 für High:
if button.value() == 0:
print("button pressed")
else:
print("button released")
Im Hauptschleifen-Muster sieht das Polling so aus:
while True:
if button.value() == 0:
do_action()
time.sleep_ms(50)
Das Sleep von 50 ms verhindert, dass die Schleife mit voller CPU-Last läuft.
3.10.3. Interrupt-gesteuerter Eingang¶
Polling funktioniert, doch jede Iteration der Hauptschleife kostet CPU-Zeit. Für Eingänge, die sich selten ändern – ein Tastendruck einmal pro Minute, ein Alarmsignal – registriert irq() einen Handler, der nur dann läuft, wenn sich der Pin ändert.
Der Handler läuft im Interrupt-Kontext, was einschränkt, was er tun darf:
Keine Speicherzuweisung. Das Erzeugen neuer Objekte – Listen, Strings, Exceptions, formatierte Strings – kann innerhalb einer ISR fehlschlagen, weil der Heap gesperrt ist. Reservieren Sie alle Puffer, die der Handler benötigt, vorab im Modul-Scope.
Keine langlaufende Arbeit. Der Handler sollte die Arbeit weiterreichen und zurückkehren. Echte Zeit innerhalb einer ISR zu verbringen verzögert alles andere (andere Interrupts, die Hauptschleife, den USB-Verkehr).
Kein Drucken in einer engen ISR.
print()weist Speicher zu, blockiert auf dem UART und ist eines der teuersten Dinge, die ein Handler tun kann.
Das Standardmuster ist, dass die ISR die eigentliche Arbeit über micropython.schedule() einplant, was eine Funktion in die Warteschlange stellt, damit sie zum nächsten sicheren Zeitpunkt zurück im Hauptkontext läuft:
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)
Die ISR ist eine einzige Zeile: den Callback in die Warteschlange stellen und zurückkehren. handle_press läuft dann im normalen Kontext, wo Speicherzuweisung, print() und langsame I/O wieder allesamt sicher sind.
Das Argument trigger wählt aus, welche Flanke auslöst:
Pin.IRQ_FALLING– 1 auf 0.Pin.IRQ_RISING– 0 auf 1.Pin.IRQ_FALLING|Pin.IRQ_RISING– beide Flanken.