Como Usar Interrupciones en Arduino - Ejemplo Práctico
¡Bienvenido al duodécimo capítulo de este curso básico de Arduino! En el tutorial de hoy te voy a explicar un nuevo mecanismo muy útil con el que podrás mejorar tus proyectos. Sin embargo, antes de aprender a utilizar interrupciones en Arduino es muy importante que sepas crear tus propias funciones.
Qué es una interrupción o ISR
Una interrupción es un mecanismo que permite asociar una función a un evento. Cuando se produce una interrupción, el procesador sale del flujo normal del programa para atender la interrupción.
¿Qué significa todo esto? Imagina que tienes un robot móvil aspirando el suelo de tu casa. Qué pasaría si de repente el sensor que avisa al robot de si se va a chocar o no le envía un aviso de que efectivamente está apunto de chocarse.
Si utilizas una interrupción, podrías hacer que cuando el sensor de colisión se activara (evento), el robot móvil se parara o diera marcha atrás (función asociada). Al utilizar una interrupción, cuando se produce el evento, en este caso el programa del robot dejaría de hacer lo que está haciendo, y ejecutaría inmediatamente la función asociada a dicho evento.
Sintaxis de una interrupción en Arduino
Lo primero que tienes que saber es que en los modelos Arduino Uno y Nano, los únicos pines digitales que pueden producir una ISR son el 2 y 3. Los pines de interrupción de Arduino Mega son el 2, 3, 18, 19, 20 y 21.
Para activar una interrupción en Arduino simplemente tienes que utilizar la función «attachInterrupt (interrupt, ISR, mode)». El primer parámetro que le tienes que pasar a la función es el número del pin digital que va a producir dicha interrupción.
La ISR es la función que se va a ejecutar cuando se produzca el evento. Simplemente tienes que escribir su nombre, los parámetros no son necesarios. Hay 4 modos de interrupción. El primero, «RISING», hace que la interrupción se produzca cuando el pin digital pasa de 0 a 1, «FALLING» cuando pasa de 1 a 0, «CHANGING» cuando cambia de 0 a 1 o de 1 a 0 y «LOW» mientras el pin tenga un 0 en su entrada.
Programa de ejemplo de interrupciones en Arduino
El objetivo principal del programa que hay a continuación es contar las veces que pulso un botón utilizando una interrupción. Lo primero que tienes que tener en cuenta es que las variables que utilizas en una función asociada a una interrupción tienes que crearlas con la palabra clave «volatile», como es el caso de «ISRcont» y «lastTime».
En la función «void setup» he inicializado el puerto serie para poder leer las veces que pulso el botón y he configurado como entrada el pin digital de dicho botón. Además he activado la interrupción que voy a utilizar con la función «attachInterrupt».
Con la función «digitalPinToInterrupt» especifico que pin digital va a producir la interrupción, que en este caso es el pin 2. «counter» es el nombre de la función que se tiene que ejecutar cuando pulse el botón, es decir, la función asociada. En este caso como puedes ver, he elegido el modo «FALLING», así que la interrupción saltará cuando suelte el pulsador.
const int button = 2; const int threshold = 200; int cont = 0; volatile int ISRcont = 0; volatile int lastTime = 0; void setup(){ Serial.begin(9600); pinMode(button, INPUT); attachInterrupt(digitalPinToInterrupt(button), counter, FALLING); } void loop(){ if(cont != ISRcont){ cont = ISRcont; Serial.println(cont); } delay(10000); } void counter(){ if((millis()-lastTime) > threshold){ ISRcont++; lastTime = millis(); } }
Función asociada a la ISR
En este programa de ejemplo, la función asociada a la interrupción se llama «counter» y la he implementado al final del programa. Lo primero que hago es restarle a «millis» el valor que guarda la variable «lastTime» y compruebo si el resultado es mayor que «threshold».
Esto sirve para corregir el error que tiene el botón, ya que es un componente electrónico bastante barato y no es perfecto. El problema es que al soltarlo debería devolver todo ceros, pero siempre se cuela algún uno nada más soltarlo. A este error se le llama «rebote». Haciendo dicha comprobación al inicio de la función lo soluciono.
Una vez compruebo que no he recibido un falso aviso por parte del pulsador, le sumo un 1 al contador «ISRcont» y actualizo la variable «lastTime».
En la función «void loop» simplemente compruebo si el valor que guarda «cont» es diferente al de «ISRcont» y en caso de ser así lo actualizo y lo muestro por pantalla. Como puedes ver esta comprobación la hago cada 10 segundos por el «delay» que hay al final de la función «void loop».