Modulo reloj fiable 24 horas.

Saludos al personal.
Soy nuevo en el foro y pido disculpas por mi torpeza y daros las gracias por la ayuda prestada en el tema anterior …y haber si me podéis orientar en otro tema.

Tengo una placa “Arduino UNO” , quiero instalar un modulo y programar un reloj de 24 horas que sea lo mas fiable posible ya que la placa se apagaría todos los días por la noche, y vuelta a encender por la mañana.

E probado con el modulo DS3231, y la librería LiquidCrystal pero tengo problemas con el paso de las 24 horas. ¿Hay algo mas fiable ó es algo que estoy haciendo mal ?
Me pregunto haber si me podéis ayudar y orientar un poco …Gracias.

He probado tanto con el DS3231 como con el DS1307, y no he encontrado problemas. Al menos, con el DS3231, tras días y días desconectado, ha mantenido la hora con muy buena exactitud.

Igual dando algo más detalle te podemos ayudar.

Exacto el DS3231 suele ser lo suficientemente preciso para aplicaciones "normales", si necesitas muuucha precision puedes buscar un modulo RTC mas preciso, que los hay, pero son dificiles de encontrar y mas caros, otra opcion es usar el DS3231 y sincronizarlo a diario con un servidor de hora NTP por internet (como hacen los ordenadores y los moviles)

Podemos partir, supongo, de pensar que el modulo esta conectado a una bateria adecuada y con carga?no? En el caso del Ds3231, una LIR2032.

El problema que tengo es que al cargar el programa y setear la hora : 24 h

Clock.setClockMode(false); // = 24 horas

Clock.setHour((byte)21); // =  las 21 Horas

me da otra hora me sale las 15, por lo demas parece que va bien.

Esa librería no la he utilizado ¿y si buscas alguna otra versión?

He probado la RTC, pero claro, la sintaxis es distinta, aunque muy simple.

Creo que tengo problemas con las librerias, e instalado varias y creo que tengo un popurri de todo, a si que me e desistalado todo y vuelta a empezar.
No se muy bien donde descargarlas en que pagina ? que libreria me recomendais para funcionar con el modulo DS3231, o algun tutorial del codigo …Gracias.

Busca adafruit y rtclib. Tiene un ejemplo para el DS3231 en el que puedes mirar en un momento, si te puede servir o no. Esta la he usado de momento solo con el DS1307.

Gracias chema_zgz. En cuanto tenga un rato lo miro y ya contare que tal :)

Tambien me recomendaron esta libreria ds3231-master parece que va bien, biene para colocar 2 alarmas.

¿Sabeis como poder identificar las horas ? Ejemplo:

if ((si son las 4h) && (30 minutos)) { quiero que aga esto }

if ((si son las 6h) && (10 minutos))  { esto otro }

if (si son las 10h) { otra cosa }

Pensaba que seria mas facil rescatar informacion del reloj.

Mi sugerencia es que uses estas librerías para el DS3231 y para comparar y hacer alarmas (comparar horarios y disparar algun evento). Uso DS1307RTC Library Uso Time Library y Uso TimeAlarms Library para las comparaciones.

Mira la página y los ejemplos presentados. Tiene soporte para actualizar la hora via internet.. esta todo pensado y resuelto.

Gracias surbyte,

Este fin de semana las hecho un vistazo.

Mira el trabajo de chema_zgs, creo que es similar al tuyo, Reloj, LCD, ajuste con pulsadores

Despues de todo el fin de semana dando vueltas en google a las librerias para el ds3231 y haciendo encaje de bolillos para conseguir un reloj 24h, con un par de alarmas ajustables, sigo sin dar con la formula :confused:

El trabajo del compañero chema_zgz "TREMENDO" enhorabuena amigo. Probe con las librerias que me paso surbyte y las comparaciones, y todo bien "estupendo" hasta que veo que no se actualiza el reloj. ¿ tengo que llevar un cable internet para actualizar la hora ?. Pufff creo que esto me sobrepasa un poquito. Seguire investigando. :o

Noooo.. La actualización del reloj es si quieres SINCRONIZARLO via ntp (ethernet, WIFI). a eso te refieres? Tu reloj depende de tu RTC DS3231 que es muy bueno y estable. Si ademas quieres cada tanto y porque dispones de la posiblidad de mantenerlo ajustado con un reloj atómico bueno lo haces, sino, que siga asi.

Estoy liado con las librerias que me paso surbyte para el modulo ds3231 y las paginas web de configuracion, pero que no me entero muy bien de como va.
No se como setear la hora y guardarla, para que cuando apague el arduino siga funcionando el reloj,
las alarmas parece que funcionan bien.

Cargo las librerias:
DS1307RTC Library
Time Library
TimeAlarms Library

#include <Time.h>
#include <TimeAlarms.h>
#include <DS1307RTC.h>
#include <Wire.h>

void setup()
{
  Serial.begin(9600);
  setTime(8,29,0,1,1,11); // set time to Saturday 8:29:00am Jan 1 2011
  // create the alarms 
  Alarm.alarmRepeat(8,30,0, MorningAlarm);  // 8:30am every day
  Alarm.alarmRepeat(17,45,0,EveningAlarm);  // 5:45pm every day 
  Alarm.alarmRepeat(dowSaturday,8,30,30,WeeklyAlarm);  // 8:30:30 every Saturday 

 
  Alarm.timerRepeat(15, Repeats);            // timer for every 15 seconds    
  Alarm.timerOnce(10, OnceOnly);             // called once after 10 seconds 
}

void  loop(){  
  digitalClockDisplay();
  Alarm.delay(1000); // wait one second between clock display
}

// functions to be called when an alarm triggers:
void MorningAlarm(){
  Serial.println("Alarm: - turn lights off");    
}

void EveningAlarm(){
  Serial.println("Alarm: - turn lights on");           
}

void WeeklyAlarm(){
  Serial.println("Alarm: - its Monday Morning");      
}

void ExplicitAlarm(){
  Serial.println("Alarm: - this triggers only at the given date and time");       
}

void Repeats(){
  Serial.println("15 second timer");         
}

void OnceOnly(){
  Serial.println("This timer only triggers once");  
}

void digitalClockDisplay()
{
  // digital clock display of the time
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.println(); 
}

void printDigits(int digits)
{
  Serial.print(":");
  if(digits < 10)
    Serial.print('0');
  Serial.print(digits);
}

setTime ajusta la hora del sistema, pero no toca la del RTC. La del RTC se ajusta con RTC.write. Hay que tener cuidado con los tipos de variable que usan ambas librerías

Son dos horas independientes, pero que una vez se sincronizan, van a la par. La del sistema (la que usa Time), cada vez que arranca la placa se va a cero, y hay que ajustarla según el RTC.

Esto hago al arranque, en el setup:

//Ajusta la hora del "sistema" en el arranque
  RTC.read(t); //Lee la hora del RTC
  //Ajusta la hora al sistema
  setTime(t.Hour, t.Minute, t.Second, t.Day, t.Month, t.Year+1970);

Para ajustar, tienes que darle los parámetros, por un método u otro. Para empezar, lo más fácil quizá sería que los metieras por puerto serie, con una función para irlos leyendo, después, una vez cargados, los gestionas y los puedes usar así:

tmElements_t t_set; //Declaración de t como el tipo que usa la libreria DS1307

//monta t_set como tipo t_elements, para ajustar el RTC
         t_set.Second=mi_segundo;
         t_set.Minute=mi_minuto;
         t_set.Hour=mi_hora;
         t_set.Day=mi_dia;
         t_set.Month=mi_mes;
         t_set.Year=(mi_anyo-1970);
         //RTC write ajusta con un tipo t_elements_t (el que usa la libreria DS1307RTC)
         byte resp=RTC.write(t_set);
         if (resp) {Serial.println("ajuste del RTC correcto");}
         else {Serial.println("Fallo en al ajuste del RTC");}


         //Vuelve a ajustar la hora del sistema con la que lee del RTC
         RTC.read(t); //Lee la hora del RTC
         //Ajusta la hora al sistema
         setTime(t.Hour, t.Minute, t.Second, t.Day, t.Month, t.Year+1970);

Una opción sería, estar atento al puerto serie. Controla que lea una cadena que empiece por * y acabe igual*, algo así como 2016/03/01 02:15:00 Luego ya es tarea tuya en código extraer de ahí las "piezas" para el ajuste

Échale un ojo a esto.
Va con un DS1307, pero con el DS3231 debería tirar igual.
No usa TimeAlarms, pero lleva, creo que lo básico para poder entender la librería Time y la DS1307, que ceo que al final su relación era lo que te daba problemas.

Por el puerto serie:

SET DATE 2016/03/01*
Ajustará la fecha a 1 de marzo de 2016, y la guardará en el RTC.

SET TIME 12:40:15*
Ajustará la hora a 12:40:15, y la guardará en el RTC.

//chema_zgz - Feb 2016
//Arduino Nano
//Transistor conectado en D6 para intentar encender un led cuando se activa

// Importamos las librerias necesarias 
#include <Wire.h> //Para el manejo del I2C
#include <DS1307RTC.h> //Para manejo del RTC
#include <Time.h>
//#include <TimeAlarms.h>

unsigned long tiemporef;

tmElements_t t;  //Declaración de t como el tipo que devuelve la libreria DS1307
time_t tt; //Declaración de tt como el tipo que gestiona la librería Time

int leidoSerie;
String scadena="";

void setup() {
  Serial.begin(9600);

  pinMode(6, OUTPUT); //Pin que controla el transistor
  digitalWrite(6, LOW); //Empieza con el pin en bajo
    
 Serial.println("ARRANCA LA PLACA");
 //Ajusta la hora del "sistema" en el arranque
  RTC.read(t); //Lee la hora del RTC
  //Ajusta la hora al sistema
  setTime(t.Hour, t.Minute, t.Second, t.Day, t.Month, t.Year+1970);
  Serial.println("Leida la hora del RTC y ajustada la del sistema");
  Serial.println("");
  Serial.println("Los comandos acaban en asterisco *");
  Serial.println("D6 ON* O D6 OFF* pone en alta o baja el pin D6");
  Serial.println("SET DATE yyyy/mm/dd* ajusta la fecha a la indicada");
  Serial.println("SET TIME hh:mm:ss* ajusta la hora a la indicada");
  tiemporef=millis();
}  
  
void loop() {
      
      
      if(Serial.available()>0){
         leidoSerie = Serial.read();
         if (leidoSerie==42) { //Fin de cadena, un asterisco
             Procesa_cadena(scadena);
             scadena="";
         }
         else {
             scadena+= char(leidoSerie);
         }

        
         
      }
      //Cada 5 segundos muestra la hora
      if ((millis()-tiemporef)>=5000) {
          tiemporef=millis();
          //Fecha y hora
          tt=now();
          Serial.print(FormatDate(tt));
          Serial.print(F(" "));
          Serial.println(FormatTime(tt));
       }
  //FIN DE MODO DE VISUALIZACIÓN
  
}

String FormatDate(time_t tr){
  String cadena;
  int mes,dia;
  mes=month(tr);dia=day(tr);
  cadena="";
  cadena+=year(tr);
  cadena+="/";
  cadena+=mes/10;
  cadena+=mes%10;
  cadena+="/";
  cadena+=dia/10;
  cadena+=dia%10;
  return cadena;
}

String FormatTime(time_t tr){
  String cadena;
  byte hora, minuto, segundo;
  hora=hour(tr);minuto=minute(tr);segundo=second(tr);
  cadena="";
  cadena+=hora/10;
  cadena+=hora%10;
  cadena+=":";
  cadena+=minuto/10;
  cadena+=minuto%10;
  cadena+=":";
  cadena+=segundo/10;
  cadena+=segundo%10;
  return cadena;
}

void Procesa_cadena(String sc){
  if (sc.indexOf("D6 ON") !=-1){
            Serial.println("Pondra D6 en alta");
            digitalWrite(6,HIGH);
            
        }
        else if (sc.indexOf("D6 OFF") !=-1){
            Serial.println("Pondra D6 en baja");
            digitalWrite(6,LOW);
            
        }
        else if (sc.indexOf("SET DATE ") !=-1){
            Serial.println("Ajuste de fecha");
            if (Ajusta_Fecha(sc)==-1){
                Serial.println("Fallo en el ajuste de fecha");
            }
            else {
                Serial.println("Ajuste de fecha correcto");
            }
            
        }
        else if (sc.indexOf("SET TIME ") !=-1){
            Serial.println("Ajuste de hora");
            if (Ajusta_Hora(sc)==-1){
                Serial.println("Fallo en el ajuste de hora");
            }
            else {
                Serial.println("Ajuste de hora correcto");
            }
        }
}

byte Ajusta_Hora (String sc){
    byte pos, hora,minuto,segundo;
    String shora,sminuto,ssegundo;
    Serial.println(sc);
    pos=sc.indexOf("SET TIME ");
    if (pos==-1){
        Serial.println("Cadena de entrada erronea");
        return -1;
    }
    shora=sc.substring(pos+9,pos+11);
    sminuto=sc.substring(pos+12,pos+14);
    ssegundo=sc.substring(pos+15,pos+17);
    
    hora=string2long(shora);
    minuto=string2long(sminuto);
    segundo=string2long(ssegundo);
    
    Serial.print("Se ajustara hora a: ");
    Serial.print(hora);
    Serial.print(":");
    Serial.print(minuto);
    Serial.print(":");
    Serial.println(segundo);
    
    //Ajusta la hora del sistema
    setTime(hora, minuto, segundo, day(), month(), year());
    //Ajusta la hora del RTC
    //Con RTC.set, ajusta con un time_t
    if ( !RTC.set(now()) ){Serial.println("Fallo en el ajuste del RTC");return -1;}
    
   return 0;
}

byte Ajusta_Fecha (String sc){
    int pos, anyo, mes, dia;
    String sanyo,smes,sdia;
    Serial.println(sc);
    pos=sc.indexOf("SET DATE ");
    if (pos==-1){
        Serial.println("Cadena de entrada erronea");
        return -1;
    }
    sanyo=sc.substring(pos+9,pos+13);
    smes=sc.substring(pos+14,pos+16);
    sdia=sc.substring(pos+17,pos+19);
    
    anyo=string2long(sanyo);
    mes=string2long(smes);
    dia=string2long(sdia);
    
    Serial.print("Se ajustara fecha a: ");
    Serial.print(anyo);
    Serial.print("/");
    Serial.print(mes);
    Serial.print("/");
    Serial.println(dia);
    
    //Ajusta la fecha del sistema
    setTime(hour(), minute(), second(), dia, mes, anyo);
    //Ajusta la fecha-hora del RTC
    //Con RTC.set, ajusta con un time_t
    if ( !RTC.set(now()) ){Serial.println("Fallo en el ajuste del RTC");return -1;}
    
   return 0;
}

long string2long(String string){
  char cadena[string.length()+1];
  string.toCharArray(cadena, string.length()+1);
  return atol(cadena);
}

Por fin tengo las alarmas, gracias a todos por ayuda y guiarme un poco :slight_smile:
Os pego el codigo, no es el original, solo es el reloj con las alarmas que tanto me costo comprender.

#include <Wire.h> 
#include "RTClib.h"
RTC_DS1307 RTC;

int h1 = 18; // Ajusta la hora que quieras
int h2 = 17; //  Ajusta la hora que quieras

void setup () {
Wire.begin(); // Inicia el puerto I2C
RTC.begin(); // Inicia la comunicación con el RTC
Serial.begin(9600);

// RTC.adjust(DateTime(__DATE__, __TIME__));  // Establece la fecha y hora 
}

void loop(){
DateTime now = RTC.now(); // rescata la informacion y la imprime 
Serial.print(now.year(), DEC); Serial.print('/'); Serial.print(now.month(), DEC); Serial.print('/'); Serial.print(now.day(), DEC); Serial.print(' ');
Serial.print(now.hour(), DEC); Serial.print(':'); Serial.print(now.minute(), DEC); Serial.print(':'); Serial.print(now.second(), DEC); 
Serial.println();
delay(1000);

// si concuerda la hora con la alarma la imprime

if ((now.hour() == h1) && (now.minute() == 0) && (now.second() == 0)) { Serial.println("ALARMA1"); }

if ((now.hour() == h2) && (now.minute() == 0) && (now.second() == 0)) {  Serial.println("ALARMA2"); }
}