3.10. Entrada GPIO¶
Ler uma chave (ou qualquer sinal digital) de um pino GPIO passa novamente por machine.Pin, desta vez configurado como entrada. A interface é simétrica à da saída: configure o modo e então faça polling do valor do pino no laço principal ou registre um manipulador de interrupção que dispara quando o valor muda.
3.10.1. Configurando uma entrada¶
Passe Pin.IN ao construtor e, opcionalmente, um resistor de pull:
from machine import Pin
button = Pin("P0", Pin.IN, Pin.PULL_UP)
Isso configura P0 como entrada com o resistor de pull-up interno do MCU habilitado. Sem nada conectado ao pino, o pull-up o mantém em nível alto; fechar uma chave do pino para o terra o puxa para nível baixo.
3.10.2. Lendo o valor¶
value() sem argumentos retorna o estado atual – 0 para nível baixo, 1 para nível alto:
if button.value() == 0:
print("button pressed")
else:
print("button released")
No padrão de laço principal, o polling fica assim:
while True:
if button.value() == 0:
do_action()
time.sleep_ms(50)
O sleep de 50 ms evita que o laço seja executado com a CPU em capacidade total.
3.10.3. Entrada orientada a interrupção¶
O polling funciona, mas cada iteração do laço principal custa tempo de CPU. Para entradas que mudam raramente – um toque de botão uma vez por minuto, um sinal de alarme – irq() registra um manipulador que é executado somente quando o pino muda.
O manipulador é executado em contexto de interrupção, o que restringe o que ele pode fazer:
Sem alocação de memória. Criar novos objetos – listas, strings, exceções, strings formatadas – pode falhar dentro de uma ISR porque o heap está bloqueado. Pré-aloque quaisquer buffers de que o manipulador precise no escopo de módulo.
Sem trabalho de longa duração. O manipulador deve repassar e retornar. Gastar tempo real dentro de uma ISR atrasa tudo o mais (outras interrupções, o laço principal, o tráfego USB).
Sem impressão em uma ISR curta.
print()aloca, bloqueia na UART e é uma das coisas mais caras que um manipulador pode fazer.
O padrão recomendado é a ISR agendar o trabalho real via micropython.schedule(), que enfileira uma função para ser executada de volta no contexto principal no próximo ponto seguro:
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)
A ISR tem uma linha: enfileirar o callback e retornar. handle_press então é executado em contexto normal, onde alocação, print() e I/O lenta são todos seguros novamente.
O argumento trigger seleciona qual borda dispara:
Pin.IRQ_FALLING– de 1 para 0.Pin.IRQ_RISING– de 0 para 1.Pin.IRQ_FALLING|Pin.IRQ_RISING– ambas as bordas.