3.10. Wejście GPIO¶
Odczyt przełącznika (lub dowolnego sygnału cyfrowego) z pinu GPIO znów przechodzi przez machine.Pin, tym razem skonfigurowany jako wejście. Interfejs jest symetryczny względem wyjścia: skonfiguruj tryb, a następnie albo odpytuj wartość pinu w głównej pętli, albo zarejestruj obsługę przerwania, która uruchamia się, gdy wartość się zmienia.
3.10.1. Konfigurowanie wejścia¶
Przekaż Pin.IN do konstruktora oraz opcjonalnie rezystor podciągający:
from machine import Pin
button = Pin("P0", Pin.IN, Pin.PULL_UP)
To konfiguruje P0 jako wejście z włączonym wewnętrznym rezystorem podciągającym MCU. Gdy do pinu nic nie jest podłączone, podciąganie utrzymuje go w stanie wysokim; zamknięcie przełącznika od pinu do masy ściąga go w stan niski.
3.10.2. Odczyt wartości¶
value() bez argumentów zwraca bieżący stan – 0 dla niskiego, 1 dla wysokiego:
if button.value() == 0:
print("button pressed")
else:
print("button released")
We wzorcu z główną pętlą odpytywanie wygląda tak:
while True:
if button.value() == 0:
do_action()
time.sleep_ms(50)
50 ms uśpienia zapobiega działaniu pętli z pełnym obciążeniem CPU.
3.10.3. Wejście sterowane przerwaniami¶
Odpytywanie działa, ale każda iteracja głównej pętli kosztuje czas CPU. W przypadku wejść, które zmieniają się rzadko – naciśnięcie przycisku raz na minutę, sygnał alarmowy – irq() rejestruje obsługę, która uruchamia się tylko wtedy, gdy pin się zmienia.
Obsługa działa w kontekście przerwania, co ogranicza to, co może robić:
Brak alokacji pamięci. Tworzenie nowych obiektów – list, łańcuchów znaków, wyjątków, sformatowanych łańcuchów – może się nie powieść wewnątrz ISR, ponieważ sterta jest zablokowana. Wstępnie zaalokuj wszelkie bufory potrzebne obsłudze w zakresie modułu.
Brak długotrwałej pracy. Obsługa powinna przekazać zadanie dalej i zakończyć działanie. Spędzanie rzeczywistego czasu wewnątrz ISR opóźnia wszystko inne (inne przerwania, główną pętlę, ruch USB).
Brak drukowania w napiętym ISR.
print()alokuje pamięć, blokuje się na UART i jest jedną z najbardziej kosztownych rzeczy, jakie obsługa może wykonać.
Standardowym wzorcem jest, by ISR zaplanował rzeczywistą pracę za pomocą micropython.schedule(), która kolejkuje funkcję do wykonania z powrotem w głównym kontekście w najbliższym bezpiecznym punkcie:
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)
ISR to jedna linia: zakolejkuj wywołanie zwrotne i zakończ. handle_press działa następnie w normalnym kontekście, gdzie alokacja, print() i wolne operacje I/O są znów bezpieczne.
Argument trigger wybiera, które zbocze wyzwala:
Pin.IRQ_FALLING– z 1 na 0.Pin.IRQ_RISING– z 0 na 1.Pin.IRQ_FALLING|Pin.IRQ_RISING– oba zbocza.