Arduino y las interrupciones: primera aproximación
Cuando un programa tiene que esperar a que ocurra un evento (p.ej. que se pulse un interruptor), tiene dos formas de hacerlo:
- polling: comprobar el estado del interruptor. Si se activa, hacer lo que sea, y mientras no se active, volver a comprobar. Es fácil de implementar, pero presenta el inconveniente de que, hasta que no se active el interruptor, el código se quedará estancado haciendo siempre lo mismo y sin poder hacer otra cosa.
- interrupciones: ir a hacer otra cosa (mismamente a dormir, para ahorrar energía), y cuando ocurra el evento que le avisen. El aviso se hace mediante una interrupción: el micro recibe una señal en una patilla y acto seguido ejecuta una función que previamente se la ha indicado.
El uso de interrupciones a veces es conveniente, a veces no, a veces es imprescindible y a veces puede ser horrible, ya que se puede recibir una interrupción en casi cualquier momento (p.ej. mientras estamos procesando otra interrupción).
Un ejemplo con Arduino. El software.
Hay formas de evitarse estos problemas, pero de momento, voy a presentar el uso básico de las interrupciones, y además lo haré desde la perspectiva del IDE de Arduino: con las directrices de Wiring, y no manipulando los registros del AVR.
En este ejemplo, primero configuramos el microcontrolador para hacer algo cuando se reciba una interrupción determinada:
void setup()
{
pinMode(pinInt0, INPUT);
Serial.begin(9600);
attachInterrupt(0,INT0_vector,RISING);
}
Lo más interesante es esto:
interrupción puede ser 0 o 1 para, respectivamente, INT0 o INT1 en Arduino Duemilanove. Arduino Mega dispone de otras cuatro interrupciones más (INT2..5). INT0 se corresponde con el pin digital 2, e INT1 con el 3.
función es la función que se ejecutará cuando se active tal interrupción. A veces se llama rutina de servicio de interrupción (Interruption Service Routine, ISR)
modo es qué se entiende por activación de la interrupción: cuando pasa a estar alta (RISING), cuando cambia de valor (CHANGE), cuando está baja (LOW) o cuando pasa a estar baja (FALLING).
Una vez ejecutemos esa función, cada vez que la patilla digital 2 (INT0) suba de nivel se ejecutará la función INT0_vector:
{
moehren++;
}
que lo que hace es incrementar una variable global:
Está declarada como volatile, para evitar que el compilador la mantenga en los registros del micro. Cada vez que se vaya a utilizar se leerá su valor de memoria, y cada vez que se escriba, se escribirá su valor en memoria.
Y mientras se reciben interrupciones, pues vigilamos a ver si cambia el valor:
{
static unsigned short oldMoehren=999;
if(oldMoehren!=moehren) {
Serial.print(“Ich hab neue Moehren gekriegt!! Sie sind schon “);
Serial.println(moehren);
oldMoehren=moehren;
}
delay(600);
}
Si el valor anterior (oldMoehren) es distinto al actual, se manda un mensaje y se actualiza su valor. En cualquier caso, a continuación se espera durante 600ms.
Acabando el ejemplo: el circuito.
Una resistencia (la mía es de 5,6K porque la tenía a mano, pero una de 10K, 1K o valores similares también son válidas) conectada a 5V por un lado y a un interruptor al otro.
El otro extremo del interruptor va conectado a GND. Así, cuando se cierre el interruptor, circulará corriente por la resistencia y por el interruptor.
La resistencia causa una caída de tensión de los 5V. de diferencia que hay, por lo que, cuando el interruptor está abierto, ambos extremos de la resistencia están a 5V. ya que no circula corriente.
Cuando el interruptor se cierra, circula corriente y los 5V. caen en la resistencia, por lo que en el extremo de la resistencia que va conectado al interruptor el voltaje es 0V.
Si finalmente conectamos un cable desde ese punto al pin 2 (correspondiente a INT0), el resultado es que cada vez que el interruptor se abra, el voltaje en ese punto vuelve a subir de 0V. a 5V., pasando la línea INT0 de bajo a alto y lanzando la función INT0_vector().

Y finalmente, la prueba
Su ejecución con el circuito:
Ich hab neue Moehren gekriegt!! Sie sind schon 1
Ich hab neue Moehren gekriegt!! Sie sind schon 2
Ich hab neue Moehren gekriegt!! Sie sind schon 3
Ich hab neue Moehren gekriegt!! Sie sind schon 6
Ich hab neue Moehren gekriegt!! Sie sind schon 7
Ich hab neue Moehren gekriegt!! Sie sind schon 9
Ich hab neue Moehren gekriegt!! Sie sind schon 10
Ich hab neue Moehren gekriegt!! Sie sind schon 11
Ich hab neue Moehren gekriegt!! Sie sind schon 13
Ich hab neue Moehren gekriegt!! Sie sind schon 15
Ich hab neue Moehren gekriegt!! Sie sind schon 16
Cada vez que se suelta el interruptor, la patilla 2 vuelve a valor alto y se ejecuta la función, incrementando la variable moehren. Posteriormente en la siguiente ejecución de loop() se detectará el cambio de valor y se notificará por el puerto serie.
¿Qué ocurre si hay dos subidas de nivel antes de que se ejecute loop() de nuevo? Pues que el valor que se notifica se habrá incrementado en dos unidades, una por cada subida.











