Fecha y hora
Arduino tiene algunas funciones que manejan directamente los temporizadores y tienen usos diversos. Pero recuerda que Arduino no tiene un temporizador permanente como si es el modulo RTC asi que no puede saber la fecha y hora. Todos sus temporizadores se resetean al desconectar la energía.
Contenido
Tiempos
En Arduino tenemos algunas funciones que detienen la ejecución del boceto.
Nota: Tenga mucho cuidado ya que durante ese tiempo el uC no hace nada mas que esterar se cumpla el retardo.
- delay() Pausa el programa por la cantidad de milisegundos especificado como parámetro. No devuelve nada.
- delayMicroseconds() Pausa el programa por la cantidad de mcrosegundos especificado como parámetro. No devuelve nada.
Nota: Si bien es fácil crear un LED parpadeante con la funcion delay() y muchos bocetos lo usan, también es usado como anti Rebote de pulsadores, el uso de delay() en un boceto tiene inconvenientes importantes. Ninguna otra lectura o manipulacion de de puerto, cálculos matemáticos puede ejecutarse durante la función de retardo, por lo que, en efecto, detiene la mayoría de otras actividades. Para obtener enfoques alternativos para controlar el tiempo consulte:
- millis() - Devuelve la cantidad de milisegundos desde que la placa Arduino comenzó a ejecutar el programa actual.
- micros() - Devuelve la cantidad de microsegundos desde que la placa Arduino comenzó a ejecutar el programa actual.
Fecha y hora
Los temporizadores internos de Arduino son de corto plazo. Pero que hacer cuando requerimos por ejemplo poner fecha y hora en nuestro tabulado de datos de sensores (datalogger) para un análisis posterior ? Estas funciones están disponibles si añades la librería estándar de Arduino TimeLib.h.
Lo primero que hace la librería TimeLib.h es definir un tipo especial de variable que llamamos time_t de 32 bits, que es la base de todo, porque almacena valores de tiempo en un formato especial calculado como el número de segundos transcurridos desde el 1-ENE-1970, llamada fecha Unix.
Funciones | Descripción | rango |
---|---|---|
millis() | Milisegundos | 0~999 |
second() | Segundos | 0~59 |
minute() | Minutos | 0~59 |
hour() | Hora | 0~23 |
day() | Numero de dia | 1~31 |
weekday() | Dia de la semana | 1~7 (1=domingo) |
dayStr(weekday()) | Nombre de dia | Saturday, Sunday |
dayShortStr(weekday()) | Nombre corto del dia | Mon, Sat, Sun |
month() | Numero de mes | 1~12 |
monthStr(month()) | Nombre del mes | July, Dicember |
monthShort(month()) | Nombre corto del mes | Jul, Dic |
year() | Año | 4 digitos |
hourFormat12() | Pone en formato 12 horas | 0~11 |
isAM() | AM | Verdadero por la mañana |
isPM() | PM | Verdadero por la tarde |
now() | Tiempos Unix | Segundos desde 1-ENE-1970 |
Nota: Fantástico ya tenemos creada nuestra variable del tipo time_h con la hora actual según nuestro Arduino... pero espera no que Arduino no sabia la fecha ni hora ? exacto lo que acabas de obtener es un porquería y hay que arreglar el Arduino.
Sincronizar reloj Arduino
La función setTime() nos permite decirle al Arduino en que día y hora estamos y que a partir de alli mantenga sincronizado adecuadamente esa fecha hasta su próximo reseteo.
setTime(ss); //Numero de segundos desde 1-ENE-1970 setTime(hh,mm,ss,dia,mes,año); //hora, minuto,segundo dia, mes, año
Otros métodos de la libreria
adjustTime(ajuste); //Ajusta fecha y hora añadiendo un ajuste setSyncProvider(getTimeFuncion); //Configurar proveedor externo setSyncInterval(intervalo); //Indicar el intervalo de re-sincronizacion timeStatus(); //Informa si el reloj fue sincronizado recientemente.
Las posibles respuestas de timeStatus() son:
- timeNotSet
- La fecha y hora nunca fue sincronizada
- timeNeedsSync
- La fecha y hora fue isincronizada pero no se completo
- timeSet
- Todo esta sincronizado
Matemática con fechas
Si requieres trabajar con matematica de fechas, es decir que requeriras crear fechas y no presisamente sincronizar el reloj de Arduino, debes usar un tipo de dato matriz llamado tmElements_t que nos permite asignar cada uno de los elementos de la fecha-hora por separado como si se tratara de un conjunto de métodos asi:
tmElements_t tx; tx.Second = Segundos; (0~59) tx.Minute = Minuto; (0~59) tx.Hour = Hora; (0~23) tx.Day = Dia; (1~31) tx.Month = Mes; (1~12) tx.Year = Año; (0~99) diferencia desde 1970.
Luego puedes usar la función makeTime() que lo que hace es pasar una variable del tipo tmElements_t a una variable del tipo time_t
time_t tiempo = makeTime(elementos);
Donde tiempo es del tipo time_t y elementos es del tipo tmElements_t.
Asi mismo si tenemos una variable tipo time_t también la podemos descomponer en una variable tipo tmElements_t con breakTime().
tmElements_t elementos; breakTime(tiempo, elementos);
Ejemplo 1
Fijamos una fecha y hora y mostramos cada segundo.
#include <TimeLib.h>
void setup(){
Serial.begin(115200);
setTime(8,0,0,14,7,2018); //14-JUL-2018 08:00:00
}
void loop(){
time_t t = now();
if (hour(t) < 10){
Serial.print("0");
}
Serial.print(hour(t));
Serial.print(":");
if (minute(t) < 10){
Serial.print("0");
}
Serial.print(minute(t));
Serial.print(":");
if (second(t) < 10){
Serial.print("0");
}
Serial.println(second(t));
delay(1000);
}
Ejemplo 2
Fijamos una fecha y hora y mostramos cada segundo. Nota que no es necesario usar now(), simplemente consultamos la funciones vacias directamente
#include <TimeLib.h>
void setup() {
Serial.begin(115200);
while (!Serial); //Esperar hasta que monitor serie esta listo
setTime(8,30,0,14,7,2019);
if (timeStatus()!= timeSet){
Serial.println("No se logro sincronizar");
}else{
Serial.println("Tenemos el reloj sincronizado");
}
}
void loop(){
if (timeStatus() == timeSet) {
digitalClockDisplay();
}else{
Serial.println("El reloj no fue sincronizado.");
delay(3000);
}
delay(1000);
}
void digitalClockDisplay(){
printDig(hour());
Serial.print(":");
printDig(minute());
Serial.print(":");
printDig(second());
Serial.print(" ");
printDig(month());
Serial.print("-");
printDig(day());
Serial.print("-");
Serial.println(year());
}
void printDig(int digits){
if(digits < 10)
Serial.print('0');
Serial.print(digits);
}
Ejemplo 3
Calcular la diferencia entre dos fechas. Por ejemplo del 6-NOV al 13-NOV del 2018. Respuesta: 0 años, 0 meses, 7 dias, 20 horas, 28 minutos, 0 segundos.
#include <TimeLib.h>
time_t t0,t1,dif;
void setup(){
Serial.begin(115200);
t0 = ponFecha(2018, 11, 6, 20, 17, 0); //6-NOV-2018 20:17:00
printFecha(t0);
t1 = ponFecha(2018, 11, 13, 16, 45, 0); //13-NOV-2018 16:45:00
printFecha(t1);
Serial.println("--------------------------------------------------");
dif = t1 - t0;
Serial.print(String(year(dif)-1970) + " años, " + String(month(dif)-1) + " meses, ");
Serial.print(String(day(dif)) + " dias, " + String(hour(dif)) + " horas ");
Serial.println(String(minute(dif)) + " minutos, " + String(second(dif)) + " segundos.");
Serial.println("---------------------------------------------------");
}
time_t ponFecha(int y, int m, int d, int hh, int mm, int ss){
tmElements_t f;
f.Second = ss;
f.Minute = mm;
f.Hour = hh;
f.Day = d;
f.Month = m;
f.Year = y - 1970 ;
return makeTime(f); //Crea tiempo Unix
}
void printFecha(time_t t){
if (day(t) < 10){
Serial.print("0");
}
Serial.print(day(t)); //dia
Serial.print("-");
if (month(t) < 10){
Serial.print("0");
}
Serial.print(month(t)); //mes
Serial.print("-");
Serial.print(year(t)); //año
Serial.print(" ");
if (hour(t) < 10){
Serial.print("0");
}
Serial.print(hour(t)); //hora
Serial.print(":");
if (minute(t) < 10){
Serial.print("0");
}
Serial.print(minute(t)); //minutos
Serial.print(":");
if (second(t) < 10){
Serial.print("0");
}
Serial.println(second(t)); //segundos
}
void loop(){
//Nada
}
Nota: Pon atención a la funciónes de usuario: ponFecha() y printFecha() que son muy interesantes.
Ejemplo 4
Dada una fecha 2019-7-14 8:30:00 sumar una hora y media (5400 segundos)
#include <TimeLib.h>
void setup(){
Serial.begin(115200);
tmElements_t tx;
tx.Second = 0;
tx.Minute = 30;
tx.Hour = 8;
tx.Day = 14;
tx.Month = 7;
tx.Year = 49; //2019-1970
muestra(tx); //Funcion muesra fecha y hora
time_t ta = makeTime(tx);
ta += 5400; //Sumar 1.5 hrs
tmElements_t tz;
breakTime(ta, tz);
muestra(tz); //Funcion muesra fecha y hora
}
void loop() {
//Nada
}
void muestra(tmElements_t ty){
Serial.print(ty.Year + 1970);
Serial.print("-");
if (ty.Month<10){
Serial.print('0');
}
Serial.print(ty.Month);
Serial.print("-");
if (ty.Day<10){
Serial.print('0');
}
Serial.print(ty.Day);
Serial.print(" ");
if (ty.Hour<10){
Serial.print('0');
}
Serial.print(ty.Hour);
Serial.print(":");
if (ty.Minute<10){
Serial.print('0');
}
Serial.print(ty.Minute);
Serial.print(":");
if (ty.Second<10){
Serial.print('0');
}
Serial.println(ty.Second);
}
Vea también
Libreria TimeLib.h
Libreia RTClib.h