Seleccionar página

Cómo Y Por Qué Usar Las Interrupciones En Arduino

por | Nov 25, 2014 | Tutoriales de Arduino

Interrupciones en Arduino
Tienes tu módulo de detección de sonido, presencia… conectado a tu Arduino y quieres activar algún motor o modificar una variable cuando suceda algo (haya ruido, entre alguien…) pero claro ¿Si no sabes cuándo va a suceder ese evento cómo haces el código? ¿Te pasas todo el día monitorizando ese pin? ¿Y si justo sucede cuando la instrucción que se está ejecutando es un delay()? ¿Y si es un sonido impulsivo (como un golpe) y no lo detectas con el código? Todos estos problemas encuentran su solución en el uso de las interrupciones. Las interrupciones en Arduino te permiten detectar eventos de forma asíncrona con independencia de las líneas de código que se estén ejecutando en ese momento en tu microcontrolador.

Tutorial Sobre El Manejo De Interrupciones

En este tutorial vas a aprender lo que se puede y no se puede hacer con las interrupciones en tu placa Arduino y de qué forma. Aprenderás cómo con unos simples pasos puedes aprovechar una de las herramientas más interesantes de Arduino (así como cualquier otro microcontrolador), con lo que seguro que muchos de tus proyectos mejorarán considerablemente (serán más eficientes y precisos).

Este (al igual que el anterior en el que te hablé de cómo usar la memoria EEPROM de Arduino) es uno de los tipos de post que más me gusta y eso se debe a que no necesitas comprar ningún módulo ni placa, es algo que ya tenías y que no sabías usar, es algo que tenías y, simplemente, estabas desaprovechando, es algo que me recuerda que te diga: ¡Conoce tu Arduino! Vale, tampoco me voy a poner en plan Bruce Lee pero en serio, gastamos mucho dinero para hacer cosas que podríamos hacer con lo que ya tenemos y usar las interrupciones en Arduino es un gran ejemplo de esto.

¿Qué Es Una Interrupción?

Una interrupción consiste básicamente en detectar detectar un evento y realizar algo en consecuencia. Tu Arduino tiene una serie de pines (podrás ver cuáles más adelante) a los que puedes asociar un módulo (un segmento de código) de modo que este se ejecute cuando en ese pin cambie de un estado a otro que tú previamente has establecido.

De hecho, seguramente ya habrás utilizado las interrupciones de Arduino sin saberlo. Cuando utilizas instrucciones del tipo millis() estás utilizando interrupciones. ¿Te suena eso de que la función millis() vuelve a 0 tras 50 días con tu Arduino conectado? ¡Exacto! Eso también se hace con interrupciones (aunque de otro tipo al que vas a ver en este post).

¿Para Qué Sirven Las Interrupciones De Arduino?

Como todos los códigos, sirve para lo que tú lo quieras usar en tu proyecto. No te ha ayudado mucho ¿Verdad? Bueno, para que te hagas un poco a la idea de para qué puedes usar las interrupciones te pongo unos cuantos ejemplos:

  • Para detectar cambios como un pulsador que ha sido presionado.
  • Para determinar cuando se ha terminado de gestionar la memoria EEPROM o Flash de tu Arduino.
  • A modo de despertador del controlador. Esta es una interesantísima funcionalidad de tu placa que te permite mantener el consumo al mínimo dejando tu Arduino en standby hasta que suceda algún evento. Con ello podrás hacer que tus baterías duren mucho más. Como esta parte es especialmente interesante, escribiré un artículo al respecto. Entre tanto, te recomiendo que le eches un vistazo a este post si quieres aprender a optimizar las baterías de tu placa.
  • Como un Watchdog. La idea es similar a la del punto anterior y espero también hacer un post sobre esto.
  • Como el complemento ideal a los módulos digitales de sonido, temperatura… que disponen de un potenciómetro que regula cuándo se activa la salida digital. Así puedes, por ejemplo, realizar un montaje simple en el que ocurra alguna acción cuando se supere un cierto umbral de sonido o una cierta distancia.

Ventajas E Inconvenientes De Usar Interrupciones

Soy de los que repiten una y otra vez los conceptos importantes así que aquí va: una interrupción es un evento asíncrono que se detecta con independencia del código que esté ejecutando en ese momento tu Arduino.

Ésto está muy bien si estás construyendo un coche que evita obstáculos ya que, si optas por el método tradicional, o vas parando cada poco tiempo los motores para medir la distancia, o es posible que, si todavía quedan muchas instrucciones por ejecutarse en tu código, cuando quieras comprobar la distancia para cambiar de rumbo, ya sea demasiado tarde (¡CRASH!). Sin embargo, utilizando las interrupciones de Arduino puedes tener tu código ejecutando las instrucciones que sean y, sólo cuando esa interrupción se active, tu programa se va al código que has asociado a esa interrupción, lo ejecuta y luego vuelve a donde estaba (a la parte del código que estaba ejecutando cuando se activó la interrupción).

Lo que te acabo de contar como una ventaja es al mismo tiempo un inconveniente. Si tu Arduino responde a la interrupción con independencia del código que se esté ejecutando ¿Qué pasa si se estaba ejecutando un delay() o una instrucción tipo millis()? Pues que tu Arduino atiende a la interrupción y vuelve por donde iba, esto es, ahora el tiempo real y el tiempo que ha pasado para tu Arduino no son lo mismo porque la interrupción se empezó a ejecutar cuando el tiempo que había transcurrido desde que conectaste tu Arduino (instrucción millis() ) eran 200ms se activó tu interrupción y ha durado 20ms pero para tu microcontrolador ese tiempo no ha existido, es decir, el valor de la función millis() no se ha incrementado y ahora no puedes fiarte del tiempo transcurrido y lo peor es que es posible que tú ni siquiera seas consciente de que la interrupción ha sucedido. ¿Y si el motor de ese coche tenía que estar encendido 200ms y nada más que 200ms?

Como te puedes imaginar, todo esto que te acabo de contar es un poco más complejo. Sin embargo, espero que haya sido suficiente para que te hagas una idea de lo que puedes esperar cuando utilices interrupciones.

¿En Qué Pines De Arduino Se Pueden Usar Las Interrupciones?

Sólo hay unos pocos pines en los que se pueden realizar interrupciones y dependen del modelo de tu placa. Aquí te dejo una lista con los pines y los nombres de las interrupciones (al existir la posibilidad de tener varias interrupciones en la misma placa, tienes que asociarles un nombre):

Pines de interrupciones de Arduino

Modos De Activar Las Interrupciones

Ahora que sabes a qué pines se pueden asociar las interrupciones en Arduino, te falta conocer cómo activarlas, es decir, qué tiene que suceder en ese pin para que la interrupción se ejecute. Estos modos de activación los determinas tú cuando programas la interrupción y las posibilidades son las siguientes:

  • LOW: La interrupción se activa cuando el valor de voltaje del pin elegido es bajo, esto es, 0V.
  • CHANGE: La interrupción se activa cuando el pin cambia de valor, es decir, cuando pasa de LOW a HIGH o de HIGH a LOW.
  • RISING: Se activa únicamente cuando el valor del pin pasa de LOW a HIGH.
  • FALLING: Es el caso opuesto al modo RISING. Se activa la interrupción cuando el valor pasa de HIGH a LOW.
  • HIGH: Este modo solo está disponible en la placa DUE y funciona de manera opuesta al modo LOW, es decir, se activa cuando el valor de voltaje del pin es alto.

Código Asociado A Las Interrupciones

Como te he comentado antes, la gracia de las interrupciones reside en que se ejecuten una serie de líneas de código cada vez que se activa la interrupción. Para conseguir esto deberás implementar un módulo asociado a dicha interrupción.

Seguramente ya conozcas el concepto de módulo pero por si tienes alguna duda de a lo que me estoy refiriendo te diré que, básicamente, se trata de un segmento de código que se ejecuta cuando es invocado. El void setup(){} y el void loop(){} a los que seguro que estás acostumbrado son un tipo particular de módulo. Puesto que no es el objetivo de este post, no voy a explicarte en profundidad las características de los módulos pero puedes dejar tu comentario si tienes alguna duda.

Para que puedas asociar un módulo a una interrupción correctamente, éste debe cumplir unas características concretas:

  • No puede tener parámetros de entrada, es decir, no puede ser una función del tipo void f_interrupt (int entrada).
  • No puede devolver ningún valor, por tanto debe ser un módulo de tipo void.
  • Para que este segmento de código pueda interactuar con el resto de tu programa puedes crear una variable de tipo volátil (por ejemplo volatile int variable), lo que te permitirá leer el valor de dicha variable fuera del módulo asociado a la interrupción y actuar en consecuencia. Algunas de las prácticas más habituales consisten en crear una variable que cambia de estado (entre LOW y HIGH) cada vez que se activa la interrupción o un acumulador, una variable que incrementa su valor con cada interrupción y que puede ser consultada en cualquier momento por el resto de módulos.

Ejemplo Del Uso De Interrupciones En Arduino

Ya conoces todas las características que debes tener en cuenta a la hora de implementar una interrupción. Estoy seguro de que podrías hacerlo sin problemas. Aun así, aquí tienes un ejemplo de cómo se crea una interrupción en Arduino.

Supón que quieres encender un LED o cualquier otro dispositivo mediante el uso de interrupciones (recuerda que en el caso del LED debes añadirle una resistencia, puedes leer más sobre la configuración de LEDs en este post), de tal manera que cada vez que se presione un pulsador, éste se encienda.

Una vez configurado un circuito para tu pulsador como el que puedes ver, conectado al pin correspondiente de interrupción que prefieras (en este caso el pin 2, es decir, la interrupción 0), debes elegir el modo en el que se activará dicha interrupción. Aunque quizás a primera vista pienses que el modo que debes elegir es LOW, recuerda que en ese estado la función se estaría ejecutando mientras tuvieses presionado el pulsador. Para evitar esto, debes seleccionar el modo RISING o el FALLING según prefieras que tu LED se encienda al presionar o levantar el pulsador.
Diagrama de Interrupción para Arduino
Aquí te dejo el código para que veas cómo se haría.

/* EducaChip – Cómo Usar Las Interrupciones En Arduino*/
// www.educachip.com

//Se declara una variable asociada al pin en el que se va a conectar
//el LED. Se puede utilizar el valor 13 para observar el efecto de
//este código a través del LED de la placa de Arduino.
int LED = 8;

//Se declara una variable volátil que cambiará de estado en el
//módulo de la interrupción y se utilizará fuera.
//Si la variable no se utilizase fuera del módulo de la interrupción
//no sería necesario crearla de tipo volátil.
volatile int estado_actual = LOW;

//Se crea la función que se ejecutará cada vez que se active la
//interrupción. Esta función es de tipo void (por lo que no devuelve
//ningún valor) y no tiene parámetros de entrada.
void fun_cambio_estado()
{
//Se cambia al estado contrario al actual, es decir, de LOW se pasa
//a HIGH y de HIGH a LOW.
estado_actual = !estado_actual;
}

void setup()
{
//Se declara el pin digital correspondiente al LED como salida.
pinMode(LED, OUTPUT);

//Se determina la interrupción 0 (por lo que el pin asociado al pulsador
//será el 2 en caso de tratarse de un Arduino UNO o similar) a la que se
//le asocia la función fun_cambio_estado que se activará al presionar el
//pulsador (por tratarse del modo FALLING).
attachInterrupt(0, fun_cambio_estado, FALLING);
}

void loop()
{
//Se escribe el valor actual del LED.
digitalWrite(LED, estado_actual);
}

Eliminando El Efecto Rebote

Cuando presionas un pulsador el contacto producido entre el botón y la base no siempre es fijo. Normalmente se producen una serie de rebotes al cambiar de estado el pulsador que tu Arduino percibe como si hubieses presionado varias veces. Esto es un verdadero problema si estás utilizando las interrupciones de tu placa para incrementar el valor de una variable o si, como en el caso del LED, este problema provoca que, como no sabes cúantos rebotes va a haber,  el estado final de tu variable estado_actual sea desconocido.

Para evitar este problema te voy a enseñar dos posibles soluciones:

Solución Vía Hardware

Esta solución es ideal si tu sistema necesita unos tiempos de reacción cortos o no quieres cargar tu microcontrolador con más código. La idea es sustituir el circuito del interruptor por el que puedes ver en la figura.

Pulsador sin Efecto Rebote para Arduino

Solución Vía Software

Si no quieres gastar dinero en más componentes o el espacio es un factor crítico en tu proyecto, puedes modificar el código anterior añadiendo una variable de tiempo, de tal forma que justo después de que tu Arduino perciba un cambio de estado, tengan que pasar unos pocos milisegundos (deberás adaptarlo en función de tu pulsador pero un valor entorno a los 200ms debería funcionar en la mayoría de los casos) antes de que se le haga caso a cualquier otra pulsación.

Si tienes algún problema realizando cualquiera de los dos procedimientos recuerda dejar un comentario.

Información Adicional

Ahora que ya sabes cómo usar las interrupciones en Arduino, aquí tienes una serie de conceptos y tips que considero importantes:

  • Debes implementar los módulos de tus interrupciones lo más cortos y eficientes que te sea posible.
  • Sólo se puede ejecutar una instrucción de cada vez, esto es, si se está ejecutando una interrupción y se activa una segunda, no tendrá efecto hasta que la primera termine.
  • No es posible utilizar la función delay() conjuntamente con las interrupciones.
  • La función millis() no incrementa su valor durante el transcurso de una interrupción.
  • A pesar de que las funciones delay() y millis() no funcionan correctamente cuando hay activadas interrupciones, sí que puedes utilizar la función delayMicroseconds().
  • Si estás transmitiendo o recibiendo datos (Serial.begin() ) cuando se activa una interrupción, es posible que los pierdas.
  • Si quieres utilizar la variable que es modificada por tu interrupción (estado_actual) fuera de ese módulo, debes crearla de tipo volatile.
  • Puedes deshabilitar las interrupciones en cualquier momento utilizando la instrucción detachInterrupt().

Esto ha sido todo. Espero que te haya gustado el post y que hayas aprendido a usar las interrupciones de Arduino. Si tienes cualquier duda, quieres contarnos tu experiencia con las interrupciones, etc. deja tu comentario.

Por último, te recuerdo que (si te ha gustado) compartas este artículo en tus redes sociales favoritas y te suscribas al blog.

Un saludo y hasta el próximo post smile

Actualmente me dedico, entre otras cosas, a crear contenidos sobre Arduino y otros dispositivos eléctricos. Me encanta todo lo relacionado con el “Universo Maker”.

Siempre estoy activo en los comentarios. Si tienes cualquier pregunta, no dudes en dejármela en los comentarios. Intentaré responderte lo antes posible… Un abrazo smile

Enrique Romero,

Autor del post.

¿No quieres perderte nada? ¡Suscríbete!

115 Comentarios

  1. Hola Enrique:

    Me ha sido de gran ayuda tu Post y el resto de la web me esta pareciendo igualmente útil.

    Te comento una duda a ver si puedes ayudarme aun mas de lo que lo has hecho.

    Estoy utilizando un modulo de Sensor de Sonido con mi Arduino. Mi intención es detectar si se esta produciendo un ruido y cambiar una variable Bool. Al ver tu articulo pensé que lo mejor era conectar la salida digital del sensor al pin 2 o 3 y gestionar esto con una interrupción.

    Todo parece funcionar bien con ruidos cortos como palmadas. Pero con ruidos largos como silbidos y soplidos, la señal se activa y desactiva varias veces durante el silbido. Supongo que es por la frecuencia del sonido en si, aparte de un molesto efecto rebote.

    ¿Crees que esto se podría solucionar añadiendo un condensador como mencionas? Me parece que una solución por hardware es la mas conveniente.

    ¿Si es así, me podrías indicar que tipo y valor de condensador utilizar? Así como la forma correcta de conectarlo.

    Te dejo aqui el código que estoy usando:

    #define PinDigSensor 3

    volatile bool Soplando=false;

    void setup()
    {
    Serial.begin(9600);
    attachInterrupt(1, DetectaRuido, RISING);
    }

    void loop()
    {
    }

    void DetectaRuido()
    {
    Serial.print(“—-INICIO DEL RUIDO—-\n”);
    Soplando=true;
    attachInterrupt(1, NO_DetectaRuido, FALLING);
    }

    void NO_DetectaRuido()
    {
    Serial.print(“———–FIN———-\n”);
    Soplando=false;
    attachInterrupt(1, DetectaRuido, RISING);
    }

    GRACIAS UNA VEZ MAS.

    Responder
    • Buenas David,

      No creo que necesites hacer gran cosa. Seguramente lo puedas solucionar directamente aumentando el nivel de potencia del sonido (o reduciendo la sensibilidad del micrófono).

      Un saludo, Enrique.

      Responder
      • La verdad es que he intentado ajustar el sensor de todas las formas y sigo sin solucionar el problema de que emita varias señales. Crees que se podria solucionar por hardware con condensadores?

        Gracias.

      • Buenas,

        La idea de los condensadores es la de evitar un mal contacto entre las partes metálicas de un interruptor o pulsador. Puede que te llegue a funcionar si lo pones entre la salida del micrófono y la entrada de la placa (justo ese problema no lo he sufrido nunca).

        También puedes jugar deshabilitando las interrupciones, midiendo tiempos con la función millis() para evitar que cambios en cortos periodos de tiempo realicen una acción o incluso con el modo en el que se activan las interrupciones.

        Te daría una solución concreta, pero me temo que vas a tener que ir probando.

        Un saludo, Enrique.

  2. Hola Enrique muy buenos dias excelete aporte este que haces muchas felicidades,te escribo por que tengo dos dudas:
    La primera es con respecto a como eliminar el efecto rebote de un push button por medio de software? con ese push estoy disparando una interrupcion pero al verificar en el monitor serial del ide de arduino noto comportamientos inestables que atribuyo al efecto rebote.

    La segunda estoy intentando hacer que cuando la interrupcion ocurra se mande una peticion a un servidor web (tengo un modulo nodeMCU) para saber que el boton ha sido presionado desde una pagina que yo monitoreo.Sin embargo aunque me consta que la interrupcion si es reconocida (checo una varible volatil en el monitor serie)la peticion no se hace. cabe mencionar que el codigo de mi peticion lo he probado poniendolo en el modulo loop y lo realiza sin problema, Gracias de antemano y qu tengas buen dia

    Responder
    • Buenas Shecko,

      Hay muchas formas de hacerlo. Puedes meter un pequeño delay después del primer cambio en el pin de la interrupción de modo que no te capte los demás.

      Respecto a la segunda duda no sé qué decirte. Si sabes que la interrupción se está llevando a cabo, prueba a hacer la petición sin utilizar interrupciones, así puedes asegurarte de que el problema esté en el resto del código.

      Un saludo, Enrique.

      Responder
  3. Cordial Saludo: Es muy interesante tu articulo pero tengo una duda y quisiera saber si me la puedes solucionar. estoy controlando un conjunto cintas led RGB a traves de un control remoto de TV, el problema que tengo es que por ejemplo le doy la tecla numero 1 e ingresa al case correspondiente el cual enciende la cinta led con una combinacion de luces a traves de fading mediante bucles for, quisiera por ejemplo oprimir la tecla 2 y que termine donde vaya es decir sin terminar el bucle apague la cinta y que por ejemplo lleve a cabo otra instruccion.

    Responder
    • Buenas Andrés,

      Se me ocurre que puedes meter un if() dentro del bucle y hacer que, si la tecla se pulsa, el índice del for() se ponga en el último valor. Así paras el bucle.

      Un saludo, Enrique.

      Responder
  4. Hola buenas tardes, tengo un detalle con mi proyecto estoy tratando de enviar los contadores de una maquina de engomado de cajas de carton, lo que busco es enviar el dato de la Orden de Trabajo, Numero de Nomina del operador y el total de cajas que ha contabilizado mi arduino, solo que no se si deba usar interrupciones para que pregunte al operador los primeros 2 datos (partida y numero de nomina), posterior a esto empiece el sensor del arduino a contabilizar las piezas y con un boton (push boton) confirmar el termino de la partida y se envie el dato a un MYSQL, me falta experiencia en la programacion ya que me estoy adentrando en este mundo del arduino, al momento tengo el clasico ejemplo del registrador de temperatura con el LM35 enviando los registros a una tabla en MYSQL, la duda es saber si con interrupciones puedo lograr l oque busco. Gracias de antemano y muy buen aporte con tu blog.

    Responder
    • Buenas Francisco,

      No creo que sea necesario. Puedes hacer que Arduino pregunte esos datos, el trabajador los introduzca y luego ya se ejecute el programa. Es decir, leer una variable de entrada y no actuar hasta que se inserte (tienes ejemplos dentro de la propia IDE).

      Un saludo, Enrique.

      Responder
  5. Como estas Enrique te consulto sobre las interrupciones actualmente estoy trabajando con un caudalimetro de 2″ con arduino UNO y necesito que en cierto valor de caudal o Hz me realice una interrupción y se quede en cero por ejemplo un valor que va de 0 a 80 l/m o lo que corresponda a Hz si supera el valor en este caso de 80 l/m se debe ir a cero el medidor, se podrá realizar con la interrupción, espero tu respuesta, el post es muy bueno, saludos.

    Responder
    • Buenas Marcelo,

      Puedes sacar la señal con la frecuencia que necesitas, filtrarla y, si es la correcta hacer que la señal la lea la tu Arduino. Te dejo un post sobre filtros pasa banda, creo que te va a ayudar.

      Un saludo, Enrique.

      Responder
  6. Hola, muy bueno tu blog, super claro tu post.
    Queria consultarle lo siguiente, en mi proyecto estoy haciendo funcionar un motor a pasos, el cual abre y cierra una puerta a traves de dos pulsadores (uno abre y otro cierra). Y un tercer pulsador debe detener la apertura o el cierre de la puerta, en caso de X situacion. La parte de las interrupciones las entendí perfectamente, pero como puedo hacer para que el tercer pulsador detenga el movimiento del motor, y luego, el motor retroceda tantos pasos como los que se hayan ejecutado al momento de pulsar la interrupcion??
    Gracias

    Responder
    • Buenas David,

      Puedes usar una tercera interrupción. Si tus interrupciones cambian el valor de una variable “estado”, puedes hacer que esta tenga tres valores posibles (0, 1 y 2 por ejemplo). Si el valor es dos (detener apertura o cierre) se comprueba el valor previo que tenía la variable (que puedes almacenar en una variable auxiliar como “estado_previo”) con sentencias if(). Si estado vale 2 y estado_previo vale 0 la puerta se estaba abriendo, entonces ejecutas la orden de cerrar y le dices a tu motor que vaya a la posición 0. Si estado vale 2 y estado_previo vale 1, entonces la puerta se estaba cerrando y puedes decirle a tu motor que vaya a la posición de apertura.

      Espero que te haya quedado más o menos claro. smile

      Un saludo, Enrique.

      Responder
      • Buenas Enrique,
        Eres un genio! Muchas gracias, me ha quedado claro, ahora lo escribiré en código, pero se aprecia muy buena la idea.
        Muchas gracias

      • Wow! Me alegro de que te haya gustado, David. smile

        Ánimo con tu proyecto. Un abrazo.

  7. Me encanta el blog!
    Tengo unas dudas con la funcion millis.
    He leido que dices que los millis se resetean en el dia 55. Yo tengo que hacer un proyecto en el cual el arduino tiene que estar siempre encendido y para hacer delays lo hago evitando la funcion delay y uso los previusmillis y tal, no se si me explico. La pregunta es… Si se resetean como puedo validar mi codigo para que no me diera error al hacer el delay?

    Saludos!

    Responder
    • Buenas Sergio,

      Al final, lo que haces cuando trabajas con millis() es utilizar diferencias de tiempo. Puedes utilizar, por ejemplo, un if() que considere si se ha reseteado el contador y, en tal caso, volver a coger la referencia.

      Un saludo, Enrique.

      Responder
  8. Felicidades por tu blog.
    Un trabajo fantástico.

    Responder
    • Muchas Gracias. Me alegro de que te guste smile

      Responder
  9. Hola, muy bueno el post, te felicito.
    Llegue a el porque quiero leer el paso de una tecla de una vieja maquina de escribir con un sensor optico y con ello accionar un relay. El problema que tengo es que, cuando la interrupcion en el sensor optico es muy rapida no funciona, si cuando la interrupcion es por mas tiempo. Como puedo acelerar esa lectura?
    Desde ya mil gracias

    Responder
    • Buenas Marcial,

      Me parece muy raro lo que comentas. ¿Qué tipo de interrupción estás usando? Parece que sea cosa de un rebote o algo similar.

      Un saludo, Enrique.

      Responder
  10. Hola Enrique, muchas gracias por la información tan útil !
    Muy bien explicado todo

    Responder
  11. Un saludo de otro Graduado en Ingeniería de tecnologías de telecomunicación XD.

    Gracias por el aporte, me sirvió para capturar las interrupciones hardware para contar las vueltas que da un anemómetro y las cucharadas de un pluviómetro para mi TFG.

    Saludos.

    Responder
  12. Hola, buen trabajo el que haces, Enrique.
    Un pregunta, quizá un poco absurda.
    El modo de activación de interrupción LOW, cuando el pin siempre es low, ¿qué hace? ¿llama constantemente a la función de interrupción?
    ¿cuál es la diferencia entre LOW y FALLING?

    Gracias.
    .

    Responder
    • Buenas Carlos,

      LOW activaría la interrupción siempre que el valor fuera bajo y FALLING activaría la interrupción únicamente en el momento justo en el que se pase de un valor alto a uno bajo.

      Un saludo, Enrique.

      Responder
  13. He revisado para arduino si existe una opción que me permita incrementar el valor de una variable en “1”, la cual esta asociada a un pin de entrada y que solo se incremente durante un flaco (subida o bajada) sin ninguna relación con interrupciones. Es la mejor forma de contar la ejecución de un suceso.
    Agradezco una respuesta a quien la tenga.

    Responder
  14. Buen día, felicidades y muchas gracias por la claridad de tu explicación, ha sido la mejor en lo que llevo buscando información respecto a los rebotes manejados mediante interrupciones, pero ¿que crees? en no me aparece el código ejemplo precisamente de los rebotes solo aparece una linea horizontal y nada mas donde debería ir el código vía software. Ojala se pueda.

    Responder
    • Buenas Héctor,

      Creo recordar que dejé el código en uno de los comentarios previos.

      Un saludo, Enrique.

      Responder
  15. Hola Enrique, he estado al tanto de tu página y he encontrado cosas muy buenas. Tengo una pregunta acerca de un proyecto que estoy realizando. Necesito sensar una variable por un tiempo y si en ese tiempo se cumple la condición que haga algo, es bastante sencillo. Por ejemplo con una fotorresistencia, necesito que el arduino se cerciore de que haya x cantidad de luz durante 1 minuto, si es así pongo en 1 algún pin. Espero me puedas ayudar con este asunto. Saludos

    Responder
    • Buenas Juan David,

      Puedes hacer, por ejemplo, que la cantidad de luz active dos interrupciones (una cuando el voltaje supera un valor y otra cuando pasa a estar por debajo de dicho valor) y que éstas guarden los momentos en los que se hizo.

      Un saludo, Enrique.

      Responder
  16. hola excelente post te felicito tengo una consulta y creo que me puedes ayudar deseo realizar un horometro electrónico pero este horometro revisara varios estados a la vez de diferentes funciones por lo cual existirá en algún momento 5 o 6 señales activas juntas a la vez y necesito estar contando el tiempo de activación de estos estados sin perder el tiempo ni de uno ni de otro necesito estar monitoreando todos a la vez la consulta es se puede realizar a travez de las interrupciones??.

    Responder
    • Buenas Roberto,

      Si te fijas en el código del funcionamiento de la instrucción millis(), verás que se utilizan variables para ir gestionando los tiempos. Puedes usar esta idea para tener tu contador de tiempo corriendo y almacenar en variables los momentos en los que tus motores cambiaron de estado.

      Un saludo, Enrique.

      Responder
  17. Hola, te envió saludos y agradecimientos por tu conocimiento y tiempo brindados.
    Me fue de mucha ayuda.

    Responder
    • Buenas Lautaro,

      Me alegro de que te haya sido de utilidad el blog. smile

      Un abrazo, Enrique.

      Responder
  18. Hola Enrique, te felicito por tus excelentes blogs.
    Quisiera saber si se podría utilizar una interrupción relacionada al tiempo, me explico.
    Tengo una Yun y con una rutina obtengo la datetime en string desde Linino cada segundo. Convierto la string en int para la hora y los minutos y los comparo con una hora fija (8:00AM). Cuando son las 8 de la mañana, se genera un pulso de 900 ms y se activa un relay el cual abre una puerta. El problema está en que el relay empieza a pulsar durante un minuto por lo tanto me veo obligado a parar la rutina con un delay de 61 segundos (hasta que la hora cambia a 8:01). No comparo los segundos porque podría pasar este instante y la puerta no se abriría.
    Siendo una Yun, no quiero utilizar las librerías time y timesAlarms.
    Dicho eso y volviendo a mi pregunta inicial, se podría usar una interrupción en este caso y, de ser así, cómo?
    Gracias y un saludo.

    Responder
    • Buenas Walter,

      Disculpa la tardanza en contestar.

      Puedes intentar solucionarlo con la función millis(), utilizando la idea de ir restando tiempos que tienes en el código del post.

      Un saludo y ánimo con el proyecto, Enrique.

      Responder
  19. Pues es un excelente post, bien explicado, en palabras faciles de entender para los que comenzamos en el tema de la programacion, y revisando los comentarios siempre estas en contacto con los que comentan.

    Responder
    • Buenas Rafael,

      … Y justo te ha tocado a ti que haya tardado en contestar, ya lo siento. He estado un poco ocupado :P.

      Me alegro de que te esté gustando el blog.

      Un abrazo, Enrique.

      Responder
  20. Buenas Enrique,
    Me he metido en el mundo del arduino para hacer un regalo y ando algo perdida. Podrías facilitarme un e-mail para poder comentarte y enviarte lo que quiero hacer? la verdad que no sé por donde empezar.
    Gracias!

    Responder
    • Buenas Edurne,

      Puedes escribirme desde la sección de contactos del blog (así evitamos que queden los emails publicados).

      Un saludo, Enrique.

      Responder
  21. Hola!

    Primero gracias por tu tiempo y enhorabuena por tu web smile
    Si quisieras meter un retardo dentro de la interrupción, ¿como podrías hacerlo?
    Pongamos el caso de que está detectando si una puerta se abre, y si lo hace cuenta si se queda abierta mas de X segundos para avisarte de alguna forma. Como se implementara ese “comprueba si esta interrupción lleva X segundos” ?

    Muchas gracias!

    Responder
    • Buenas Miguel,

      Desde dentro de la interrupción puedes cambiar el valor de una variable que leas fuera para controlar ese tiempo.

      Un saludo, Enrique.

      Responder
  22. Hola, Enrique.
    Excelente explicación. Muy clara y didáctica, sobre todo para quienes no somos del mundo de la electrónica.
    Te molesto con una consulta.
    Estoy utilizando un Arduino Mega 2560 con un módulo de RFID (pn532) y una shield ethernet. Lo que necesito hacer es que cuando alguien apoye una tarjeta en el lector RFID se envíe el tag, a través de la shield ethernet, a una aplicación en una pc para que valide el tag y devuelva a la shield el resultado (habilitar/no habilitar).
    Había pensado en estar monitoreando constantemente el lector para que, una vez detectada una tarjeta, se desencadene toda la secuencia de transferencia y recepción hacia y desde la pc, para luego, llegado el caso, abrir el molinete (a través de un relay con un solenoide y finalmente retomar el monitoreo del lector RFID.
    Esto, claro, hasta que leí tu post sobre interrupciones. ¿Será mejor hacerlo con interrupciones?
    Muchas gracias por tu post y por leer mi comentario/consulta.

    Jerónimo

    Responder
    • Buenas Jerónimo,

      Si puedes sí. La verdad es que ahora que lo dices nunca me he puesto a ver la compatibilidad de las interrupciones con ese shield. Si te decides a probarlo, haz el favor de comentármelo. smile

      Muchas gracias, Enrique.

      Responder
      • Hola, Enrique.
        Haré algunas pruebas y luego volveré aquí para compartir los resultados obtenidos.
        Muchas gracias.

        Jerónimo

  23. Buenos días Enrique, tengo un Arduino Duemilanove, y quiero medir el tiempo entre dos pulsaciones de la misma señal, para calcular el tiempo de paso de un motor paso a paso. Necesito duplicar la velocidad de giro de un eje respecto de otro. Que funcion utilizarías? soy totalmente nuevo en esto.

    Responder
    • Buenas Jonatan,

      Para calcular el tiempo que ha transcurrido entre dos acciones puedes utilizar la función millis().

      Un saludo, Enrique.

      Responder
  24. Hola Enrique, lo primero gracias por estas explicaciones. Una duda que tengo con el puerto Serie. Si yo quiero que el arduino ejecute una interrupción cuando le llega algo por el RX y el resto del tiempo esté descansando, ¿cómo podría hacerlo? ¿Se podría hacer algo similar para cuando quiero transmitir algo por el TX del puerto Serie?
    Un saludo, gracias

    Responder
    • Buenas Samuel,

      Échale un ojo a la librería de comunicación serial, seguramente verás instrucciones y módulos que te sirvan.

      Un saludo, Enrique.

      Responder
  25. Hola Enrique, consulta ¿Para eliminar el efecto rebote vía software, poner un delay (o millis( )) de 40 milisegundos entra en conflicto? Solo para llamar a la función que me cambia el estado (attachInterrupt(0, fun_cambio_estado, FALLING);). Muchas gracias

    Responder
    • Buenas Pablo,

      Para evitar conflictos puedes utilizar la función delayMicroseconds().

      Un saludo, Enrique.

      Responder
  26. Hola Enrique, muy bueno tu post. ¡Habrá mucha gente agradecida, seguro!

    Tengo un problema que creo que puedo solventar con interrupciones pero no sabría cómo hacer ya que estoy usando un módulo GSM que ocupa los pines de interrupción y no podría utilizarlos.
    Cuento mi problema: tengo implementado un sketch que, en algún momento de éste, se para y espera a leer un localizador con un lector de código de barras a través de un usb. Se queda para aquí: “usb.Task()”. Y hasta que no lee el localizador, no sigue corriendo el sketch. Pero me gustaría que si se tirara mucho tiempo esperando el localizador hiciera otras cosas.
    ¿Tendrías una idea?

    Muchísimas gracias.
    Mando el ejemplo del sketch de la librería USB-Host.

    “”””””””””
    /*
    Keyboard Controller Example

    Shows the output of a USB Keyboard connected to
    the Native USB port on an Arduino Due Board.

    created 8 Oct 2012
    by Cristian Maglie

    http://arduino.cc/en/Tutorial/KeyboardController

    This sample code is part of the public domain.
    */

    // Require keyboard control library
    #include

    // Initialize USB Controller
    USBHost usb;

    // Attach keyboard controller to USB
    KeyboardController keyboard(usb);

    // This function intercepts key press
    void keyPressed() {
    Serial.print(“Pressed: “);
    printKey();
    }

    // This function intercepts key release
    void keyReleased() {
    Serial.print(“Released: “);
    printKey();
    }

    void printKey() {
    // getOemKey() returns the OEM-code associated with the key
    Serial.print(” key:”);
    Serial.print(keyboard.getOemKey());

    // getModifiers() returns a bits field with the modifiers-keys
    int mod = keyboard.getModifiers();
    Serial.print(” mod:”);
    Serial.print(mod);

    Serial.print(” => “);

    if (mod & LeftCtrl)
    Serial.print(“L-Ctrl “);
    if (mod & LeftShift)
    Serial.print(“L-Shift “);
    if (mod & Alt)
    Serial.print(“Alt “);
    if (mod & LeftCmd)
    Serial.print(“L-Cmd “);
    if (mod & RightCtrl)
    Serial.print(“R-Ctrl “);
    if (mod & RightShift)
    Serial.print(“R-Shift “);
    if (mod & AltGr)
    Serial.print(“AltGr “);
    if (mod & RightCmd)
    Serial.print(“R-Cmd “);

    // getKey() returns the ASCII translation of OEM key
    // combined with modifiers.
    Serial.write(keyboard.getKey());
    Serial.println();
    }

    void setup()
    {
    Serial.begin(9600);
    Serial.println(“Program started”);
    delay(200);
    }

    void loop()
    {
    // Process USB tasks
    usb.Task();
    }
    “”””””””””

    Responder
    • Buenas Ricardo,

      ¿Has pensado en utilizar la placa Leonardo o la DUE que tienen más pines de interrupción?

      Un saludo, Enrique.

      Responder
      • Hola Enrique, muchas gracias por contestar.

        Tengo que utilizar esta placa, sí o sí.
        Estoy trabajando en una empresa y ya están todas compradas.
        Yo soy el desarrollador del proyecto.

      • Buenas de nuevo,

        Podrías intentar tirar por programar vía AVR pero va a ser mucho trabajo, eso sí.

        Un saludo, Enrique.

  27. En caso de utilizar una entrada análoga. Por ejemplo al utilizar una LDR o un LM35 ¿Como seria el uso de interrupciones en ese caso?

    Responder
    • Buenas,

      Las interrupciones están asociadas a pines concretos. No puedes (en principio) utilizar interrupciones de ese tipo.

      Si tienes idea de utilizar muchas interrupciones te recomiendo que le eches un ojo a la placa DUE.

      Un saludo, Enrique.

      Responder
  28. Buen aporte, las interrupciones son importantes en procesos críticos aún no se hacen demasiadas aplicaciones industriales con Arduino pero es lo mismo que un aútomata y cualquiera debe conocer esto si desea ser un buen programador.

    Responder
    • Muy buen dato Nuño smile

      Responder
  29. gracias por las instrucciones
    por favor estoy utilizando una pantalla 4 d systems controlo cuatro resistencias y un reloj y se detiene la pantalla despume de 20 minutos que puedo hacer

    Responder
    • Buenas Jorge,

      Es difícil de saber lo que está ocurriendo con esos datos, pero me parece un problema de alimentación.

      Un saludo, Enrique.

      Responder
  30. Hola Enrique.
    A estas alturas ya no me es útil esta información, yo ya llegué a estas conclusiones a la fuerza y haciendo muchas pruebas y con muchos fracasos, el antirebote del teclado lo hice con 250ms, no sabía que se podía hacer con hardware, pero también me supone problema de espacio (como bien decías podía suceder)
    No obstante me encanta como has tratado este tema, y como lo has redactado.
    Te he castigado con un share de Facebook y un +1 de google. tongue
    Felicidades!

    Responder
    • Muchísimas gracias Pedro. La verdad es que esas cosas son imprescindibles para darle vidilla al blog.

      Un abrazo, Enrique.

      Responder
  31. Hola Enrique.
    Espero te encuentres bien.

    Me gustaría saber si puedes ayudarme con una duda.
    Al momento de querer hacer la solución del Efecto Rebote por medio de Software.
    ¿En qué parte del programa le agregas el delay()? Antes de la función atachtInterrup() o después.
    De antemano muchas gracias.

    Responder
    • Buenas Felipe,

      Debe implementarse dentro del módulo que se ejecuta cuando se activa la interrupción.

      Un saludo, Enrique.

      Responder
  32. muchas gracias por ayudarme.
    trate de construirlo y quisiera que me ayudases a verificar si esta bien lo que he querido hacer si no es mucho problema:
    int pinder = 13; //nombro los pines
    int pinizq = 12;
    int estado; //variables
    int movimiento;
    void setup() {

    attachInterrupt(0, paradaestado, RISING);//interrupcion para el boton de
    //parada de estado
    pinMode(pinder, OUTPUT); //declaro salidas de izq y der
    pinMode(pinizq, OUTPUT);

    Serial.begin(9600);//comunicacion serial

    }

    void loop() {

    movimiento = 0;//valor predeterminado
    while(movimiento == 1){
    Serial.println(“derecha”);
    digitalWrite(pinder, HIGH);
    }
    while(movimiento == 2){
    digitalWrite(pinder, LOW);//derecha apagado, se detiene
    Serial.println(“stop”);
    }
    while(movimiento == 3){
    digitalWrite(pinizq, HIGH);//izquierda encendido
    Serial.println(“izquierda”);
    }
    while(movimiento == 4){
    digitalWrite(pinizq, LOW);//izquierda encendido
    Serial.println(“stop”);
    }

    estado = 1;//defino etapa giro derecha
    Serial.println(“derecha”);
    digitalWrite(pinder, HIGH);//derecha encendido por 3 segundos
    delay(3000);

    estado = 2;//defino etapa frenado 1
    digitalWrite(pinder, LOW);//derecha apagado, se detiene por 4 seguindos
    Serial.println(“stop”);
    delay(4000);

    estado = 3;//defino etapa giro izquierda
    digitalWrite(pinizq, HIGH);//izquierda encendido por 1 segundo
    Serial.println(“izquierda”);
    delay(1000);

    estado = 4;//defino etapa frenado 2
    digitalWrite(pinizq, LOW);//parada por 2 segundos
    Serial.println(“stop”);
    delay(2000);

    }

    //la interrupcion hace que el estado de movimiento sea igual al estado que se
    //este ejecutando en ese momento, asi se habilitara el while correspondiente
    void paradaestado() {
    movimiento = estado;
    }
    ese seria el programa, si no tienes tiempo esta bien solo te pediria que me dijeras donde podria contactar a algun tipo de mentor ya que aca no tengo, y sos quien responde mas rapido y con mayor experiencia que conozco sobre el tema, muchas gracias

    Responder
    • Buenas Jose,

      Lo primero que veo es que los delay() y las interrupciones no se llevan bien :/.

      En cualquier caso, te diría que probases el código que has implementado ya que te será más sencillo ver posibles comportamientos erráticos.

      Un saludo, Enrique.

      Responder
  33. buenas enrique me gusto muchisimo tu post, soy estudiante de secundaria de electrónica y estoy empezando a usar el arduino soy bastante nuevo, todavia no lo tengo pero he empezado a estudiarlo, por q mi tiempo es corto, me fascina este amiguito por que previamente he trabajado con assembler que es mas jodido jaja, pero la idea de programar es casi la misma, y la cuestion esta aca: estoy haciendo un programa que encienda un motor, en realidad hay que verlo como que tiene 4 estados, en el primero manda un high desde un pin durante 3seg (este hara girar el motor a la derecha mediante un puente h) luego esperar 4seg (todo en low) luego 1 otro pin en high (gira a la izq) y despues esperar 2seg mas, esto se repetira ciclicamente y es como un lavarropa (der, stop, izq, stop etc) ahora , necesito 1boton de parada de estado el cual no se como asociarle la interrupcion ni la funcion por q lo q tieene q hacer es justamente mantener el estado que se esta ejecutando en ese momento, es decir, si esta girando a la der y lo presiono, se quedará girando hasta q lo vuelva a presionar o si esta en stop que siga en ese estado cuando lo presione, ese seria mi problema, y quisiera si podes, ayudarme a solucionarlo muchas gracias, perdon por los errores de ortografía smile

    Responder
    • Buenas Jose,

      Puedes introducir el código relativo a los movimientos dentro de un if() y “activar o desactivar” ese if() en función del valor de la interrupción, así conseguirás que se siga moviendo el motor al no modificarse la instrucción asociada. Es sólo una idea, seguro que dándole unas vueltas se te ocurre algo mejor.

      Un saludo, Enrique.

      Responder
  34. Hola, buenos días! Soy estudiante de mecatrónica curso el segundo semestre, me encanto tu articulo/post. Tengo una duda, estoy haciendo un proyecto en la escuela, un “pov led globe”, Estoy ocupando un arduino mega, 24 leds y un motor de ventilador . Estaba ocupando los delay pero ya veo que no era una buena idea, me gustaría ocupar las interrupciones para que el mundito se pueda ver con claridad, el problema es que no tengo idea de como ponerlo en el código sad

    int LED = 8;
    volatile int estado_actual = LOW;
    void fun_cambio_estado()
    {
    //Se cambia al estado contrario al actual, es decir, de LOW se pasa
    //a HIGH y de HIGH a LOW.
    estado_actual = !estado_actual;
    }

    void setup()
    {
    //Se declara el pin digital correspondiente al LED como salida.
    pinMode(LED, OUTPUT);

    //Se determina la interrupción 0 (por lo que el pin asociado al pulsador
    //será el 2 en caso de tratarse de un Arduino UNO o similar) a la que se
    //le asocia la función fun_cambio_estado que se activará al presionar el
    //pulsador (por tratarse del modo FALLING).
    attachInterrupt(0, fun_cambio_estado, FALLING);
    }

    void loop()
    {
    //Se escribe el valor actual del LED.
    digitalWrite(LED, estado_actual);
    }
    No entendí esa parte, donde quedo el pin 2?
    De antemano, Gracias!

    Responder
    • Buenas Pamela,

      Lo que tienes es que utilizar es simplemente el pin al que esté asociada esa interrupción de Arduino.

      Un saludo, Enrique.

      Responder
      • Gracias!! Lo intentare smile

  35. hola quetal muy bueno el post y bueno no se si me podrias ayudar estoy en un proyecto el cual consiste en un medidor de agua los datos de la lectura del sensor de flujo tienen que ser enviados atraves de un modulo gprs sim900 el problema es que el modulo gprs utiliza los pines 2 y 3 para la comunicacion con el arduino y me invalida la posibilidad de usar las interrupciones ya que el arduino uno maneja solo los pines 2 y 3 para el manejo de interrupciones te agradeceria mucho que me dieras alguna pista saludos…

    Responder
    • Buenas Wilder,

      Puedes plantearte usar un Leonardo, que es muy parecido al UNO pero tiene más interrupciones.

      Un saludo, Enrique.

      Responder
  36. Cuál es tu apellido. Lo necesito para una referencia de un reporte. Gracias.

    Responder
    • ¿Un reporte? smile

      Me apellido Romero.

      Un saludo.

      Responder
  37. Hola Enrique, Muy bueno tu aporte! Se agradece! Soy estudiante de ingeniería informática y por mi cuenta comencé a hacer proyectos con arduino y tu blog me resulta de gran ayuda. Abrazo grande

    Responder
    • Muchas gracias por los ánimos, Pablo. smile

      Responder
  38. hola Enrique.
    Te envío este mensaje para pedirte ayuda con un ejercicio de pulsadores en arduino y guardarlos en la memoria eeprom. Quisiera saber si tienes disponibilidad para hacerlo, ya que he buscado mucha información y no logro saber como hacerlo.
    Ahí te dejo mi correo para saber tu respuesta y enviarte el ejercicio.
    Gracias ante todo.

    Responder
    • Buenas,

      No tengo mucho tiempo últimamente :S pero intentaré ayudarte con las dudas puntuales que puedas tener.

      Un saludo, Enrique.

      Responder
  39. Hola Enrique, felicidades, bueno tengo una consulta no se si me salte esa parte o que paso, pero yo tenia entendido que existen distintos tipos de interrupciones, por ejemplo las externas (las que tu mencionaste en tu post) y las internas que son manejando los módulos del timmer del mismo MCU ATMEGA. Saludos!

    Responder
    • Exacto Diego,

      Hay un pequeño registro en el chip en el que se almacena si se produjo un tipo de interrupción (sea del tipo que sea) y de ser así, se ejecuta.

      Un saludo, Enrique.

      Responder
  40. Buenas, estaba programando un teclado de seguridad y queria hacer un gestor de bateria, mientras la bateria esta por encima del 20% parpadearia un led verde, y cuando estuviera por debajo del 20% un led rojo, la cosa es que estoy usando un teclado matricial conectado en los pines digitales del 2 al 9 de un arduino uno, con lo que no podria usar los pines de las interrupciones, mi duda es si podria usar la interrupcion para medir ese porcentaje de alguna manera, o si en este programa no es necesario usar interrupciones? Muchas gracias ^^

    Responder
    • Buenas Pablo,

      Puedes simplemente monitorizar el estado de la batería cada cierto tiempo o incluso ampliar los pines de Arduino para evitar este tipo de problemas, te dejo un post sobre esto.

      Un saludo, Enrique.

      Responder
  41. Excelente articulo Enrique ! gracias por compartir y enseñarnos mas cosas.

    Responder
    • Gracias a ti por leerlo, Cristian. Me alegro de que te haya gustado. smile

      Un saludo.

      Responder
  42. Hola Enrique, excelente post.
    Me gustaría hacerte una consulta sobre los antirrebotes de botones, la cuestión es que estoy haciendo un cronometro, de tal forma que cuando pase un objeto por delate de un ldr iluminado con un láser empiece a contar y cuando pase por otro pare de contar, el problema es que tengo 4 botones que controlan el valor de una variable pero el antirrebote lo hago con delays y creo que por eso hay errores en el resultado fina. Como no puedo añadir un condensador como dices en el post me gustaría arreglarlo vía software, ¿como podría evitar estos delays?
    Un saludo

    Responder
    • Buenas Pablo,

      Las interrupciones son “incompatibles” con los delays, pero sí que puedes utilizar delayMicrosecond().

      Un saludo, Enrique.

      Responder
      • Muchas gracias por responder Enrique.
        Me gustaría hacerte una pregunta más, intentando aplicar la teoría de este post, me di cuenta de que no entendía muy bien que es una variable tipo volatile int, no si me lo podrás explicar, ¿ Qué es? ¿ Cómo funciona?

        Un saludo y nuevamente muchísimas gracias.

      • Buenas Pablo,

        La instrucción volatile se utiliza para decirle al compilador que almacene la variable en la RAM en lugar de en el registro donde se almacenaría habitualmente, con ello se consigue que pueda ser accedida por acciones “externas” al sketch como son las interrupciones.

        Un saludo, Enrique.

  43. Hola que tal, me parece muy util tu post, tengo una pregunta, espero que me puedas ayudar, trabajo en un proyecto bio-médico y necesito lo siguiente:

    se estará ejecutando una rutina en el arduino, pero al momento de que por bluetooth, por medio de una app, se mande un caracter, se pase a ejecutar las ordenes que se mandan del celular y se dejen de ejecutar las rutinas que se estaban ejecutando, la pregunta sería, como hago para que la interrupción me detecte ése caracter, leí que comentaste algo de serialEvent….

    espero me puedas ayudar, gracias y excelentísima página

    saludos

    Responder
    • Buenas Arroyo Rivera,

      El serialEvent(){} es una función que se activa cuando se reciben datos. Puedes implementar instrucciones dentro de ésta (entre los corchetes) como sería, por ejemplo, Serial.read() para que (cuando recibas datos) los lea tu placa o los gestiones como necesites.

      Un saludo, Enrique.

      Responder
  44. Hola, el post solo hace referencia a que las interrupciones se activen según un valor binario (HIGH y LOW), si el sensor devuelve otros valores (como el sensor de temperatura y humedad DHT), puede configurarse la interrupción para que se dispare después de cada cambio de valor?
    Saludos, Claudio

    Responder
    • Buenas Claudio,

      La verdad es que no tengo demasiada experiencia con esos sensores pero si no me equivoco funcionan por comunicación serie con la placa. En tal caso lo que puedes hacer es poner el pin del sensor relativo a esa comunicación en paralelo con la base de un transistor que sea la que active el paso de un voltaje HIGH o LOW con los que regular la activación de las interrupciones.

      Un saludo, Enrique.

      Responder
  45. Muchas gracias Enrique

    Responder
  46. Tengo un proyecto de cuando se activan switch realice una accion pero tengo ocupado todos los pines, como puedo ocupar las interrupciones cuando tengo todos los pines ocupados? debido a que mi codigo es muy extenso y mientras realiza el resto del codigo y se activa un switch espera q ejecute el resto del codigo y despues activa la salida cuando regresa a la linea en la q pregunta x el switch..

    Responder
    • Buenas Jorge,

      Puedes ampliar las salidas de Arduino para dejar libres las correspondientes a las interrupciones. Te dejo un link sobre cómo realizarlo.

      Un saludo, Enrique.

      Responder
  47. Excelente post.
    Tengo la duda de como podría hacer para cambiar una variable guardada en la EEPROM mientras se ejecuta la interrupción para después utilizarla en el programa principal. Necesito guardar esta variable forzosamente en la EEPROM pues no quiero perder este dato aun cuando se quita la energía en el Arduino.
    saludos.

    Responder
    • Buenas Mirm,

      Puedes almacenar la variable en la memoria EEPROM sin problema. Te dejo un post para que te hagas una idea de cómo se haría.

      Un saludo, Enrique.

      Responder
    • Cuidado, que la EEPROM tiene un número limitado de escrituras.

      Saludos.

      Responder
  48. Hola,
    Me ha resultado muy esclarecedor este artículo tuyo Enrique. Llevo 8 años trajinando con Arduino y las interrupciones siempre me resultaron “yu yu”, hasta ahora.
    Me gusta mucho tu estilo pedagógico. Tienes madera de profe, como soy yo. Además somos colegas pues yo también soy Ingeniero de Telecomunicaciones, aunque mucho mas viejo que tu.
    Saludos.

    Responder
    • Buenas Francisco,

      Siempre es un gusto encontrarse con telecos :). Me alegro de que te haya servido el post.

      Un saludo, Enrique.

      Responder
  49. Enrique, buen tutorial. Conoces como son las interrupciones por transmisión y recepción con la USART=? gracias

    Responder
    • Buenas Jairo,

      Supongo que te refieres a las interrupciones del tipo serialEvent() en las que se realiza alguna acción tras la llegada de algún carácter… ¿Qué problema tienes exactamente?

      Lamento la tardanza. Un saludo, Enrique.

      Responder
  50. Gracias por la pronta respuesta Enrique.

    Lo que pasa es que cuando la puerta se encuentra cerrada, tendría 5Vdc en el pin y cuando se encuentre abierta tendría 0Vdc, lo que podría hacer es una interrupcion en CHANGE y luego leer el nivel de voltaje en el Pin de interrupción para saber si se encuentra abierta o cerrada. Quedaría probar que solución me consume menos bateria.

    Gracias por el comentario!

    Responder
    • Buenas Antoni,

      En ese caso, una interrupción de tipo CHANGE es buena opción.

      En cuanto a lo de leer el voltaje del pin, de eso ya se encarga la propia interrupción. Así que no debes preocuparte.

      Un saludo, Enrique

      Responder
  51. Enrique que tal, un gusto participar en tu sitio web.

    Tengo una consulta, por ejemplo necesito conocer cuando se abra y cierre una puerta mediante un reel switch, estoy pensando en hacerlo con 02 interrupciones (Falling y Rising) pero orientadas al mismo pin de interrupción, será posible asignar estos 2 modos diferentes al mismo pin? Gracias de antemano.

    Sldos.

    Responder
    • Buenas Antony,

      Para una misma interrupción sólo puedes establecer un modo de “activación”. En cualquier caso, no creo que necesites utilizar más. El hecho de que la puerta suba o baje no influye en el voltaje, es decir, si tu sensor manda 5V pasadas “x” distancias, en ambos casos (cuando abre y cuando cierra) el efecto en la interrupción es el mismo. Lo que puedes hacer es utilizar una variable booleana en la interrupción y así cuando ocurre la interrupción una vez abre y la siguiente cierra.

      Esperando haberte ayudado. Un saludo, Enrique.

      Responder
  52. Oye y que hay de las interrupciones internas ? buen post man wink

    Responder
    • Buenas Asploman,

      Si buscas hacer cosas más complejas, más cerca de lo que es el controlador, necesitas programarlo mediante AVR (sin utilizar la IDE de Arduino).

      Un saludo, Enrique.

      Responder
  53. Hola, Excelente tu post, podrías poner un ejemplo de interrupción por software? es que no me quedó claro sobre cómo usarlas, soy nuevo en esto gracias por la paciencia

    Responder
    • Buenas Oscar,

      ¿A qué te refieres exactamente con interrupción por software?

      Un saludo, Enrique.

      Responder
  54. Hola Enrique. Muchas gracias y Enhorabuena por tu post, es lo mas claro y conciso que he leído referido a las interrupciones en Arduino. Ahora solo me queda revisar todos mis sketch es y modificarlos xd

    Responder
    • Buenas Jukar, me alegro de que te haya gustado.

      Espero que no sean muchos sketchs sino… ¡Vaya curro! pero seguro que notas la diferencia smile

      Un saludo, Enrique.

      Responder

Enviar un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Cómo Y Por Qué Usar Las Interrupciones En Arduino was last modified: Diciembre 14th, 2016 by Enrique

¿Me ayudas?

Hey! Espero que te esté gustando el artículo. ¿Me ayudarías compartiéndolo con tus amigos? Un pequeño paso para ti, un gran paso para EducaChip. :) ¡Gracias!