Manipulação de GPIO em Python usando libgpiod
Após compreender o uso das ferramentas de shell, o próximo passo natural em sistemas Linux embarcados é controlar GPIOs programaticamente. Para isso, a própria libgpiod fornece bindings oficiais para Python, permitindo acessar exatamente a mesma API usada pelas ferramentas gpioset, gpioget e gpiomon, porém de forma estruturada, segura e integrada à lógica da aplicação .
Antes de qualquer código, é importante garantir que o ambiente esteja preparado. Em distribuições modernas, os bindings Python costumam estar disponíveis como pacote:
sudo apt install python3-libgpiod
Ou, em alguns sistemas, como:
pip install gpiod
Uma vez instalada a biblioteca, o modelo mental em Python segue exatamente o conceito do kernel: abrir um gpiochip, obter uma linha, requisitar a linha e então ler ou escrever valores. Esse fluxo explícito é uma das grandes vantagens da nova interface, pois deixa claro quando um recurso está alocado e sob controle do processo.
Leitura de um GPIO como entrada
O exemplo abaixo demonstra como abrir o gpiochip0, requisitar a linha 7 como entrada e ler seu estado:
import gpiod
# Abre a controladora de GPIO
chip = gpiod.Chip("gpiochip0")
# Obtém a linha desejada
line = chip.get_line(7)
# Requisita a linha como entrada
line.request(consumer="leitura_gpio", type=gpiod.LINE_REQ_DIR_IN)
# Lê o valor lógico
value = line.get_value()
print(f"Estado do GPIO: {value}")
# Libera recursos explicitamente
line.release()
chip.close()
Observe que o código deixa explícito quem é o consumidor da linha (consumer="leitura_gpio"). Essa identificação aparece inclusive em ferramentas como gpioinfo, facilitando o diagnóstico em sistemas complexos. Além disso, quando o processo encerra, o kernel garante a liberação do GPIO, evitando estados indefinidos — um problema clássico do sysfs antigo.
Escrita em um GPIO como saída
Para controlar um LED ou um relé, basta alterar o tipo de requisição para saída:
import gpiod
import time
chip = gpiod.Chip("gpiochip7")
line = chip.get_line(0)
# Requisita como saída e define valor inicial
line.request(
consumer="controle_led",
type=gpiod.LINE_REQ_DIR_OUT,
default_vals=[0]
)
# Liga o GPIO
line.set_value(1)
time.sleep(1)
# Desliga o GPIO
line.set_value(0)
line.release()
chip.close()
Aqui já aparece uma vantagem importante da API moderna: o valor inicial do GPIO pode ser definido no momento da requisição, evitando glitches elétricos durante a transição de estado — algo extremamente relevante em aplicações industriais e de potência.
Monitoramento de eventos (interrupções)
Uma das funcionalidades mais poderosas da nova interface é o suporte confiável a eventos. O exemplo abaixo demonstra como esperar por bordas de subida e descida em um GPIO:
import gpiod
chip = gpiod.Chip("gpiochip0")
line = chip.get_line(7)
line.request(
consumer="monitor_gpio",
type=gpiod.LINE_REQ_EV_BOTH_EDGES
)
print("Aguardando eventos...")
while True:
if line.event_wait(sec=5):
event = line.event_read()
if event.type == gpiod.LineEvent.RISING_EDGE:
print("Borda de subida detectada")
elif event.type == gpiod.LineEvent.FALLING_EDGE:
print("Borda de descida detectada")
Nesse modelo, o processo entra em espera bloqueante, sem polling agressivo ou desperdício de CPU. O kernel garante que os eventos sejam entregues corretamente, mesmo sob carga, tornando essa abordagem adequada para botões, sensores digitais e sinais de sincronismo em sistemas embarcados robustos.
Do ponto de vista arquitetural, esse estilo de programação aproxima o Linux embarcado de um RTOS orientado a eventos, com a vantagem de herdar toda a infraestrutura de multitarefa, drivers e segurança do kernel Linux.
Na próxima seção, vamos consolidar o aprendizado comparando shell vs Python, discutindo boas e más práticas, e indicando quando cada abordagem deve ser usada em sistemas reais.