viernes, 7 de julio de 2017

Controlar un botón con Python, detectar un evento del botón (Parte 2)

En un post anterior ya vimos como detectar un evento de un botón, pero muchas veces podemos ralizar una tarea de distintas maneras. En este post os voy a mostrar otra manera de ejecutar una función usando los puertos GPIO y un pequeño programa en Python para controlar botón o pulsador, aquí os dejo una imagen del que he usado yo.



Para ello voy a usar una placa protoboard, cables de conexión, 1 botón y mi RaspberryPi. Si sois nuevos en esto os aconsejo leer los anteriores posts (del uso de los GPIO en el apartado Programación/GPIO).


1. Organización del circuito

En primer lugar vamos a ver como nos debe quedar nuestro circuito para este ejercicio. Aquí os dejo una imagen para que veáis la distribución que he usado, es la misma que en el ejercicio anterior.



si no habéis leído los anteriores post os recomiendo hacerlo (sobretodo el primero, en el que detallo el uso de las conexiones y hay un apartado al final sobre el uso de las resistencias, aquí está el link). 
Bien, como podéis ver uso el pin número 6 (cable negro para tierra, etiquetado como GROUND) y el pin número 12 (cable rojo para el positivo, etiquetado como GPIO18). 


2. Código Python

2.1 Capturar la pulsación de un botón

Para empezar vamos a crear un pequeño programa en python que al ejecutarlo nos permita detectar si se ha pulsado un botón. Si no sabéis como crear un archivo con un programa en python os recomiendo leer los post sobre programación python del apartado Programación/GPIO del blog.

En primer lugar abrimos el IDLE de Python en nuestra RaspberryPi (yo uso Python3), una vez abierto creamos un nuevo fichero (en el menú File-New File) y introducimos el siguiente código

# importamos librerias
import RPi.GPIO as GPIO
import time
# indicamos el uso de  la identificacion BCM para los GPIO
GPIO.setmode(GPIO.BCM)
# configuramos el pin 18 como entrada y activamos 
# la resistencia de activacion del pin 18 con PUD_UP
# esto hará que al presionar el botón se interrumpe
# la tensión de 3,3V del pin
GPIO.setup(18,GPIO.IN,pull_up_down=GPIO.PUD_UP)
# bucle infinito que recoge el estado de la resistencia
# del pin18, si el estado es Falso (interrupción 3,3V) 
# mostramos el texto boton presionado
while True:
    input_state=GPIO.input(18)
    if input_state==False:
        print('Boton presionado')
        time.sleep(0.2)

guardamos el archivo en una ubicación conocida (en el menú File-Save As), si es necesario apuntad la ruta por si la necesitáis usar más tarde. 

Podemos ejecutar directamente este pequeño programa presionando la tecla F5 (también se puede ejecutar des de el menú Run-Run Module)

Si todo es correcto se abre una nueva ventana de IDLE de python y empieza la ejecución, 
si presionamos el botón en la pantalla aparecerá el texto Boton presionado. Fijaos que no estamos capturando el evento de presionado del botón como en el post anterior, sino que la función dentro del bucle infinito comprueba si el estado del pin de activación ha cambiado (se ha desactivado la corriente de 3,3V) y si es así se ejecuta la función. Podéis mantener presionado el botón y por el efecto de rebote del botón veréis que la función se ejecuta más de una vez. La línea final time.sleep(0.2) sirve para evitar el rebote ya que deja en suspensión la ejecución del código durante 0.2 segundos, si queréis podéis aumentar el tiempo de latencia para mejorar el funcionamiento.
Enhorabuena, ya conocéis otra técnica para detectar la presión del botón a través del cambio de estado de un PIN. Vamos a ver algo más.

2.2 Crear un switch (on/off) con un botón

Vamos a modificar el código anterior para crear un swtich (on/off) que enciende y apaga un led. Aqui os dejo una imagen de como debe quedar el circuito




y aquí tenéis el código, en el que vamos a usar el GND, GPIO18 y GPIO23

# importamos librerias
import RPi.GPIO as GPIO
import time
# indicamos el uso de  la identificacion BCM para los GPIO
GPIO.setmode(GPIO.BCM)
# configuramos el pin 18 como entrada y activamos 
# la resistencia de activacion del pin 18 con PUD_UP
# esto hará que al presionar el botón se interrumpe
# la tensión de 3,3V del pin
GPIO.setup(18,GPIO.IN,pull_up_down=GPIO.PUD_UP)
#  configuramos el pin 23 como salida para el led
GPIO.setup(23,GPIO.OUT)
# definimos dos variables para guardar el estado del led
# por defecto el estado del led es False (apagado)
switch_state=False
# por defecto el estado anterior es True (encendido)
old_input_state=True # activada
# bucle infinito que recoge el estado del pin18
# cada vez que presionamos el botón,el estado del switch
# alterna entre True/False
while True:
    # guardo en una variable el estado del pin
    new_input_state=GPIO.input(18)
    # si el estado es False (presionado),y el estado
    # anterior es True cambiamos el valor del switch
    if new_input_state==False and old_input_state==True:
        switch_state=not switch_state
        # tiempo de demora para evitar rebote
        time.sleep(0.3)
    # guardamos el estado actual del GPIO18
    old_input_state=new_input_state
    # modificamos el estado del led
    GPIO.output(23,switch_state)

al ejecutarlo podréis activar y desactivar el led cada vez que pulsamos el botón.

Espero que os haya gustado, nos leemos pronto.