Hola a todos!!,
Tal como dice el título, ando en busca un reloj que utilice la funcion millis() para hacer avanzar la cuenta del tiempo en intervalos de 24 horas, seguro que alguien ya lo escribió, pero por mas que busco no lo encuentro.
Mientras tanto propongo un código en donde hay 2 funciones relacionadas con el tiempo:
- contar_tiempo(): cuando es llamada mide un intervalo de tiempo, que es asignado a la variable diferencia (cuando el valor es mayor que 1 min), despues esta diferencia (que es un numero entero), es sumada a la variable minuto_humano
- actualizar_tiempo(): actualiza el tiempo, esta función no se encuentra lista, le falta la corrección por overflow de millis() (necesito un poco mas de tiempo para pensarla), pero la planteo porque tengo la sospecha de que hay algo extraño en esta función que no puedo determinar, a pesar de que ha pasado una hora desde que la escribí y aun coincide con un cronómetro (estoy comparando con un cronómetro externo).
Quiero aclarar que en el código hay dos funciones (tentativas, que aun no he probado), para cambiar las horas y los minutos con tres botones (en los pines digitales 7, 8 y 9), sin embargo, no se si éstas funcionarán:
- cambiar_hora(): que sirve para cambiar la hora con los botones boton_arriba(pin digital 8 ), y boton_abajo(pin digital 9), y se sale de la función con el boton_menu(pin digital 7), mientras cambia la hora imprime en pantalla lcd
- cambiar_minuto(): que tiene las mismas caracteristicas de cambiar_hora() pero cambia los mintutos
Estoy usando un Arduino Uno y una pantalla lcd 16x2 tal como se propone aqui, no tengo los botones y me complica hacer algo que funcione como botón, por eso no pude comprobar las funciones de cambios.
Si alguien se encuentra en las mismas condiciones, puede reemplazar la variable hora_humana por la hora actual, y la variable minuto_humano por el minuto actual, al momento de cargar el sketch.
Aqui el código, pido disculpas por las instrucciones que tienen que ver con imprimir en la pantalla lcd (que me quedaron un poco engorrosas), espero que no sea una complicación para quien las vea.
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
int minuto_maquina = 0;
int minuto_humano = 0;
int hora_humana = 0;
int actualizador = 0;
int boton_menu = 7;
int boton_arriba = 8;
int boton_abajo = 9;
//funcion que hace avanzar los minutos con millis()
void contar_tiempo(){
long diferencia = millis()/60000 - minuto_maquina;
if (diferencia < -3600){ //correccion por overflow
/* el numero 71582.78825 es la cantidad maxima
en minutos, de la funcion millis(). */
diferencia = 71582.78825 - minuto_maquina + millis()/60000;
}
minuto_maquina = millis()/60000;
minuto_humano += diferencia;
if (minuto_humano > 59){ //tambien hace avanzar las horas
minuto_humano -= 59;
hora_humana += 1;
if (hora_humana > 23){
hora_humana = 0;
}
}
if (diferencia >= 1){ //para imprimir el cambio en el tiempo si corresponde
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Hora");
lcd.setCursor(0,1);
if(hora_humana<10){
lcd.print("0");
lcd.print(hora_humana);
}
else{
lcd.print(hora_humana);
}
lcd.setCursor(2,1);
lcd.print(":");
lcd.setCursor(3,1);
if(minuto_humano<10){
lcd.print("0");
lcd.print(minuto_humano);
}
else{
lcd.print(minuto_humano);
}
}
}
//funcion que actualiza el estado del tiempo
void actualizar_tiempo(){
if (actualizador < millis()/61000){
contar_tiempo();
actualizador = millis()/60000;
}
}
//esta funcion es para ajustar la hora
void cambiar_hora(){
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Cambio de Hora");
lcd.setCursor(0, 1);
lcd.print(hora_humana);
delay(500); //para no salir del while que viene
while(digitalRead(boton_menu) == LOW){
while(digitalRead(boton_arriba) == HIGH){ //suma hora
hora_humana += 1;
if (hora_humana > 23){
hora_humana = 0;
}
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Cambio de Hora");
lcd.setCursor(0,1);
if(hora_humana < 10){
lcd.print("0");
lcd.print(hora_humana);
}
else{
lcd.setCursor(0,0);
lcd.print("Cambio de Hora");
lcd.print(hora_humana);
}
delay(400);
}
while(digitalRead(boton_abajo) == HIGH){ //resta hora
hora_humana -= 1;
if(hora_humana < 0){
hora_humana = 23;
}
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Cambio de Hora");
lcd.setCursor(0,1);
if(hora_humana<10){
lcd.print("0");
lcd.print(hora_humana);
}
else{
lcd.setCursor(0,0);
lcd.print("Cambio de Hora");
lcd.print(hora_humana);
delay(400);
}
}
}
}
//esta funcion es para ajustar los minutos
void cambiar_minuto(){
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Cambio de Min");
lcd.setCursor(0, 1);
lcd.print(minuto_humano);
delay(500); //para no salir del while que viene
while(digitalRead(boton_menu) == LOW){
while(digitalRead(boton_arriba) == HIGH){ //suma minuto
minuto_humano += 1;
if (minuto_humano > 59){
minuto_humano = 0;
}
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Cambio de Min");
lcd.setCursor(0, 1);
if(minuto_humano<10){
lcd.print("0");
lcd.print(minuto_humano);
}
else{
lcd.print(minuto_humano);
}
delay(400);
}
while(digitalRead(boton_abajo) == HIGH){ //resta minuto
minuto_humano -= 1;
if (minuto_humano < 0){
minuto_humano = 59;
}
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Cambio de Min");
lcd.setCursor(0, 1);
if(minuto_humano<10){
lcd.print("0");
lcd.print(minuto_humano);
}
else{
lcd.print(minuto_humano);
}
delay(400);
}
}
}
void setup(){
lcd.begin(16, 2);
pinMode(boton_menu, INPUT);
pinMode(boton_arriba, INPUT);
pinMode(boton_abajo, INPUT);
}
void loop(){
actualizar_tiempo();
if(digitalRead(boton_menu) == HIGH){
cambiar_hora();
cambiar_minuto();
}
}
Las dudas que surgen son:
- ¿Encuentran razonable la función contar_tiempo()?
- Se cuentan demasiados milisegundos por el tiempo que quiero medir (horas por ejemplo) ¿Alguien sabe que error asociado trae cada milisegundo de la funcion millis()?
- ¿Me podrían recomendar alguna lectura asociada a la variabilidad del tiempo relacionado al hardware?... en todo este tiempo no me he podido sacar de la cabeza el oscilador de 16MHz, (aunque esto debe ir en otro lugar, creo que se encuentra en el contexto de la propuesta)
Gracias max_saeta por la traducción de la función millis().
Se me olvido aclarar que la hora se imprime en la pantalla tras 1 minuto despues de la carga del sketch.