3.10. Intrare GPIO

Citirea unui comutator (sau a oricărui semnal digital) de la un pin GPIO trece din nou prin machine.Pin, de data aceasta configurat ca intrare. Interfața este simetrică cu cea de ieșire: configurați modul, apoi fie interogați valoarea pinului în bucla principală, fie înregistrați o rutină de tratare a întreruperilor care se declanșează când valoarea se schimbă.

3.10.1. Configurarea unei intrări

Transmiteți Pin.IN constructorului și, opțional, un rezistor de tragere:

from machine import Pin

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

Acest lucru configurează P0 ca intrare cu rezistorul intern de ridicare al MCU-ului activat. Fără nimic conectat la pin, rezistorul de ridicare îl menține la nivel ridicat; închiderea unui comutator de la pin la masă îl trage la nivel coborât.

3.10.2. Citirea valorii

value() fără argumente returnează starea curentă – 0 pentru nivel coborât, 1 pentru nivel ridicat:

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

În tiparul cu buclă principală, interogarea arată astfel:

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

Pauza de 50 ms împiedică bucla să ruleze cu procesorul la capacitate maximă.

3.10.3. Intrare bazată pe întreruperi

Interogarea funcționează, dar fiecare iterație a buclei principale consumă timp de procesor. Pentru intrările care se schimbă rar – o apăsare de buton o dată pe minut, un semnal de alarmă – irq() înregistrează o rutină de tratare care rulează doar când pinul se schimbă.

Rutina de tratare rulează în contextul de întrerupere, ceea ce restricționează ce poate face:

  • Fără alocare de memorie. Crearea de obiecte noi – liste, șiruri de caractere, excepții, șiruri formatate – poate eșua în interiorul unui ISR deoarece heap-ul este blocat. Prealocați la nivel de modul orice tampoane (buffers) de care are nevoie rutina de tratare.

  • Fără lucru de lungă durată. Rutina de tratare ar trebui să predea sarcina și să revină. Petrecerea unui timp real în interiorul unui ISR întârzie tot restul (alte întreruperi, bucla principală, traficul USB).

  • Fără afișare într-un ISR strâns. print() alocă memorie, se blochează pe UART și este unul dintre cele mai costisitoare lucruri pe care le poate face o rutină de tratare.

Tiparul standard este ca ISR-ul să programeze lucrul real prin micropython.schedule(), care pune în coadă o funcție pentru a rula înapoi în contextul principal la următorul punct sigur:

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-ul este o singură linie: pune în coadă funcția de retroapelare (callback) și revine. handle_press rulează apoi în context normal, unde alocarea, print() și operațiile I/O lente sunt din nou toate sigure.

Argumentul trigger selectează ce muchie declanșează: