3.10. GPIO-вхід¶
Читання перемикача (або будь-якого цифрового сигналу) з GPIO-виводу знову виконується через machine.Pin, цього разу налаштованого як вхід. Інтерфейс симетричний виходу: налаштувати режим, а потім або опитувати значення виводу в головному циклі, або зареєструвати обробник переривань, що спрацьовує при зміні значення.
3.10.1. Налаштування входу¶
Передайте Pin.IN конструктору та, за бажанням, підтягуючий резистор:
from machine import Pin
button = Pin("P0", Pin.IN, Pin.PULL_UP)
Це налаштовує P0 як вхід із увімкненим внутрішнім підтягуючим резистором мікроконтролера. Якщо до виводу нічого не підключено, підтяжка утримує його на HIGH; замикання перемикача від виводу до землі тягне його на LOW.
3.10.2. Читання значення¶
value() без аргументів повертає поточний стан – 0 для LOW, 1 для HIGH:
if button.value() == 0:
print("button pressed")
else:
print("button released")
У патерні з головним циклом опитування виглядає так:
while True:
if button.value() == 0:
do_action()
time.sleep_ms(50)
Затримка в 50 мс не дає циклу виконуватися на повній швидкості CPU.
3.10.3. Вхід на основі переривань¶
Опитування працює, але кожна ітерація головного циклу витрачає час CPU. Для входів, що змінюються рідко, – натискання кнопки раз на хвилину, сигнал тривоги – irq() реєструє обробник, який виконується лише при зміні виводу.
Обробник виконується в контексті переривання, що обмежує те, що він може робити:
Без виділення пам’яті. Створення нових об’єктів – списків, рядків, винятків, відформатованих рядків – може завершитися невдачею всередині ISR, оскільки купа заблокована. Заздалегідь виділіть будь-які буфери, що потрібні обробнику, на рівні модуля.
Без тривалих операцій. Обробник повинен передати роботу й повернутися. Витрачання реального часу всередині ISR затримує все інше (інші переривання, головний цикл, USB-трафік).
Без виведення в щільному ISR.
print()виділяє пам’ять, блокує на UART і є одним із найвитратніших дій обробника.
Стандартний патерн полягає в тому, щоб ISR планував реальну роботу через micropython.schedule(), який ставить функцію в чергу для виконання назад у головному контексті в наступній безпечній точці:
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 складається з одного рядка: поставити зворотний виклик у чергу й повернутися. handle_press потім виконується у звичайному контексті, де виділення пам’яті, print() і повільний ввід-вивід знову безпечні.
Аргумент trigger вибирає, який фронт спрацьовує:
Pin.IRQ_FALLING– з 1 до 0.Pin.IRQ_RISING– з 0 до 1.Pin.IRQ_FALLING|Pin.IRQ_RISING– обидва фронти.