Interrupciones de hardware con Arduino

Las interrupciones de hardware con Arduino son un tema un tanto avanzado para los que recién comienzan. Sin embargo, saber algo de ellas puede llegar a ser muy util a la hora de avanzar en nuestros proyectos. Hasta ahora, los programas se basaban en una estructura rígida de 2 funciones primarias, una setup() y otra loop(), pero las interrupciones (en este caso de hardware) nos permiten ejecutar otras funciones fuera de setup() y loop() y sin depender de ellas.

¿Qué son las interrupciones de hardware con Arduino?

Las interrupciones de hardware, como su nombre lo indica, es una manera de interrumpir un programa para que haga algo especial mediante una señal electrónica (digital). La interrupción puede activarse al estar la señal digital baja (LOW), alta (HIGH), cuando cambia (de HIGH a LOW o al reves), cayendo (cuando la señal está bajando de HIGH a LOW), o subiendo (cuando la senal esta subiendo de LOW a HIGH).

Lo interesante es que podemos hacer lo que sea necesario sin preocuparnos de la interrupción hasta que la señal es del tipo indicado. Esto es económico a la hora de programar Sketchs más complejos, los que pueden estar haciendo todo tipo de cosas y solo ocuparse de las tareas importantes cuando se activa la interrupción.

Las interrupciones de hardware en los Arduino UNO y MEGA

El Arduino UNO posee 2 interrupciones de hardware disponibles, las que estan asociadas a los pines 2 y 3. El Arduino MEGA posee además de las 2 mencionadas del UNO, 4 más correspondientes a los pines 18, 19, 20 y 21. Si bién es posible mantener el estado de los pines/interrupciones en el estado contrario a su activacion (por ejemplo HIGH cuando se activan en LOW), es siempre recomendable hacer esto mediante una resistencia de pullup.

Como probar las interrupciones

Se puede hacer una prueba muy simple y rudimentaria con un Arduino UNO o MEGA y un cable de interconexión macho-macho. El Sketch para la prueba es el siguiente:

// Interrupciones de hardware con Arduino

// Definimos el pin de interrupcion
#define INT_PIN 2

// Algunas variables auxiliares
int contador = 0;
int contadorAnterior = -1;
bool estado = true;

void setup() {
  // Inicializamos el Monitor Serial para la prueba
  Serial.begin(9600);
  Serial.println("Probando interrupciones por hardware...");
  
  // Inicializamos el pin de interrupcion como entrada con pullup 
  pinMode(INT_PIN, INPUT_PULLUP);
  
  // Adjuntamos la funcion "inter" al pint de interrupcion para que dispare la interrupcion en LOW
  attachInterrupt(digitalPinToInterrupt(INT_PIN), inter, LOW);
}

void loop() {
  // Si el contador cambio, lo mostramos por el Monitor Serial
  if (contador > contadorAnterior) {
    Serial.println(String("Contador de interrupciones: ") + contador);
   
    // Y actualizamos el contador anterior para solo mostrar los cambios 
    contadorAnterior = contador;
    estado = true;
  }

  // Revisamos todo 1 vez por segundo
  delay(1000);
}

// Funcion a ejecutar cuando la interrupcion se active
void inter() {
  if (estado) {
    contador++;
    estado = false;
  }
}

Y lo que debe hacer después de cargar el Sketch en su Arduino y abrir el Monitor Serial, es conectar el pin de interconexión en GND de su Arduino, y tocar el pin 2 con el otro extremo. Verá un contador que irá incrementándose a medida que usted conecta y desconecta el cable.

Interrupciones de hardware con Arduino

El Sketch en mas detalle

Solo explicaré un par de lineas clave de lo que está en el Sketch para comprender las interrupciones de hardware con Arduino.

Lo primero es lo que se encuentra en setup(), que es para adjuntar una función o porción de programa a una interrupción de hardware. En nuestro caso adjuntamos la interrupción del pin 2 a la función “inter” para que se ejecute cuando la señal digital del pin está baja (en LOW). Otro detalle de esa misma linea es el uso de la función digitalPinToInterrupt() para obtener la interrupción correspondiente a un pin específico. Esta función simplifica el trabajo ya que solo le pasamos el numero de pin.

attachInterrupt(digitalPinToInterrupt(INT_PIN), inter, LOW);

La otra línea significativa es la declaración de la función ya que debe cumplir unos requisitos. La función no debe recibir ningun parámetro y no debe retornar ningún valor.

void inter() {
  ...
}

Por último, dentro de la función no tiene efecto usar delay(), y la funcion millis() no incrementa sus contadores (siempre retornará lo mismo).

 

 

Deja un comentario