Controle GPIO da Raspberry Pi e Python – Parte 3

Este é um tutorial sobre como usar a GPIO da Raspberry Pi usando a biblioteca Python. Ele foi dividido em quatro partes para facilitar o acesso:

  • Parte 1: introdução e configuração
  • Parte 2: acesso às entradas e saídas
  • Parte 3: aguardando eventos
  • Parte 4: callbacks

Introdução

Nas partes 1 e 2 deste tutorial vimos como configurar e utilizar a GPIO da Raspberry Pi. No programa anterior, ficávamos em um loop verificando o nível do pino de entrada (do botão) a cada um segundo para daí realizarmos a ação desejada (acender/apagar o LED).

Isso é o que chamamos de polling, o ato de ficar verificando alguma coisa continuamente. Caso você deseje que o programa reaja mais rápido, você pode definir um tempo menor de espera entre uma verificação e outra. Isso é bom caso deseje uma reação rápida, mas usa bastante o processador.

Interrupção

Mas deve existir um jeito melhor, não? Sim, existe. São as interrupções.

Interrupção é um jeito muito mais eficiente de lidar com a situação do tipo esperar que algo aconteça e então fazer a ação. Ela libera o recurso que você ocuparia no momento do polling e que você pode usar para outra coisa.

Na biblioteca do Pyhon, isso é resolvido se usando a função GPIO.wait_for_edge([pin], [borda], [timeout]). Você pode configurar para usar a borda de subida (GPIO.RISING), a borda de descida (GPIO.FALLING) ou ambas (GPIO.BOTH).

O parametro de timeout é opcional e serve para aguardar apenas por um certo período de tempo (e não travar o seu programa). O valor é dado em milissegundos.

if GPIO.wait_for_edge(18, GPIO.FALLING, timeout=5000):
    out = not out
    GPIO.output(12, out)

Materiais necessários

  • Raspberry Pi com sistema operacional Raspbian já instalado (vamos usar o a RPi 2 modelo B, mas pode ser utilizado outro, caso queira)
  • Led
  • Resistor 100 Ohm
  • Push button
  • Jumpers
  • Protoboard

Conexão

Estamos o usando o mesmo circuito do exemplo anterior (que pode ser visto aqui também).

  • Conectar o lado positivo LED (anodo) ao pino 12 (GPIO 18) da RPi. O lado negativo conectar ao resistor e o outro lado do resistor ao terra (GND).
  • Conectar o lado positivo do outro LED (anodo) ao pino 16 (GPIO 23) da RPi. O lado negativo conectar ao resistor e o outro lado do resistor ao terra (GND).
  • Conectar um lado do push button ao pino 18 (GPIO 24) da RPi e o outro lado ao terra (GND).
  • Conectar um lado do outro push button ao pino 22 (GPIO 25) e o outro lado ao 3.3V.

Programação

Vamos modificar um pouco o nosso programa. Agora, ao invés de ficarmos no loop, vamos usar a função GPIO.wait_for_edge() para aguardar a borda do botão e realizar a operação desejada. Vamos também inserir a leitura de mais um botão. Dessa vez, cada botão vai ser responsável por acender/apagar um LED assim que for acionado.

import RPi.GPIO as GPIO
 
LedPin1 = 12    # pin12 --- led
LedPin2 = 16    # pin16 --- led
BtnPin1 = 18    # pin18 --- button
BtnPin2 = 22    # pin22 --- button
 
GPIO.setmode(GPIO.BOARD)       # Pinagem física
GPIO.setup([LedPin1, LedPin2], GPIO.OUT)   # Pino de led como saída
GPIO.setup(BtnPin1, GPIO.IN, pull_up_down=GPIO.PUD_UP)    # Pino do botão como saída e aciona o pull-up
GPIO.setup(BtnPin2, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) 
GPIO.output([LedPin1, LedPin2], GPIO.LOW) # Desliga o led
 
# Loop principal
print('Pressione Ctrl+C para sair')
try:
    out1 = False
    out2 = False
    while True:
        if GPIO.wait_for_edge(BtnPin1, GPIO.RISING, timeout=2000):
            print('Borda detectada no botao 1...')
            out1 = not out1
            GPIO.output(LedPin1, out1)
        if GPIO.wait_for_edge(BtnPin2, GPIO.FALLING, timeout=2000):
            print('Borda detectada no botao 2...')
            out2 = not out2
            GPIO.output(LedPin2, out2)
 
except KeyboardInterrupt:
    # Ctrl+C foi pressionado
    pass
 
GPIO.output([LedPin1, LedPin2], 0)
GPIO.cleanup()  # Limpa configuração

Salve o arquivo e rode. Aperte os botões e você deve ter uma saída parecida com essa:

Você deve ter reparado alguns problemas agora com nossa solução. O sistema agora demora um pouco para perceber que o botão 1 ou 2 foi pressionado. Isso porque ele está aguardando ocorrer alguma coisa no outro botão, devido à função GPIO.wait_for_edge().

Vamos resolver isso no próximo artigo da série.

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *