Cuando vamos a construir un proyecto con Arduino y necesitamos ejecutar tareas repetitivas, o temporizar dichas tareas para que se ejecuten en un momento determinado, la función Millis de Arduino es probablemente la mejor opción que podemos utilizar.
Puede ser que hayas llegado hasta aquí porque otra de las alternativas que contemplas es utilizar la función Delay. Si es así, solo con hacer una búsqueda rápida por internet sobre Delay para Arduino, y verás cómo afortunadamente cada vez es menos usada, ya que no es la mejor alternativa para crear tareas repetitivas, ya que lo que hace es dormir la ejecución completa del sketch Arduino.
En este artículo vamos a estudiar en profundidad la función millis() que nos proporciona Arduino, y la flexibilidad que proporciona a la hora de programar eventos temporizados en nuestro código de Arduino. ¡Vamos allá!
¿Qué es la función Millis de Arduino?
Para resumirlo en una frase, la función millis() nos permite acceder al reloj interno de nuestra placa Arduino. Al invocar la función, símplemente nos devuelve el valor actual de dicho reloj interno en milisegundos. De ahí el nombre de la función 🙂
Dicho de otra forma, el valor que devuelve la función millis() es la cantidad de tiempo que ha transcurrido desde que encendimos nuestro Arduino.
Si reflexionamos durante unos segundos, estoy seguro de que ya estás viendo las enormes posibilidades que tiene esta función. Por ejemplo, si necesitamos tomar una medida de un sensor cada 5 segundos, podemos utilizar la función millis para comprobar cuándo han transcurrido 5000 milisegundos (5 segundos) y llevar a cabo la lectura.
¿Hasta cuánto es capaz de contar?
Como hemos comentado antes, la función millis() devuelve un número equivalente a los milisegundos que va contando el reloj interno de Arduino. Y como todo número, tiene un valor máximo que puede alcanzar.
La función millis de Arduino es capaz de contar hasta un valor de 4,294,967,296 (¡wow!), y para llegar hasta ese valor es necesario que transcurran 49 días.
¿Esto quiere decir que tras 49 días, la función millis() ya no servirá en mi sketch Arduino?
Cuando el valor llega al máximo, se produce lo que en informática se denomina como «overflow». Es decir, el valor vuelve a 0 de forma interna y comienza a contar de nuevo. De esta forma, comienza de nuevo el ciclo de 49 días de forma totalmente transparente para nosotros 🙂
Millis en la línea temporal
Vamos a profundizar un poco más en la conceptualización de la función Millis, antes de ver cómo se implementa en Arduino.
Podemos pensar en la ejecución de nuestro código como una línea temporal a través de la que nos iremos desplazando, de izquierda a derecha. Esta línea temporal comienza en el segundo 0, cuando nuestro Arduino arranca, y finaliza en el «infinito», es decir cuando finalizamos al ejecución del Arduino.
En cualquier momento de la ejecución del Arduino, si invocamos a la función millis(), nos devolverá exactamente el milisegundo en el que se encuentra la ejecución. De esta forma, podemos implementar lógica en nuestro código que nos permita crear eventos repetitivos cada cierto tiempo.
A partir de aquí, podemos crear dos tipos de eventos: ejecución única (por ejemplo, una única vez cuando hayan transcurrido 5 minutos desde que se arrancó el Arduino), o eventos repetitivos (por ejemplo, que se repitan cada 20 segundos).
Eventos de ejecución única
Si por ejemplo queremos ejecutar un evento en un punto temporal determinado, podemos crear un temporizador utilizando millis() como en el siguiente ejemplo:
1 2 3 4 5 6 7 8 9 | const unsigned long say_hello_event = 1000; void setup() { } void loop() { if (millis() > say_hello_event) { // Ejecutar el evento "say_hello" } } |
Vamos a explicar este ejemplo de función millis paso a paso, desde que se inicia Arduino. En primer lugar, cuando conectamos Arduino a la corriente o le ponemos la pila, se ejecuta una única vez la función «setup», y a continuación comienza a ejecutarse la función «loop» en bucle, es decir, cuando termina la función loop, vuelve a comenzar.
La primera vez que se ejecuta el loop, el valor que devuelve millis() será inferior a 1 segundo, ya que la función setup no hace nada y se ejecutará muy rápido. La función loop continuará ejecutándose en bucle, hasta que el programa lleve 1 segundo en funcionamiento. Pasado ese tiempo de 1 segundo, la función millis() nos devolverá un valor superior a 1000 (ms), y se cumplirá la condición de nuestra sentencia «if». En ese momento, se ejecutará nuestro evento «say hello» que tenemos dentro del if 🙂
Llegar hasta este punto es muy importante, ya que hemos construido nuestro primer temporizador en Arduino utilizando la función millis.
Eventos repetitivos
El potencial de la función millis es que nos permite crear temporizadores para ejecutar eventos de forma repetida. Por ejemplo, leer la temperatura de un sensor cada 10 segundos.
Para ello, lo que vamos a hacer es utilizar millis para saber cuándo ha transcurrido el tiempo, de forma repetitiva. Os dejamos aquí el ejemplo de este temporizador utilizando millis, y a continuación vamos a explicar el sketch.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | const unsigned long intervaloLecturaTemp = 10000; // leeremos cada 10 segundos unsigned long tiempoAnterior = 0; // almacena la ultima vez que se lanzo nuestro evento void setup() { Serial.begin(9600); // nos permite depurar prints en la consola serial } void loop() { /* En cada iteracion de loop, guardamos en que momento de la linea temporal estamos con millis */ unsigned long tiempoActual = millis(); /* Comprobamos si debemos lanzar el evento */ if (tiempoActual - tiempoAnterior >= intervaloLecturaTemp) { /* Han pasado los 10 segundos => lanzamos el evento */ // LEER VALOR DEL SENSOR DE TEMP // IMPRIMIR POR CONSOLA ESTE VALOR Serial.println("Evento lanzado"); /* Se actualiza el temporizador para los siguientes 10 segundos */ tiempoAnterior = tiempoActual; } } |
Con este ejemplo de temporizador, conseguimos que nuestro evento se lance cada 10 segundos. El punto clave es gestionar correctamente la variable «tiempoAnterior», para que cuando pasen los primeros 10 segundos, podamos comprobar cuándo vuelven a pasar otros 10 segundos. Y así de forma infinita.
Conclusión
En esta entrada te hemos explicado los fundamentos de la función millis() de Arduino. No es una función que tengamos que implementar, ya que forma parte del Core de Arduino y símplemente tenemos que utilizarla cuando queramos.
A continuación, hemos visualizado una línea temporal de izquierda a derecha, que comienza cuando a nuestro Arduino le damos corriente. En ese momento, cada vez que invoquemos a la función millis() nos va a devolver el número de milisegundos que han transcurrido desde el comienzo de la ejecución. Os hemos dejado un par de ejemplos de uso de millis en Arduino.
Gracias a la potencia de esta función de Arduino, podemos crear temporizadores que nos permitan ejecutar eventos de forma recurrente. Por ejemplo, leer cada 10 segundos el valor de un sensor de temperatura que tenemos conectado al Arduino.
Esperamos que esta entrada os parezca interesante y pueda aclarar las posibles dudas. Dejadnos en los comentarios si tenéis alguna pregunta sobre el uso de millis en Arduino.
quiero hacer una lectura de un pin y en base a esa si es low o high ejecutar la función de un pin 3 y 4 pero quiero que al cabo de ejemplo 5 min apagar el pin 3 y el 4 siga activo hasta cambiar la lectura ďel pin q este leyendo, puedo ejecutar ese temporizsdo con la función milis independientemente del tiempo transcurrido desde que se inicio el energizar del arduino y solo llamándolo en base a la del pin?
Hola
Estoy haciendo un sistema para regar…
Tengo que usar el comando millis() pues tengo dos sensores que pueden interrumpir el «programa» pero no logro hacer los tiempos correctamente pues la condicional que me interrumpe los ciclos (presión) y es que si falta el agua, debo apagar la bomba y al llegar el agua, arranco la bomba nuevamente y debo volver al punto donde estaba y es eso lo que no logro.
Alguien con alguna idea??