G042 La libreria TimeLib en Arduino

 ADM

Antiguamente se usaban relojes de agua y arena.  En la Edad Media aparecieron los primeros relojes mecánicos. En el siglo XVIII surgieron relojes más fiables gracias al reloj de escape. En el siglo XIX aparecieron relojes de bolsillo precisos. En los años 70 se popularizaron los relojes de cuarzo, mucho más precisos.

Arduino y la medida del tiempo
Arduino utiliza un cristal piezoeléctrico de 16 MHz como base de tiempos.  Eso es 16.000.000 de pulsos por segundos. Su precisión tiene una deriva de inferior a medio segundo al día.

Porque  controlar el tiempo y gestionar fechas y horas
La funciones
delay();
millis();
micros();

son útiles para tiempos cortos, pero no para proyectos que necesitan trabajar con:
minutos
horas
días
meses
años

como en un data logger que necesita guardar junto con los datos una marca temporal, fecha y hora de cuando se hizo la medición.

La librería Time
La librería #include <TimeLib.h> es estándar en Arduino, pero debe instalarse antes de usarla.  Esta librería consume recursos, especialmente en arduino UNO

Trabajar con fechas manualmente es complicado por que
Las horas y los minutos usan sistema sexagesimal
Los días tiene 24 horas
Los meses tienen distinta duración
Existen años bisiestos
Existen reglas especiales del calendario.
Todos esos cálculos los hace automáticamente la librería.

La librería define un tipo especial:
time_t

Es una variable  de 32 bits que guarda el número de segundos transcurrido desde el 1 de Enero de 1970.

Algunas ventajas de usar la librería es que permite comparar fechas, sumar tiempos o restar fechas de forma sencilla.  El inconveniente principal es que no funciona con fechas anteriores al 1 de enero de 1970.

Cómo obtener la fecha y hora actual
time_t T=now();

La función now() devuelve el tiempo actual almacenado por arduino

Cómo ajustar la fecha y hora
setTime(19,58.00,25,12,2026);

Los parámetros son hora, minutos, segundos, día, mes, año

Funciones básicas que permiten extraer las partes de una fecha

day(t) devuelve el día de la fecha
month(t) devuelve el mes de la fecha
year(t) devuelve el año de la fecha
hour(t) devuelve la hora de una feche
minute(t) devuelve el minuto de una fecha
second(t) devuelve el segundo de una fecha


Estructura para construir fechas

tmElements_t tm;


Campo


Significado

tm.Second

0–59 segundos

tm.Minute

0–59 minutos

tm.Hour

0–23 horas

tm.Wday

día semana

tm.Day

1–31 día

tm.Month

1–12 mes

tm.Year

años desde 1970


Es siguiente código usa la librería TimeLib para imprimir en el monitor serie la hora y la fecha.
#include <TimeLib.h>

void setup(){  
  Serial.begin(115200);
  setTime(20,01,00,30,04,2026);
}

void loop(){  
  time_t t = now();
  Serial.print(day(t));
  Serial.print(+ "/") ;
  Serial.print(month(t));
  Serial.print(+ "/") ;
  Serial.print(year(t));
  Serial.print( " ") ;
  Serial.print(hour(t));  
  Serial.print(+ ":") ;
  Serial.print(minute(t));
  Serial.print(":") ;
  Serial.println(second(t));
  delay(1000);
}
Convertir una fecha a time_t
Crear la estructura
tmElements_t Fecha;

Fecha.Second
Fecha.Minute
Fecha.Hour
Fecha.Day
Fecha.Month
Fecha.Year

Conversión
T0 = makeTime(Fecha);

Devuelve una fecha en formato:
time_t

Restar fechas
Las variables time_t pueden restarse directamente:
H = T1 - T0;

Significado
T1 → fecha final.
T0 → fecha inicial.
H → diferencia entre ambas.

La diferencia se calcula en segundos, pero puede mostrarse en:
años
meses
días
horas

Sincronización del reloj
Problema
Arduino guarda el tiempo usando los milisegundos transcurridos desde que se encendió.

Si se apaga o reinicia:
pierde la hora
vuelve a empezar desde cero

Desbordamiento (Overflow)
Arduino utiliza una variable unsigned long de 32 bits. Valor máximo es:
232=4.294.967.2962 

Milisegundos por día
1000×60×60×24=86.400.000

Tiempo hasta el desbordamiento
4.294.967.29686.400.000 = 49,71 día

Resultado
Después de aproximadamente:
50 días el contador vuelve a cero.

#include <TimeLib.h>

time_t  T0, T1 ;         // Contenedores de fechas

void setup(){
  Serial.begin(115200);  
}

void loop(){    
  T0 = SetFecha(2014, 11, 6, 20, 17, 0);  // 6 nov 2014  20:17
  printFecha(T0) ;
  T1 = SetFecha(2014, 11, 13, 16, 45, 0);  // 13 nov 2014 16:45
  printFecha(T1) ;
  printFecha(T1 - T0);
  Serial.println("--------------------------------------------------");
  time_t H =  T1 - T0 ;
  Serial.print(String(year(H )- 1970)+" años,"  + String(month(H)-1 )+" meses,");
  Serial.println(String(day(H))+ " dias," + String(hour(H))+ " horas");
  Serial.println("---------------------------------------------------");
}

void printFecha(time_t  t){
  Serial.print(day(t)) ;    Serial.print(+ "/") ;   Serial.print(month(t));   Serial.print(+ "/") ;
  Serial.print(year(t));    Serial.print( " ") ;
  Serial.print(hour(t));   Serial.print(+ ":") ;   Serial.print(minute(t));   Serial.print(":") ;
  Serial.println(second(t));
  delay(1000);
}

time_t SetFecha(int y, int m, int d, int h, int mi, int s  ){
  tmElements_t Fecha ;
  Fecha.Second = s;
  Fecha.Minute = mi;
  Fecha.Hour = h;
  Fecha.Day = d ;
  Fecha.Month = m ;
  Fecha.Year = y -1970 ;
  return makeTime(Fecha);
}
Sincronización del reloj
La hora interna debe actualizarse periódicamente.

Métodos para sincronizar la hora
Manualmente
setTime(...)
Simple, pero poco práctico.

Desde un PC
Un programa del ordenador envía la hora al Arduino

Con un reloj RTC
Un chip con batería mantiene la fecha y la hora incluso apagado

Mediante Internet
Usando servidores:
NTP (Network Time Protocol)

Mediante GPS
Los GPS incorporan relojes extremadamente precisos

Funciones de sincronización
timeStatus()
Indica el estado del reloj.

Posibles valores
timeNotSet
No se ha ajustado la hora.

timeSet
La hora está ajustada.

timeNeedsSync
La hora estaba ajustada pero ha fallado la sincronización externa.

setSyncProvider()
Define la función encargada de sincronizar el reloj con una fuente externa.

setSyncInterval()
Define cada cuánto tiempo se realiza la sincronización.

No hay comentarios:

Publicar un comentario