13 julho 2013

Raspberry PI GPIO - Parte Final (RPi.GPIO lendo dados)

Nos posts anteriores foi possível mostrar como fazer para ativar pinos de saída com a biblioteca RPi.GPIO. Este post agora é para demonstrar como fiz para ler pinos de entradas, ou seja, como ler pinos que receberão sinais lógicos 0 ou 1.

Acho que seria bom explicar como funciona o hardware utilizado. Pois bem, nada mais é do que o pino 1 da GPIO, que representa 3,3V constantes, ligado em série a um resistor de 10K a um terminal de um botão (push button), esse mesmo terminal está conectado a um pino utilizado como entrada (pinos 15, ou 16, ou 18, ou 19), e o outro terminal do botão conectado ao pino 6 que é o terra (GND) da GPIO.

Pino 1 (3.3V)
|
|
R10K
|__________________ Pino 19 (input)
|
_/    (chave do tipo push-button)
|
|
Pino 6 (GND)


Dessa maneira quando a chave estiver aberta o pino receberá 3.3V (nível lógico alto), quando estiver fechada receberá 0V (GND, nível lógico baixo). Resumidamente:
- chave não pressionada = 1
- chave pressionada = 0

Pois bem, agora que entendemos quais os sinais serão recebidos, vamos falar da RPi.GPIO. Bem simples, como sua utilização para pinos de saída. Primeiramente deve-se setar qual o modo de representação dos pinos, numeração da placa (GPIO.BOARD) ou numeração do chip BCM2830 (GPIO.BCM). Depois quais os pinos que serão de usados como entrada. Acabei criando duas funções para isso:

import RPi.GPIO as GPIO

def init_env():
        GPIO.setmode(GPIO.BOARD)
        GPIO.setwarnings(False)

def init_pin():
        GPIO.setup(15,GPIO.IN)
        GPIO.setup(16,GPIO.IN)
        GPIO.setup(18,GPIO.IN)
        GPIO.setup(19,GPIO.IN)


Para ler a entrada, a maneira mais simples seria fazer um loop e invocar a função input() da biblioteca RPi.GPIO, passando qual o pino será ligo. Exemplo:

entrada = print(GPIO.input(19))
while(entrada):
        entrada = GPIO.input(19)

Para testar os botões do meu hardware fiz um código que exibe os estados dos pinos de entrada (15,16,18 e 19) durante 5 segundos, e a medida que pressiono os botões, o programa exibe 0 no pino da chave que pressionei.

Em uma aplicação mais real, essa abordagem mais simples causa problemas, pois a leitura do pino somente será realizada quando o programa encontrar a instrução com o método input, o que ocasiona certo atraso. A biblioteca RPi.GPIO possui mecanismo de tratamento de evento, percebendo alterações de nível de sinais, o que é chamado de alterção de bordas em eletrônica digital. Isso quer dizer que algum código pode ser invocado através de chamadas de interrupções, quando for percebido uma alteração de subida (GPIO.RISING) de 0 para 1, ou uma alteração de descina (GPIO.FALLING) de 1 para 0, ou para ambos os casos (GPIO.BOTH).

É bem simples, basta adicionar um evento com função RPi.GPIO.add_event_detect(pino, alteração de sinal, func) onde func é uma função que você pode criar que será chamada quando for percebido uma alteração de sinal, em um determinado pino de entrada. Exemplo:

def callback_exit(channel):
        print("Botão pressionado no pino ",channel)
        print("Saindo do programa.")
        quit()


GPIO.add_event_detect(18, GPIO.FALLING, callback_exit)

Com o exemplo acima, um programa enquanto estiver sendo executado, poderá ser interrompido quando o sinal do pino 18 cair de 1 para 0.

Para terminar a brincadeira resolvi utilizar a função system() para desligar o Raspberry PI quando pressionado um botão. Abaixo segue uma representação do trecho do código:

def callback_off(channel):
        print("Botão pressionado no pino ",channel)
        print("Desligando o Raspberry PI")
        os.system("shutdown -h now")


GPIO.add_event_detect(19, GPIO.FALLING, callback_off)

Colocando um loop infinito no final do programa, e exibindo em tela duas opções, para pressionar o botão do pino 18 para sair do programa, ou pressionar o botão do pinto 19 para sair do programa.

Com isso seria possível colocar algumas funções de teclado através da GPIO.

Para os códigos completos, inclusive dos posts anterior, podem ser encontrados no endereço abaixo do github:

https://github.com/ferauche/gpiodk

Aliás, foi bem fácil instalar o cliente git pelo pacman, e fazer o clone, depois o push para o servidor github, tudo isso diretamente pelo Pi.

Link utilizado:
http://code.google.com/p/raspberry-gpio-python/wiki/Inputs

Um comentário:

  1. Olá, gostei da sua solução para conectar o DB25, eu posso usar esse mesmo cabo que você fez para usar em uma placa CNC3AX e controlar uma Router CNC? Nesse caso, funcionaria com GRBL ou precisaria ser um programa próprio para a CNC3AX como o Mach3? Minha placa CNC3AX tem apenas saída DB25 e gostaria de conectar a uma Raspberry parada que tenho para não ter que comprar tudo de novo com o Arduíno. Obrigado.

    ResponderExcluir