Interrupciones en Arduino

por Ricardo Vega el 19/04/2017

Recordarás que hace pocas semanas hablábamos del modo sleep de Arduino como una de nuestras principales armas a la hora de reducir el consumo de nuestro Arduino, permitiéndonos mayores autonomías de la batería. Ya en ese artículo hablábamos que intentaríamos en un futuro ampliar esa información para tener más control sobre el modo sleep. Pues bien, hoy vamos a retomar ese tema hablando de las interrupciones.

Interruptor Off.

Lo que habíamos visto del modo sleep, se centraba en programar un tiempo en estado "dormido" tras el cual, se ejecutaba una rutina y el Arduino volvía al estado "sleep". Mientras estuviera dormido Arduino, no podríamos interactuar con él, teniendo que esperar a que transcurra el tiempo que hemos fijado y vuelva a "despertar".

Gracias a las interrupciones, vamos a poder parar cualquier ciclo de ejecución (ya sea despierto o dormido) para hacer algo concreto que "urge". Un ejemplo típico es un sensor que toma una medida cada 5 minutos y la envía a un servidor (sería el ejemplo visto en la anterior entrada) pero que además, tiene un botón que permite, una vez pulsado, ejecutar la lectura y envío de la misma independientemente de si estamos o no dormidos. Es decir, al pulsar un botón, se interrumpe todo y se hace "algo" que tenemos configurado.

Estas interrupciones son parte de la configuración y se fijan en el setup inicial mediante la siguiente instrucción: attachInterrupt(digitalPinToInterrupt(sensor), handler, CHANGE);

En dicha sentencia, podemos apreciar:

  • digitalPinToInterrupt(sensor): función de Arduino que devuelve a que interrupción corresponde un determinado pin ya que no todos los pines de Arduino pueden ser empleados como interrupciones y no existe relación directa entre número de pin y número de interrupción.
  • handler: función que se ejecutara cuando dicha interrupción sea detectada. Hablaremos de ella a continuación.
  • CHANGE. Existen diferentes tipos de interrupción a saber:
    • LOW: la interrupción se dispara cuando el pin está en estado LOW.
    • CHANGE: cuando pase de HIGH a LOW o viceversa. (usada en nuestro caso al querer detectar cualquier cambio).
    • RISING: dispara en el flanco de subida (al pasar de LOW a HIGH).
    • FALLING: Dispara en el flanco de bajada (al pasar de HIGH a LOW).

Un detalle muy importante a destacar es como al dispararse una rutina de interrupción, ésta tiene prioridad sobre cualquier otra tarea que esté ejecutando el microcontrolador. La prioridad se manifiesta llevando a cabo una acción y haciéndolo lo más rápido posible por lo que también se ignoran los sleep o los sleepMillis de la API de Arduino.

Esta situación nos lleva a una posible dificultad si nuestro código precisa de esperas para la estabilización de componentes (por ejemplo transistores del circuito) o conversores Analógico-Digital internos necesarios a la hora de hacer lecturas analógicas.

Es un pequeño problema del que tenemos que ser plenamente conscientes en nuestras implementaciones para evitar errores.

Por lo demás, como vemos es muy sencillo trabajar con las interrupciones para ampliar la funcionalidad dada por el modo sleep. Ten en cuenta que las interrupciones no son parte del modo sleep y pueden ser útiles también en ejecuciones normales si queremos priorizar eventos. También ten en cuenta que aunque hablamos de un pulsador o un botón como fuente que inicia la interrupción, ésta puede ser sustituida por cualquier elemento capaz de enviar un pulso al pin que tenemos configurado como escuchador de la interrupción.

Existen algunos módulos receptores que tienen un pin habilitado para ponerse a 0 o a 1 cuando reciben señal, de forma que podríamos usarlos para "encender" el Arduino y procesar la señal que estamos recibiendo. Esta actividad, requiere de receptores especiales que cuenten con esta caracterísitica, pero abre las puertas al uso del bajo consumo no sólo en emisores, sino también en receptores, contradiciendo lo que te contaba en mi anterior entrada.

Creo que con ambos posts, puedes tener una visión bastante completa de algunas de las opciones que tenemos disponibles a la hora de reducir el consumo en un Arduino que queramos alimentar usando una batería. Como ves, a nivel teórico, no es muy complicado y hacer pequeñas pruebas de concepto no desentraña ninguna dificultad. Cuando empieces a pegarte realmente con ello, aplicándolo a proyectos reales, empezarás a ver los problemas que surgen (casi todos relacionados con el hecho de no poder usar delays en los handler de la interrupción), teniendo que pensar en alternativas.

Por eso, te invito a empezar cuanto antes e intentar integrar estas dos técnicas en tus proyectos. Está claro que para el Internet de las Cosas y la domótica, el bajo consumo es una característica muy apreciada, ¿verdad? Ya tienes por donde empezar.

Nos vemos muy pronto.

¡Saludos!

Apoya al blog


Si te ha gustado este artículo, valora apoyarme económicamente a través de Patreon, una plataforma de Micro-mecenazgo con la que puedes hacerme un donativo que ayude a la continuidad del blog. Una pequeña ayuda significa mucho. 😃

Deja tu comentario!

Permanezcamos en contacto!


¿Quieres enterarte de todas las novedades del sector? ¿Te gustaría trabajar conmigo? ¡Puedes contactar conmigo de forma muy sencilla!