Como usar interrupciones en Arduino

Publicado por Loli Diéguez en

Una interrupción, en el contexto de un microcontrolador como Arduino UNO, es una señal que detiene temporalmente el código que la CPU está ejecutando actualmente para ejecutar otro código totalmente diferente. La programación mediante interrupciones es muy diferente de la secuencia habitual de arriba a abajo en un programa Arduino y, por lo tanto, puede ser confusa para algunos. En este artículo os explicaré como funciona una interrupción y como puedes utilizarla. Además, si estás pensando en diseñar un código multitarea, las interrupciones es la forma de conseguirlo, así que sigue leyendo que te cuento como usarlas.

Un típico programa de Arduino consiste en las funciones setup () y loop ()

Estructura codigo Arduino

 

Cuando se ejecuta un sketch, la mayoría de las líneas superiores se ejecutan primero, al ser un código que se ejecuta de arriba a abajo. Entonces, lógicamente, la función setup () se ejecuta antes que la función loop (). Antes de la función setup suelen estar también las definiciones de variables y la declaración de librerías que se usen en la ejecución del sketch, así que esta parte será ejecutada antes que setup, por otro lado, la función loop () es donde definiremos lo que queremos que Arduino haga, lo que aquí escribamos será ejecutado en un bucle sin fin, por lo que no hay manera de salir de él.

Si queremos que Arduino salga de ese bucle infinito, lo conseguiremos mediante el uso de interrupciones, así que es necesario definir otra función debajo de loop que será la que contenga el código que se ejecutará cuanto se producen las interrupciones, esta función la puedes llamar como quieras, pero se suele llamar isr () . ISR es la abreviatura de rutina de servicio de interrupción en ingles y es el programa al que Arduino salta cuando hay una interrupción.

Estructura codigo Arduino con funcion ISR

 

Como os comentaba arriba, el código que pongamos dentro de la función ISR (o como la queráis llamar) se ejecutará cada vez que se produzca una interrupción y esta se producen cuando los pines específicos cambian su estado. Según la placa que estés usando los pines de interrupciones pueden variar, mira esta tabla para que sepas cual tiene tu placa:

Pines de interrupcion en Arduino

 

Te pongo un ejemplo de funcionamiento, digamos que estas usando Arduino UNO, y como vemos en la foto de arriba, el pin 2 es de interrupción y lo vamos a configurar en un estado ALTO, entonces, cada vez que su estado cambie a BAJO la interrupción se disparará y el programa saltará a la isr ().

Sigo con el ejemplo, para lo que te pongo el siguiente código y te comento las lineas importantes más abajo:

const byte ledPin = 13;
const byte interruptPin = 2;
volatile byte state = LOW;
void setup() {
pinMode(ledPin, OUTPUT);
pinMode(interruptPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(interruptPin), inter, CHANGE);
}
void loop() { //bucle
digitalWrite(ledPin, state);
}
void inter() { //rutina de interrupcion
state = !state;
}

Básicamente, un botón está conectado a un pin de interrupción. Cada vez que se presiona el botón, el pin de interrupción cambia su estado y activa la interrupción. Si no se presiona el botón, el programa permanece en la función loop (). 

Boton interrupciones Arduino

La rutina de servicio de interrupción en el ejemplo se llama inter() y contiene un código con una sola linea que hace que el LED parpadee.

void inter() { //rutina de interrupcion
state = !state;

Aquí el pin de interrupción es D2 y se le da el nombre interruptPin. Al igual que cualquier pin de entrada, el interruptPin debe ser declarado usando pinMode ()

pinMode(interruptPin, INPUT_PULLUP);

Utilizamos la opción INPUT_PULLUP para que se omita la adición de una resistencia de pull-up al botón.

A continuación, adjuntamos la interrupción utilizando la función attachInterrupt () :

attachInterrupt(digitalPinToInterrupt(interruptPin), inter, CHANGE);

La función attachInterrupt() tiene tres parámetros: primero es el pin de interrupción convertido a Interrupt utilizando la función digitalPinToInterrupt () , segundo es la función isr llamada inter, y el último es el modo que describe cuándo se activa la interrupción. Aquí, se establece en CHANGE, lo que significa que la interrupción se activa cuando el pin cambia su estado. Otras opciones posibles son:

  • LOW para activar la interrupción siempre que el pin esté BAJO
  • RISING para disparar cuando el pin pasa de BAJO a ALTO
  • FALLING para cuando el pin pasa de ALTO a BAJO

 

Ahora puedes estar preguntándote: ¿no es lo mismo que usar digitalRead() dentro del loop() ?

A priori puede parecer lo mismo, pero con digitalRead() debes presionar el botón en el momento correcto para que Arduino capture el cambio de estado. Esto podría no importar cuando la única cosa dentro del loop() es leer el estado del botón. Pero cuando tienes un montón de cosas sucediendo dentro del bucle, Arduino puede perder la pulsación del botón, pero usando interrupciones esto no pasará, ya que cada vez que se produzca una interrupción, Arduino dejará de hacer lo que está ejecutando para realizar la acción de la interrupción.

Como ves, las interrupciones son un recurso muy interesante para utilizar en tus sketch, te permitirán ejecutar un código de forma continua para pasar a otra rutina si se da un evento, como por ejemplo que un sensor IR detecte movimiento.

Espero que te guste este articulo y que puedas emplearlo en tus diseños.

 

 


Compartir esta publicación



← Publicación más antigua Publicación más reciente →