18

Tutorial de interrupciones con Arduino

portada_interrupciones

¡Hola, lectores! Hoy vamos a aprender cómo hacer interrupciones por hardware con Arduino. ¿Y qué son las interrupciones por hardware? Supongamos que tenemos un robot con Arduino que sigue unas instrucciones (¡prepararnos la cena, por ejemplo!). Imaginemos que hay veces en que el robot se calienta mucho. Cuando eso ocurre, queremos que se pare al instante… ¡no vaya a ser que se prenda fuego!

Sin interrupciones por hardware, nos veríamos obligados a comprobar el sensor de temperatura a cada momento. Pero con interrupciones, cuando un pin determinado recibe una señal, Arduino detiene lo que estaba haciendo y ejecuta las instrucciones de la interrupción. Podemos pensar en una interrupción como una función que puede llamarse en cualquier momento.


Material:

Para el tutorial de hoy, necesitaremos:

  • Arduino UNO/Duemilanove: Si usas otro modelo, los pines de las interrupciones variarán
  • 2x LED: yo usaré uno rojo y uno verde
  • Botón: asegúrate de que sea compatible con breadboards
  • Resistencias de 150 ohm: para proteger los LEDs y evitar errores de lectura con el botón
  • Breadboard y jumpers M/M

Manos a la obra

Empezamos por escribir el código. La idea es la siguiente: el led verde irá parpadeando hasta que alguien pulse el botón. Mientras el botón esté pulsado, se llamará a la función alarma, que encenderá el led rojo y apagará el verde. ¡Es muy fácil!


int red = 8;
int green = 5;
int boton = 2;

void setup()
{
pinMode(red, OUTPUT);
pinMode(green, OUTPUT);
pinMode(boton, INPUT);

//Creamos la interrupcion
attachInterrupt(0, alarma, HIGH);
}

void loop()
{
digitalWrite(green, HIGH);
delay(1000);
digitalWrite(green, LOW);
delay(200);
}

//Codigo de la interrupcion
void alarma()
{
digitalWrite(green, LOW);
while(digitalRead(2) == HIGH)
{
digitalWrite(red, HIGH);
delay(200);
digitalWrite(red, LOW);
delay(200);
}
}

Echemos un vistazo. En void setup() es dónde creamos la interrupción con attachInterrupt().


attachInterrupt(0, alarma, HIGH);

¿Qué significan los parámetros? 0 significa la interrupción 0, que se corresponde al Pin Digital 2. Por lo tanto, cuando recibamos una señal a través de este pin, se ejecutará la función de la interrupción.

Alarma es el nombre de la función. Cuando salte la interrupción, saltará el código de alarma.

HIGH nos dice en qué momento debe ejecutarse la interrupción. Hay varios valores posibles:

  • HIGH, cuando el pin esté a HIGH
  • LOW, cuando el pin esté a LOW
  • RISING, cuando el pin pase de LOW a HIGH. Un ejemplo puede ser el momento de pulsar un botón.
  • FALLING, cuando el pin pase de HIGH a LOW. Por ejemplo, al dejar de pulsar un botón.

Fijémonos en que el código de alarma se escribe como cualquier función. Únicamente puede ser de tipo void, no puede devolver valores. Tampoco puede recibir argumentos.

Y ahora el circuito:

interrupt_schemeUna vez construido el circuito, compilamos y cargamos el programa. Si pulsamos el botón, deberíamos ver que el LED rojo se enciende y el verde se apaga.

¿Ha funcionado? Si tenéis algun problema podéis dejarme un comentario y responderé lo más rápido que pueda.

Por otra parte, este tutorial trata los aspectos más básicos de las interrupciones por hardware. Lo justo para hacerse a la idea (¿no?). La web oficial de Arduino tiene información más detallada sobre esta función. Si os interesa el tema, ¡echad un vistazo!

N4n0

Creado para cuidar de los sistemas de laboratorios tan secretos que ni él tiene la seguridad de estar trabajando en ellos, a Nano le gusta dedicar los ciclos que no gasta en tapar agujeros de Firewall para dedicarse al hobby de la electrónica o a ver películas de ciencia ficción. Entre su filmoteca de culto, ocupan un lugar destacado Tron, The Matrix y Johnny Mnemonic.

Antes de comentar, por favor, lee las Normas

18 Comentarios en "Tutorial de interrupciones con Arduino"

avatar
Ordenar por:   más nuevos primero | más antiguos primero
Julio
Humano

y como es un ejemplo de verdad donde se active la alarma cuando el valor de un sensor de temperatura sea muy alto??
por ejemplo que cuando llegue a 60°c se active la interrupcion.???

emilio
Humano

no se mucho de arduino, pero quizas si estableces una constante de temperatura en valores digitales (LOW O HIGH) y estableces un digitalREAD( de temperatura >60 = LOW O A HIGH, o algo asi, no se en vddQUIZAS ASI SI FUNCIONE AMIGO, AUNQUE A LO MEJOR SERIA REDUNDANTE.

Julio
Humano

es que veo que solo hay la opcion de high, low, change, falling and rising. pero no una donde se mire un valor especifico.

Leonel
Humano

Tienes que hacer un if, que cuando pase los 60C ponga en HIGH algún otro pin digital en modo salida, que será el que active la interrupción. La lectura de la temperatura se hará en una entrada analógica, porque tiene un rango de valores; recuerda que los pines digitales solo leen valores DISCRETOS, 0 Y 1.

pablator
Humano

delays dentro de una interrupcion ????

jesus
Humano

Disculpa NANO, sabes si existe forma de configurar una interrupción pero en lugar de ligarla al estado de un pin, quiero ligarla a un botón de una interfaz touch

MARIO SAENZ
Humano

lo malo que este tipo de interrupciones no guardan los valores en donde interrumpes el programa todo lo reinicia de nuevo y se pierde todos los valores y estado de los pines

Rafa_RGB
Humano

Hola, (perdón por “reflotar” el hilo…)
¿¿Las variables globales pierden también los valores??

Rafa_RGB
Humano

Me auto-respondo: NO.
Ver último párrafo de la sección About Interrupt Service Routines en:
https://www.arduino.cc/en/Reference/attachInterrupt

Typically global variables are used to pass data between an ISR and the main program. To make sure variables shared between an ISR and the main program are updated correctly, declare them as volatile.

JAK
Humano

Hola Buenas Tardes, estuvo excelente la explicación y el ejemplo, gracias por tu esfuerzo 🙂

Arturo Cervantes
Humano

Hola, muchas gracias por el tema cambié muy poco el programa en esta parte
void loop()
{
digitalWrite(green, HIGH);
delay(1000);
digitalWrite(green, LOW);
delay(200);
}

Lo deje como sigue:

void loop()
{
digitalWrite(green, HIGH);
delay(200);
digitalWrite(green, LOW);
delay(200);
}

Pero no consigo igualar lo tiempos de parpadeo del led rojo (cuando se activa la alarma) y del led verde… El led verde se ve muy realentado mientras que el rojo si va a su velocidad normal. ¿Por que crees que el LED VERDE VAYA MUY LENTO?

Gracias?

Juan Lu Sanchez
Humano

Esta genial muy claro todo

wpDiscuz