FAVORITAR
FecharPlease loginn
19 Comentários
FAVORITAR
FecharPlease loginn

Raspberry PI – GPIO input com Python

modo Input

Introdução

A primeira parte da série de interação com o GPIO (General Purpose Input Output) do Raspberry PI no modo Output possui os passos fundamentais para esta segunda etapa como a preparação do ambiente. Nesta segunda etapa vamos ver o modo Input, e para a prática será utilizado o Raspberry PI B, protoboard, pushbutton e alguns resistores. Serão mencionados os possíveis modos de trabalho com Input utilizando resistores de pull-up e pull-down, internos ou externos, e recursos como detecção de borda, debounce por software e uma “interrupção” baseada na detecção por borda.

Configuração do ambiente host

  • Board: Raspberry PI B;

  • Distribuição: Raspbian – Debian Wheezy (2014-01-07);

  • Kernel 3.12.22;

  • Python 2.7.3;

  • RPi.GPIO 0.5.7.

RPi.GPIO

Já vimos na primeira parte da série as funções RPi.GPIO.setmode(), RPi.GPIO.setup(), RPi.GPIO.output(), RPi.GPIO.input() e RPi.GPIO.cleanup(), e agora vamos ver algumas funções e parâmetros que tornam o modo input muito interessante.

  • RPi.GPIO.RISING => Borda de subida, quando passa de 0V para 3.3V;
  • RPi.GPIO.FALLING => Borda de descida, quando passa de 3.3V para 0V;
  • RPi.GPIO.BOTH => Os dois estados, ocorre ação tanto na subida [0V → 3.3V] quanto na descida [3.3V → 0V];
  • RPi.GPIO.LOW => Nivel lógico baixo [low] ou 0V;
  • RPi.GPIO.HIGH => Nivel lógico alto [high] ou 3.3V;
  • RPi.GPIO.PUD_UP => Pino Input em modo pull-up;
  • RPi.GPIO.PUD_DOWN => Pino Input em modo pull-down;
  • RPi.GPIO.PUD_OFF => Padrão.
  • RPi.GPIO.wait_for_edge() => Bloqueia a execução até que o botão seja pressionado ou a ação setada aconteça;
  • RPi.GPIO.event_detected() => Guarda o estado de um evento no pino, e quando for verificado no loop, indica se houve ou não mudança no pino. Pode ser utilizado dentro do loop e não irá perder a informação;
  • RPi.GPIO.add_event_detect() => Adiciona um evento baseado no pino, se o evento irá ocorrer na borda de descida [FALLING], subida [RISING] ou em ambos [BOTH]. Adiciona uma função para ser chamada e aceita parâmetro de tempo debounce;
  • RPi.GPIO.remove_event_detect() => Permite remover um evento em qualquer parte do código se não for mais utilizado.

A Figura 1 ilustra os comportamentos que ocorrerão no decorrer do artigo ao acionar o pushbutton.

modo Input
Figura 1 – Detalhes sobre a mudança do nível lógico com chaves mecânicas

Olhando a Figura 1, fica fácil entender os parâmetros LOW (representado por 0V), HIGH (como 3.3V), Edge Rising ou RISING (transição de 0V a 3.3V), Edge Falling ou FALLING (transição de 3.3V a 0V) e o efeito bouncing. Esse último, se você não conhece, pode ver o artigo Leitura de chaves mecânicas e o processo de debounce, escrito pelo Rodrigo Almedia, indicando como contornar o problema via hardware e software, e neste artigo iremos estudar a solução via software.

PushButton com pull-down interno

modo Input
Figura 2 – Esquema de ligação do PushButton em pull-down interno

O primeiro exemplo prático será adicionar um pushbutton. Uma de suas extremidades será conectada ao 3.3V (pino 1) e a outra ao pino 16 (ou GPIO 23) da Raspberry Pi no modo BCM, como na Figura 2. Configuraremos via software utilizando RPi.GPIO o pino 16 (GPIO 23) no modo INPUT e com pull-down interno.

Código:

Executando o código:

PushButton com pull-up interno

modo Input
Figura 3 – Esquema de ligação do PushButton em pull-up interno

No segundo exemplo prático o mesmo PushButton será utilizado, trocando apenas a extremidade de 3.3V (pino 1) para 0V GND (pino 6), como na Figura 3. Configuraremos via software utilizando RPi.GPIO o pino 16 (GPIO 23) no modo INPUT e com pull-up interno.

Código:

O nosso código acima é praticamente o mesmo do exemplo anterior com algumas alterações como: o setup() do GPIO 23 como pull-up; o teste que verifica o estado do pino faz uso da constante gpio.LOW, que poderia ser 0, seguindo a analogia do exemplo anterior; o botão, quando pressionado, faz o programa parar.

Executando o código:

PushButton com  pull-down externo

modo Input
Figura 4 – Esquema de ligação do PushButton em pull-down externo

O próximo exemplo é utilizando resistores externos para configurar como pull-up ou pull-down e, como na Figura 4, vamos utilizar 2 resistores: um de 1k e outro de 10k. A configuração que foi utilizada é o resistor de 1k entre o GPIO e o PushButton e o 10k entre GPIO e o GND, caracterizando ser pull-down.

Código:

Executando o código:

PushButton com pull-up externo

modo Input
Figura 5 – Esquema de ligação do PushButton em pull-up externo

O esquema final da Figura 5, praticamente o mesmo que o anterior, apenas com a alteração do resistor 10k que é entre VCC (3.3V) com GPIO e o PushButton agora é entre o pino do GPIO e o GND, caracterizando ser pull-up. A mesma ideia deve-se seguir no código.

Código:

Executando o código:

Não errei o código não, é que utilizando resistores externos altera-se apenas a linha do if de gpio.HIGH para gpio.LOW. No caso ainda dei uma valorizada, onde troquei gpio.LOW por 0.

Eventos e Interrupções

Os exemplos utilizados até agora foram legais e interessantes, porém na prática sabemos que é um pouco inconveniente aguardar o loop ou, como no exemplo que fizemos, utilizarmos um delay de 1s. Em alguns casos isso é um absurdo e pode ser que a ação de pressionar o botão não seja capturada, sendo uma falha grave e que pode ser facilmente contornada com as funções de “detecção de eventos” event_detect do RPi.GPIO, que tem uma grande relação com Edge Rising (Borda de Subida), Edge Falling (Borda de Descida) ou Both (Ambos sentidos). Utilizaremos o esquemático da Figura 2 por ser mais simples de montar, o PushButton com pull-down e vamos ao código.

Código:

Executando o código:

Você pode testar, e pode ver que independente do momento que pressionar o pushbutton, na ação dele ser pressionado (RISING), indo de 0V para 3.3V, como estamos com pull-down, ele irá “guardar” esta mudança de estado. Na próxima vez que for executado o loop, este evento será tratado, no nosso caso sendo chamada a função action_press_button() e saindo do programa.

E se por acaso quiséssemos que a ação ocorresse ao soltar o pushbutton e não ao pressionar o mesmo?

Código:

Executando o código:

Não mudou nada na saída do código, tirando que o programa só parou quando pressionamos e soltamos o PushButton. Enquanto o botão estiver pressionado, nada acontece. O mesmo pode ser feito com BOTH, que a ação ocorrerá ao pressionar e soltar.

Outra opção interessante no event_detect() é poder adicionar uma função a ser chamada assim que ocorrer a mudança de estado, utilizando o parâmetro callback. Seria a correspondência de uma “Interrupção”, porém eu não gosto muito deste termo e prefiro aceitar o de uma chamada em paralelo ou execução já que uma segunda thread é disparada neste caso. Vamos ver!

Código:

Executando o código:

Usando callback no add_event_detect(), podemos ver que existem “prioridades” na chamada, porque assim que o evento ocorre é lançada uma segunda thread para a chamada. Após isso vem a continuação do loop e depois é atendida nossa mudança de estado no próprio loop como antes. Assim conseguimos prioridade no tratamento de input independente do tamanho e tempo de nosso loop, caracterizando a interrupção dita. Comentando sobre a opção de utilizar o debounce via software, como na linha 30, com ou sem o callback, podemos definir o parâmetro bouncetime, que é um valor de tempo em ms para ser ignorado na detecção da borda.

A função remove_event_detect(), pode ser chamada e passado como parâmetro o pino. A qualquer momento o evento sobre o mesmo pino passa a não ser mais válido e você pode remover a ação sobre a borda naquele pino. Vamos ver no próximo código.

Código:

Executando o código:

E por último o wait_for_edge(), que podemos parar a execução do programa até que a mudança no pino ocorra, também sendo válido para a mudança RISING, FALLING ou BOTH.

Código:

Executando o código:

Conclusão

Podemos ver mais uma vez como Python é uma ferramenta fantástica para prototipagem. Com poucas linhas e utilizando o RPi.GPIO conseguimos manipular de diversas maneiras o GPIO do Raspberry Pi no modo input.

O que vem por aí?

No próximo artigo vamos continuar brincando com o GPIO do Raspberry Pi, só que desta vez partindo para PWM.

Outros artigos da série

<< Raspberry PI – GPIO output com PythonRaspberry PI – PWM com Python >>
Licença Creative Commons Esta obra está licenciada com uma Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional.
Home » Linux Embarcado » Raspberry PI – GPIO input com Python

WEBINARS

LEIA TAMBÉM

JUNTE-SE HOJE À COMUNIDADE EMBARCADOS

Comentários:
Notificações
Notificar
guest

19 Comentários
recentes
antigos mais votados
Inline Feedbacks
View all comments
Marina
Marina
06/02/2021 14:11

Olá, muito obrigada pelo tutorial!
Todos os pinos da Rasp apresentam pull-up / pull-down interno? Qual seria a diferença em relação a usar um pull-up/pull-down externo?
Agradeço

Vanessa
Vanessa
19/09/2019 14:38

Material Fantástico e Esclarecedor!!!

Jonathan
Jonathan
01/05/2018 18:11

Os códigos de interrupção realmente funcionam? Testei no raspberry pi 3 e apenas fica retornando polling mesmo clicando no botão.

Cleiton Bueno
Reply to  Jonathan
22/06/2018 12:56

Olá Jonathan, com a RaspberryPI B que foi escrito o artigo funcionava, como faz pouco mais de 3 anos, e a biblioteca com certeza lançou novas versões assim como RaspberryPI precisaria testar novamente com este ambiente atualizado e verificar o que mudou, ficou devendo uma posição sobre o atual funcionamento.

Emerson Alves
Emerson Alves
02/10/2017 17:15

Olá Cleiton,

Você pode me tirar uma dúvida? Qual a função do “break” dentro do if?

“while True:
if gpio.input(23) == gpio.LOW:
print(“Botão acionado”)
break
else:
printf(“Botão desligado”)”

Muito obrigado!

Cleiton Bueno
Reply to  Emerson Alves
02/10/2017 17:31

Olá Emerson,

o break neste caso serve para assim que o botão for pressionado sai do loop while True.

Emerson Alves
Emerson Alves
02/10/2017 17:01

Olá Cleiton.

Apenas gostaria de agradecer pela brilhante explicação sobre os programas para Raspberry, você conseguiu tirar bastantes dúvidas minhas. Meu próximo passo, assim como o Roniere, é integrar o display de LCD com o controlador.

Muito obrigado! Abraços.

Cleiton Bueno
Reply to  Emerson Alves
02/10/2017 17:32

Obrigado Emerson, fico feliz que tenha gostado.

Um abraço.

Roniere Rezende
Roniere Rezende
Reply to  Emerson Alves
03/10/2017 09:46

Emerson, eu já consegui colocar para funcionar o LCD caso tenha alguma dúvida pode me procurar nas redes sociais que te ajudo.
Abraço!

Emerson Alves
Emerson Alves
Reply to  Roniere Rezende
03/10/2017 09:58

Sua ajuda seria muito bem vinda Roniere. Estou trabalhando no projeto de TCC e isso vai alavancar uma boa parte do trabalho.

Roniere Rezende
Roniere Rezende
12/09/2017 09:17

Olá Cleiton Bueno, o seu artigo está muito bom e atendeu meus objetivos de entender como utilizar as GPIOs como entrada. Mas pesquisei aqui sobre o seu próximo artigo sobre PWM e não o encontrei. Houve sequência nos seus artigos? Abraço!

Cleiton Bueno
Reply to  Roniere Rezende
16/09/2017 13:39

Olá Roniere, que bom que gostou do artigo. Você tem razão era para ter uma sequencia com PWM, posso testar novamente, na época com a versão utilizada o PWM ficou muito ruim e com alto overload de CPU, não achei plausível de um artigo.

Acho que vou retestar para tentar cumprir esta promessa.

Um abraço.

Roniere Rezende
Roniere Rezende
Reply to  Cleiton Bueno
17/09/2017 14:40

Cleiton, esses dias eu fiz dois códigos usando o controle PWM. Um usando dois leds, um aumentava a sua luminosidade ao mesmo tempo que o outro iria diminuindo quando chegava nos seus limites retornavam ao estado inicia.O outro, eu controlava o duty cycle usando dois botões, um para aumenta e outro para dimunuir. Ficaram bem simples e interessantes para usuários iniciantes como eu. Se quiser, posso te envio os códigos e você faz o artigo em cima deles. Ou gostaria de sugerir, um artigo falando como usar display LCD na Raspberry, é isso que estou estudando como fazer agora. Abraço!

Cleiton Bueno
Reply to  Roniere Rezende
18/09/2017 10:51

Legal Roniere, tenho uma proposta melhor para você, porque tu não escreve um artigo para o Embarcados? Eu ajudo na revisão.

Roniere Rezende
Roniere Rezende
Reply to  Cleiton Bueno
18/09/2017 11:16

Podemos pensar nisso Cleiton. Mas podemos conversar mais reservadamente sobre isso, pode me passar alguma forma de contatar você?

Roniere Rezende
Roniere Rezende
Reply to  Cleiton Bueno
25/09/2017 11:50

Cleiton, como podemos iniciar os trabalhos. Estou no seu aguardo!

Talvez você goste: