Arduino cuenta con un buen repertorio de funciones para trabajar con el tiempo. Una de ellas es millis(), una instrucción que te da el tiempo en milisegundos desde que se enciende la placa Arduino. Esto puede parecer algo absurdo, y que solo sirve para saber cuándo se encendió la placa, pero lo cierto es que tiene muchas más aplicaciones prácticas.
Por ejemplo, te puede servir para determinar el tiempo que ha pasado entre dos o más eventos, evitar el debounce (rebote) de un botón, etc. También podría servir para mostrar el tiempo de ejecución en etapas críticas del código, asegurando que el programa funciona en tiempo real.
Función millis()
Como ya he comentado, la función millis de Arduino sirve para medir el tiempo, y lo hace en milisegundos (ms), de ahí su nombre. Dicho de otro modo, el valor numérico que devuelve esta función cuando la incluyes en tu sketch es un dato temporal expresado en esa unidad.
Debes saber que el valor máximo de esta variable es unsigned long, es decir, larga sin signo. Eso es importante, ya que si se usa otra más pequeña podrían ocurrir problemas de lógica. Además, debes saber que puede prolongarse hasta 50 días de tiempo (4.320.000.000 ms), una vez llegado a ese valor se reiniciará y comenzará nuevamente de cero.
Otra de las cosas que tienes que saber es que la función millis no usa parámetros.
Otras funciones temporales de Arduino
Arduino cuenta con otras funciones referentes al tiempo para que puedas usar en tus códigos. Una de ellas es la famosa delay(), pero hay más:
- delay(): es la más utilizada y común de todas las funciones de Arduino. También usa los milisegundos como millis(). Y también será de tipo unsigned long, además de no tener un valor de retorno. Se usa principalmente para introducir pausas en la ejecución de un programa, con numerosas aplicaciones.
- delayMicroseconds(): es menos usada en los sketches, en este caso sigue siendo unsigned long, sin valor de retorno, y en este caso usa microsegundos. Actualmente se puede conseguir un valor máximo con precisión de 16383, y la mínima de 3μs. Si tienes que manejar esperas mayores que esa se recomienda usar delay().
- micros(): también devuelve un valor numérico en microsegundos (μs) desde que la placa Arduino empezó a ejecutar el programa. Es decir, es como millis(), pero con otra unidad. De hecho, también usa el tipo unsigned long y tampoco usa parámetros. Pero tiene algunas diferencias adicionales, como que se resetea y comienza de cero cuando llega a 70 minutos. En cuanto a su resolución de 4 μs, o dicho de otro modo, el valor que devuelve siempre será un múltiplo de cuatro (4, 8, 12, 16,…). Recuerda que 1000 μs equivalen a 1 ms y 1.000.000 a 1 s.
Ejemplos de millis() en Arduino IDE
Todo esto son palabras, y como mejor se ve la función millis() es mostrando algunos ejemplos de sencillos sketches en Arduino IDE para que veas algunas aplicaciones y casos de uso. Así que aquí tienes algunos ejemplos prácticos…
1-Ejemplo para explicar el uso de millis():
unsigned long inicio, fin, transcurrido; // Declarar las variables a usar void setup(){ Serial.begin(9600); //Iniciar la comunicación serial } void loop(){ inicio=millis(); //Consultar ms desde que inició la ejecución del sketch delay(1000); //Espera 1 segundo fin=millis(); //Consultar ms fin del sketch transcurrido=fin-inicio; //Calcula el tiempo desde la última lectura Serial.println(transcurrido); //Muestra el resultado en el monitor serial delay(500); //Esperar medio segundo }
Medir el tiempo entre dos mensajes seriales:
unsigned long tiempo1 = 0; //Declaramos las variables e iniciamos a 0 unsigned long tiempo2 = 0; unsigned long diferenciaTiempo = 0; void setup() { Serial.begin(9600); Serial.println("Envía la letra A/a por la terminal serial"); } void loop() { if(Serial.available() > 0){ char datoRecibido = Serial.read(); if(datoRecibido == 'A' || datoRecibido == 'a'){ tiempo1 = millis(); Serial.println("Envía la letra B/b por la terminal Serial"); } else if(datoRecibido == 'b' && datoRecibido == 'B'){ tiempo2 = millis(); diferenciaTiempo = tiempo1-tiempo2; Serial.print("El tiempo transcurrido entre el primer y último dato enviado es: "); Serial.print(diferenciaTiempo); } } }
Hacer titilar un LED con millis():
int estadoLed; //Almacena el estado del LED (Encendido o apagado) int periodo = 100; //Tiempo que está el LED encendido o apagado unsigned long tiempoAnterior = 0; //Almacena tiempo de referencia para comparar void setup() { pinMode(13,OUTPUT); //Configura el pin 13 como salida para el LED } void loop() { if(millis()-tiempoAnterior>=periodo){ //Evalúa si ha transcurrido el periodo programado estadoLed=!estadoLed; //Cambia el estado del LED cada 100ms digitalWrite(13,estadoLed); //Actualiza el estado del LED al actual tiempoAnterior=millis(); //Almacena el tiempo actual como referencia } }
Crear un simple secuenciador para que envíe texto por el monitor serial en distintos intervalos de tiempo usando millis():
#define INTERVALO_MENSAJE1 3000 #define INTERVALO_MENSAJE2 5000 #define INTERVALO_MENSAJE3 7000 #define INTERVALO_MENSAJE4 15000 unsigned long tiempo_1 = 0; unsigned long tiempo_2 = 0; unsigned long tiempo_3 = 0; unsigned long tiempo_4 = 0; void print_tiempo(unsigned long tiempo_millis); void setup() { Serial.begin(9600); } void loop() { if(millis() > tiempo_1 + INTERVALO_MENSAJE1){ tiempo_1 = millis(); print_tiempo(tiempo_1); Serial.println("Soy"); } if(millis() > tiempo_2 + INTERVALO_MENSAJE2){ tiempo_2 = millis(); print_tiempo(tiempo_2); Serial.println("Un mensaje"); } if(millis() > tiempo_3 + INTERVALO_MENSAJE3){ tiempo_3 = millis(); print_tiempo(tiempo_3); Serial.println("De"); } if(millis() > tiempo_4 + INTERVALO_MENSAJE4){ tiempo_4 = millis(); print_tiempo(tiempo_4); Serial.println("Esperanza"); } } void print_tiempo(unsigned long tiempo_millis){ Serial.print("Tiempo: "); Serial.print(tiempo_millis/1000); Serial.print("s - "); }
Ya sabes que para más información puedes descargar el curso gratis de programación de Arduino en PDF.