Reloj DS1302 No configura [ SOLUCIONADO ]

Hola a todos:

He encontrado un código para reloj RTC con el modulo DS1302.

El reloj marca el tiempo, pero no deja configurar (a fecha real de hoy: 7 Octubre a las 12:30 .Marca: >2063-11-31-domingo-14-21-50.

Lo encontré en:

El codigo de configuracion:

/*
 * 
 * RELOJ CONFIGURACION 2 EXPE
 * 
 * 
 */

 #include <Arduino.h>
#include <Ds1302.h>

// Definición de los pines para la conexión del módulo DS1302
#define PIN_RST 2  // Pin de reinicio (RST) del DS1302
#define PIN_CLK 3  // Pin de reloj (CLK) del DS1302
#define PIN_DAT 4  // Pin de datos (DAT) del DS1302

// Instancia del objeto DS1302 para manejar el RTC (Real Time Clock)
Ds1302 rtc(PIN_RST, PIN_CLK, PIN_DAT);

// Función para convertir una cadena de caracteres a un número de 8 bits
uint8_t parseDigits(char* str, uint8_t count)
{
    uint8_t val = 0;
    while(count-- > 0) val = (val * 10) + (*str++ - '0');  // Convierte cada dígito de la cadena en un número
    return val;
}

void setup()
{
    rtc.init();  // Inicializa el módulo DS1302
    Serial.begin(9600);  // Inicia la comunicación serial a 9600 bps
    Serial.println("Ingresa la fecha y la hora (AAMMDDWhhmmss): ");  // Mensaje para el usuario
}

void loop()
{
    static char buffer[13];  // Buffer para almacenar los caracteres ingresados
    static uint8_t char_idx = 0;  // Índice para controlar la posición en el buffer

    // Si se han ingresado 13 caracteres, se procesa la fecha y hora
    if (char_idx == 13)
    {
        // Estructura para almacenar la fecha y hora a configurar
        Ds1302::DateTime dt;

        // Asignación de valores a la estructura `dt` a partir del buffer
        dt.year = parseDigits(buffer, 2);      // Años
        dt.month = parseDigits(buffer + 2, 2); // Meses
        dt.day = parseDigits(buffer + 4, 2);   // Días
        dt.dow = parseDigits(buffer + 6, 1);   // Día de la semana
        dt.hour = parseDigits(buffer + 7, 2);  // Horas
        dt.minute = parseDigits(buffer + 9, 2);// Minutos
        dt.second = parseDigits(buffer + 11, 2);// Segundos

        rtc.setDateTime(&dt);  // Configura la fecha y hora en el RTC

        char_idx = 0;  // Reinicia el índice del buffer para la próxima entrada
    }

    // Si hay datos disponibles en el puerto serial, se leen y se almacenan en el buffer
    if (Serial.available())
    {
        buffer[char_idx++] = Serial.read();  // Lee un carácter del puerto serial y lo almacena en el buffer
    }
}

El de uso:

/*
 * 
 * RELOJ FUNCIONAMIENTO 2 EXPER
 * 
 * 
 */

 #include <Arduino.h>
#include <Ds1302.h>

// Definimos los pines de conexión para el módulo DS1302
#define PIN_RST 2  // Pin de reinicio (RST) del DS1302
#define PIN_CLK 3  // Pin de reloj (CLK) del DS1302
#define PIN_DAT 4  // Pin de datos (DAT) del DS1302

// Instancia del objeto DS1302 para manejar el RTC (Real Time Clock)
Ds1302 rtc(PIN_RST, PIN_CLK, PIN_DAT);

// Definimos un arreglo de cadenas para representar los días de la semana
const static char* DiasdelaSemana[] =
{
    "Lunes", "Martes", "Miercoles", "Jueves", "Viernes", "Sabado", "Domingo"
};

void setup()
{
    Serial.begin(9600);  // Inicia la comunicación serial a 9600 bps
    rtc.init();          // Inicializa el módulo DS1302
}

void loop()
{
    // Estructura para almacenar la fecha y hora actual
    Ds1302::DateTime now;
    rtc.getDateTime(&now);  // Obtiene la fecha y hora del RTC y la guarda en 'now'

    static uint8_t ultimo_segundo = 0;  // Variable para almacenar el último segundo registrado

    // Verifica si ha pasado un segundo desde la última vez que se actualizó
    if (ultimo_segundo != now.second)
    {
        ultimo_segundo = now.second;  // Actualiza la variable 'ultimo_segundo' con el segundo actual

        // Buffer para almacenar la cadena formateada de fecha y hora
        char buffer[30];
        sprintf(buffer, "20%02d-%02d-%02d %s %02d:%02d:%02d",
                now.year, now.month, now.day,                          // Año, mes, día
                DiasdelaSemana[now.dow - 6],                           // Día de la semana
                now.hour, now.minute, now.second);                     // Hora, minuto, segundo

        Serial.println(buffer);  // Imprime la cadena formateada en la consola serial
    }
    
    delay(10);  // Pequeño retraso para evitar saturar el loop
}

Agradecería vuestra colaboración !!! :cocktail_glass:... :cocktail_glass:

El DS1302 es regular/pobre RTC, cumple con su función, pero tiene un corrimiento por dia importante. Usa en su lugar el DS3231.
Otro tema es la librería.
Siempre he usado DS1302 o DS3231 con librerías que usan I2C. Claro que lo que propones funciona. Pero estas librerias que estan en tu gestor tienen ejemplos completos para DS1302 o DS3231/2.
IC2 usa A4 y A5.

Ese es el precio de Adafruit. Lo vas a conseguir mucho mas barato.
Ahora hace falta un RTC con un UNO/NANO para tu proyecto?
Si usas algo que tenga Wifi, podrás usar un reloj NTP que usa lo mismo que tu PC. No necesitas nada extra. Simplemente siempre esta sincronizado. Claro, si se corta la energía no tienes reloj.

Hola @Surbyte

Tienes razón, el DS1302 no tiene una gran exactitud (gana 2/3 seg. diarios) , pero… era el único que tenían en una tienda física.

Con mas tiempo, (o por internet) comprare el que tu comentas.

De la consulta primera, al final cambie de código , encontré este para configuración del reloj:

[code]
    /*
     * 
     * 
     * 
     * RELOJ  DS1302   TREBOADA_CONFIGURACION
     * 
     * https://github.com/Treboada/Ds1302/blob/master/examples/get-date-time/src/main.cpp
     
     * Obtener fecha y hora.cpp
     *
     * Ejemplo de CONFIGURACION de la fecha y la hora del RTC.
     *
     * @version 1.0.1
     * @author Rafa Couto <caligari@treboada.net>
     * @license GNU Affero General Public License v3.0
     * @see https://github.com/Treboada/Ds1302
     * 
     *
     * 
     *
     */
    
    #include <Arduino.h>
    #include <Ds1302.h>
    
                                 // Definición de los pines para la conexión del módulo DS1302 
    #define PIN_CLK 4  // Pin de datos (CLK) del DS1302
      
    #define PIN_DAT 3  // Pin de reloj (DAT) del DS1302
       
    #define PIN_ENA 2  // Pin de reset (ENA) del DS1302> RST
    
                                            // DS1302 RTC instance
    Ds1302 rtc(PIN_ENA, PIN_CLK, PIN_DAT);
                                //Ds1302 rtc(PIN_ENA, PIN_DAT, PIN_CLK);// CAMBIO
      
    uint8_t parseDigits(char* str, uint8_t count)
    {
        uint8_t val = 0;
        while(count-- > 0) val = (val * 10) + (*str++ - '0');
        return val;
    }
    
    
    void setup()
    {
        // initialize the RTC
        rtc.init();
    
        Serial.begin(9600);
        Serial.println("CONFIGURANDO (2ªVERSION) ");
        Serial.println("Ingrese la fecha y hora (AAMMDDWhhmmss): ");
    }
    
    
    void loop()
    {
        static char buffer[13];
        static uint8_t char_idx = 0; // Crea indice character
    
        if (char_idx == 13)  //Si, llega a 13....
        {                               
          Ds1302::DateTime dt;  // Estructura para gestionar fecha y hora
  
          dt.year = parseDigits(buffer, 2);
          dt.month = parseDigits(buffer + 2, 2);
          dt.day = parseDigits(buffer + 4, 2);
          dt.dow = parseDigits(buffer + 6, 1);
          dt.hour = parseDigits(buffer + 7, 2);
          dt.minute = parseDigits(buffer + 9, 2);
          dt.second = parseDigits(buffer + 11, 2);
                                
          rtc.setDateTime(&dt); // Estructura para gestionar fecha y hora
  
          char_idx = 0; //  Indice vuelve a (0).
        }
    
        if (Serial.available())   
        {
            buffer[char_idx++] = Serial.read();  // Lee el buffer.
        }
        
    } //LL-LOOP.

    //*****************  FIN  *******************************

[/code]

Y este para su utilización:

[code]
  /*
   * 
   * RELOJ  DS1302   _TREBOADA_UTILIZACION  BUENO !!!!!
   * 
   * https://github.com/Treboada/Ds1302/blob/master/examples/get-date-time/src/main.cpp
   
     GetDateTime.cpp
   *
   * Ejemplo de obtención de la fecha y la hora del RTC.
   *
   * @version 1.0.1
   * @author Rafa Couto <caligari@treboada.net>
   * @license GNU Affero General Public License v3.0
   * @see https://github.com/Treboada/Ds1302
   *
   */
  
   
   #include <Arduino.h>
   #include <Ds1302.h>
   
 
   #define PIN_CLK 4  // Pin de reloj (CLK) del DS1302
    
   #define PIN_DAT 3  // Pin de datos (DAT) del DS1302
     
   #define PIN_ENA 2  // Pin de reset (ENA) del DS1302> RST
  
                                    
  
  Ds1302 rtc(PIN_ENA, PIN_CLK, PIN_DAT);    // DS1302 RTC instancia
  
  const static char* DiaSema[] =           // array  "CHARACTERS"
  {
      "Lunes",
      "Martes",
      "Miercoles",
      "Jueves",
      "Viernes",
      "Sabado",
      "Domingo"
  };
  
  
  void setup()
  {
      Serial.begin(9600);
      Serial.println("   ======================================== ");
      Serial.println("   =====  RELOJ DS1302 -- 2ª VERSION  =====   ");
      Serial.print("   ======================================== \n");   
                                 
      rtc.init();// inicializa RTC
      
     // prueba si el reloj está detenido y establece una fecha y hora (ver ejemplo 2)?? para iniciarlo
      if (rtc.isHalted())
      {
      Serial.println("El RTC está detenido. Ajuste de la hora...");

      Ds1302::DateTime dt = 
   {
      .year = 17,          // Estas variables son provisionales,se actualizan en el curso del programa.
      .month = Ds1302::MONTH_OCT,
      .day = 3,
      .hour = 4,
      .minute = 51,
      .second = 30,
      .dow = Ds1302::DOW_TUE  // Dia  de la Semana
   };

      rtc.setDateTime(&dt);
    }
  }
  
  
  void loop()
  {                          
      Ds1302::DateTime now;           // obtiene la hora actual
      rtc.getDateTime(&now);
  
      static uint8_t last_second = 0;
      if (last_second != now.second)  // Si,el anterior segundo NO es igual que el nuevo segundo....
      {
          last_second = now.second;  // ..."now.second" cambia a "last_second".
  
          Serial.print("20");
          Serial.print(now.year);    // 00-99
          Serial.print('-');
          if (now.month < 10) Serial.print('0');
          Serial.print(now.month);   // 01-12
          Serial.print('-');
          if (now.day < 10) Serial.print('0');
          Serial.print(now.day);     // 01-31
          Serial.print(' ');
          Serial.print(DiaSema[now.dow - 1]); // resta -1 a la posicion en el array:(anula el "0").Empieza en "1"
          Serial.print(' ');
          if (now.hour < 10) Serial.print('0');
          Serial.print(now.hour);    // 00-23
          Serial.print(':');
          if (now.minute < 10) Serial.print('0');
          Serial.print(now.minute);  // 00-59
          Serial.print(':');
          if (now.second < 10) Serial.print('0');
          Serial.print(now.second);  // 00-59
          Serial.println();
      } 
      delay(100);
      
  }  //LL-LOOP.

  //*********************************  FIN  *************************

[/code]

Ha funcionado todo correctamente, por tanto, si no tienes nada mas que aconsejarme, en unos días, lo marcare como SOLUCIONADO .

Un saludo @Surbyte !!..:cocktail_glass::cocktail_glass: