009
Interrupciones
Las interrupciones son un tipo de «mecanismo» que interrumpe la ejecución normal de un programa para atender un evento. Los eventos que puede atender un Arduino son:
•Evento por señal (evento externo)
•Tiempo
•Comunicación
Las interrupciones son similares a una función; la diferencia estriba en que las funciones que hemos programado tenían que ser «llamadas» desde una parte del programa. Una interrupción no es más que una función que se ejecutará, no por ser «llamada», sino porque se configura para que, ante un evento se ejecute.
El primer tipo de interrupciones que estudiaremos son las interrupciones ante un evento externo. Estas interrupciones están pensadas para dar una respuesta rápida ante un evento crítico o relevante.
Como se mencionaba al principio, las interrupciones son funciones que se ejecutan por haber sido previamente configuradas; por lo tanto, es por donde tenemos que empezar.
1.Este tipo de interrupciones necesitan configurar tres parámetros:
•El pin en donde se puede producir el evento.
•El nombre de la función que se ha de ejecutar si ocurre el evento.
•El tipo de evento que ha de ocurrir.
2.Por ejemplo, un evento crítico puede ser una parada de emergencia. Para que se ejecute una interrupción por evento externo, tenemos que tener una señal que nos indique que ha ocurrido algo, como es lógico, esa señal se ha de conectar a uno de los pines del Arduino, con lo que tenemos que indicar por programación en qué pin está conectada esa señal.
3.Como lo que, al fin y al cabo, lo que se va a ejecutar es una función, será necesario indicar el nombre de la función que se ha de ejecutar.
4.El último parámetro es el tipo de evento, cuando recibimos una señal tenemos que saber que comportamiento de esta nos indica que hay que atender a un evento: señal a nivel alto, a nivel bajo, flanco de subida…
5.La instrucción <<attachInterrupt(,,)>> permite programar interrupciones por evento externo; necesita los tres parámetros que se han mencionado en el primer punto (siguiendo el mismo orden).
Antes de continuar, hay que revisar ciertas peculiaridades de este tipo de interrupciones:
•No se pueden atender eventos en todos los pines: en el caso del Arduino UNO, disponemos de dos pines que pueden atender eventos por interrupción y son los pines 2 y 3 que en el parámetro correspondiente de la función anterior, se configurarán como 0 y 1, respectivamente.
•El nombre de la función que programamos tiene que respetar las mismas reglas que cualquier otra función.
•Tenemos una serie de palabras reservadas para indicar el tipo de interrupción:
•LOW: si configuramos la interrupción con este parámetro, se ejecutará la función cuando el pin reciba una señal a nivel bajo.
•CHANGE: si configuramos la interrupción con este parámetro, se ejecutará la función cuando el pin cambie de estado, tanto si es de 0 a 5 voltios (flanco de subida) como de 5 a 0 voltios (flanco de bajada).
•RISING: si configuramos la interrupción con este parámetro, se ejecutará la función cuando el pin cambie de 0 a 5 voltios (flanco de subida).
•FALLING: si configuramos la interrupción con este parámetro, se ejecutará la función cuando el pin cambie de 5 a 0 voltios (flanco de bajada).
•HIGH: si configuramos la interrupción con este parámetro, se ejecutará la función cuando el pin reciba una señal a nivel alto. No obstante, el Arduino UNO no dispone de este tipo de evento.
La programación de este tipo de interrupciones es fácil de probar: con el siguiente montaje
010
Interrupciones por evento
Si, como en el caso del capítulo anterior, utilizamos variables que pueden ser modificadas dentro de la interrupción, estas deben tener una declaración especial, que no es más que empezar por la palabra reservada <<volatile>> y, a continuación, el tipo de variable, el nombre de esta y, si fuese necesario, se le asigna un valor
En el caso del anterior, también tenemos que tener presente que se pueden dar rebotes en la señal, por lo que tenemos que solucionarlo por hardware o software
Las interrupciones están pensadas para dar una respuesta rápida, en ellas se deben programar unas pocas líneas o, en todo caso, que el tiempo de ejecución sea corto. Es más, dentro de una interrupción no funcionan los delay; como decía, el código que se programe se ha de ejecutar rápidamente.
Disponemos de más instrucciones para trabajar con este tipo de interrupciones:
•noInterrupts() desactiva cualquier interrupción del programa.
•Interrupts() para los casos en los que se han deshabilitado las interrupciones con la instrucción anterior y queremos que se vuelvan a activar.
•detachInterrupt() desactiva la interrupción indicada: detachInterrupt ( interrupción )
•detachInterrupt (digitalPinToInterrupt (pin));
•detachInterrupt (pin) (solo Arduino DUE y CERO).
Lo que tenemos que tener presente es que, si se ejecuta una interrupción, el programa «saltará» desde la línea de código en donde se encuentre, ejecutará las líneas de código que haya dentro de la función de la interrupción y volverá a la línea del programa desde donde ha saltado y continuará con la ejecución normal del programa.
¿Qué ocurre si se da la circunstancia de que dos interrupciones suceden al mismo tiempo? Primero se debe decir que ese caso no es muy habitual, pero, dada esa circunstancia, existe lo que se conoce como «prioridades»; esto quiere decir que hay interrupciones que son más prioritarias que otras, por lo que se iría atendiendo los eventos de las más prioritarias para dejar para el final las menos prioritarias.
Cada Arduino (en concreto, cada MCU) tiene su propia lista de prioridades. De hecho, la interrupción más prioritaria es la que atiende al reseteo de Arduino; esa es la más prioritaria de todas.
También cabe mencionar que cada Arduino tiene más o menos pines,