¡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:
Una 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!
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.???
es que veo que solo hay la opcion de high, low, change, falling and rising. pero no una donde se mire un valor especifico.
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.
Hola Julio! No se puede mirar un valor específico, sólo se puede jugar con el high, low, change, etc.
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.
delays dentro de una interrupcion ????
Sip. Si queremos parpadear un LED es lo más fácil.
Aunque bien pensado, habría quedado mejor utilizando millis(). Un rato de estos voy a cambiarlo.
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
Sólo si encuentras una forma de que al pulsar el botón se envíe una señal al pin de la interrupción, si no que yo sepa no hay forma de hacerlo con Arduino…
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
Hola, (perdón por “reflotar” el hilo…)
¿¿Las variables globales pierden también los valores??
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.
Hola Buenas Tardes, estuvo excelente la explicación y el ejemplo, gracias por tu esfuerzo 🙂
Gracias JAK! 😀
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?
Porque cuando salta la interrupcion se detiene el bucle del LED verde y este se queda bloqueado hasta que Arduino ha acabado de ejecutar las instrucciones de la función alarma().
Esta genial muy claro todo