millis()
Contenido
Descripción
Devuelve el número de milisegundos desde que la placa Arduino empezó a ejecutar el programa actual. Este número se desbordará (volverá a cero), después de aproximadamente 50 días.
Sintaxis
millis();
Parámetros
Nada.
Retornos
Número de milisegundos desde que el programa se inició. Numero tipo unsigned long.
Comentario 1
Ya que una variable unsigned long almacena numero entre 0 y 4,294,967,295 (2^32-1), esta función se vuelve a 0 a los 49.71 días pero eso no representa ningún problema para los cálculos porque al no aceptar numero negativos la variable se da la vuelta por decirlo de alguna manera.
Para que te quede claro simplificaremos con un ejemplo: supongamos que nuestra variable solo soporte 0 a 99 osea 100 números. Ahora te pregunto cuanto es 0 - 1 ? en nuestro ejemplo la respuesta correcta es 99 porque es el numero que esta antes de 0. Exactamente por el otro extremo el numero que sigue de 99 es 0. A esto se le llama lógica boleana.
Ahora supongamos que quieres prende un foco por 10 números e inicias el proceso en 22, por lo que preguntas if (números - tiempo = 10), se apagaría cuando números llegue a 32 (32 - 22 = 10). Ahora supón que se prende en 95, cuando apagara ? la respuesta es cuando números llegue a 5 (5 - 95 = 10).
Comentario 2
Se puede resetear el temporisador de millis() ?
extern volatile unsigned long timer0_millis;
unsigned long nuevo_valor = 0;
void setup(){
//Algo
}
void loop(){
//Algo
//--------
//Change Millis
setMillis(nuevo_valor);
}
void setMillis(unsigned long nuevo_valor){
uint8_t oldSREG = SREG;
cli();
timer0_millis = nuevo_valor;
SREG = oldSREG;
}
Advertencias
- Tenga en cuenta el tipo de valor que retorno millis() es unsigned long y pueden producirse errores lógicos si hacer operaciones aritméticas con otros tipos de datos más pequeños como: byte o int, incluso los long con signo pueden producir errores de calculo.
- millis() funciona mediante una interrupción (la misma de micros()); por lo tanto, su valor dejará de incrementar durante una rutina de servicio de interrupción (ej.: posterior a attachInterrupt()), o mientras no se llame a interrupts() después de llamar a noInterrupts().
Ejemplo 1
Parpadeo del LED incorporado sin usar delay()
unsigned long hora = 0; //Es muy importante respetar el tipo de dato
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
if (milis() - hora >= 500){
hora = millis(); //Guarda a hora de cada cambio
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); //Invierte valor del pin
}
}
Ejemplo 2
Parpadeo sin usar delay()
unsigned long t = 0; //Es muy importante respetar el tipo de dato
unsigned int d = 2000; //Duración en milisegundos del ciclo completo
void setup() {
pinMode(9, OUTPUT);
}
void loop() {
t = millis();
if (t%d > d/2){
digitalWrite(9, HIGH); //Prende LED
}else{
digitalWrite(9, LOW); //Prende LED
}
}
Ejemplo 3
En este ejemplo similaremos las direccionales de un auto, para lo que tenemos 2 pulsadores y 2 LED. Cada vez que pulso un boton el LED correspondiente parpadea cada 250 ms durante 3 segundos.
unsigned long izq=0,der=0,ti=0,td=0;
bool LEDi=false,LEDd=false;
void setup(){
pinMode(2, INPUT); //Pulsador derecho
pinMode(3, INPUT); //Pulsador izquierdo
pinMode(8, OUTPUT); //LED izquierdo
pinMode(9, OUTPUT); //LED derecho
}
void loop(){
if (digitalRead(3)){
LEDi = true;
izq = millis();
}
if (digitalRead(2)){
LEDd = true;
der = millis();
}
if (millis() - izq > 3000){
LEDi = false;
digitalWrite(8, LOW);
}
if (millis() - der > 3000){
LEDd = false;
digitalWrite(9, LOW);
}
if (LEDi){
if (millis()-ti > 250){
digitalWrite(8, !digitalRead(8));
ti = millis();
}
}
if (LEDd){
if (millis()-td > 250){
digitalWrite(9, !digitalRead(9));
td = millis();
}
}
}
Vea también
Referencias
- Guia de referencia de Arduino
- Resetting the Arduino millis() count - Tom Blanchard