lunes, 28 de septiembre de 2015

Interrupciones externas en Raspberry Pi con Python

A partir de la versión 0.5.6 de la librería RPi.GPIO es posible utilizar rutinas de interrupción externas. Como los usuarios de microcontroladores experimentados deben saber, una rutina de interrupción permite ejecutar una o una serie de instrucciones sin perder tiempo en bucles de lectura. Es decir que si el procesador se encuentra ejecutando una tarea, éste pausará el proceso en curso y ejecutará la rutina de interrupción ante un flanco de subida o bajada ocurrido en un pin GPIO. Si no has comprado tu Raspberry recientemente y no has actualizado su software es recomendable hacerlo:

sudo apt-get update 

sudo apt-get upgrade #(Esto podría tardar hasta más de una hora)

El siguiente código es un ejemplo sencillo sobre el uso de interrupciones. Tenemos dos rutinas de interrupción CuentaA() y CuentaB() asociadas a GPIO23 y GPIO24 respectivamente. Cada una incrementan una variable de conteo y muestran el resultado en consola. El programa se detiene cuando el contador A es mayor o igual a 5. Para más detalles sobre interrupciones pueden revisar la documentación de la librería RPi.GPIO. Para evitar el el efecto de rebote se utilizan capacitores de entre 22 o 10 uF conectados en paralelo con las resistencias pulldown de 10K como se muestra en el circuito [aunque también puede utilizarse un debounce vía software agregando el argumento bouncetime=200 a la función add_event_detect()]:
import RPi.GPIO as GPIO
import os

contaA = 0
contaB = 0

#Setup
GPIO.setmode(GPIO.BCM)
GPIO.setup(23,GPIO.IN)
GPIO.setup(24,GPIO.IN)

#Callbacks
def CuentaA(channel):
    global contaA
    contaA += 1
    os.system("clear")
    print "Contador A: ", contaA
    print "Contador B: ", contaB

def CuentaB(channel):
    global contaB
    contaB += 1
    os.system("clear")
    print "Contador A: ", contaA
    print "Contador B: ", contaB

#Interrupciones
GPIO.add_event_detect(23, GPIO.RISING, callback = CuentaA)
GPIO.add_event_detect(24, GPIO.RISING, callback = CuentaB)

print "Contador A: ", contaA
print "Contador B: ", contaB

#Bucle principal
while(contaA < 5):
    pass

GPIO.cleanup()

No hay comentarios: