Cambio de horario Verano/invierno

Hola a todos, soy nuevo en el foro y tal vez este ahogándome en un vaso de agua pero necesito de su ayuda. recientemente realice un reloj con arduino usando un RTC DS3231, un LCD 16x2 con su interfaz I2C y todo funciona bien, pero quiero agregar la funcion del camio de horario. leyendo y buscando en otros foros encontra un codigo en el que resolvian este problema asi que decidi copiarlo y correrlo sin realizar ningun cambio al codigo original. pero la sorpresa fue que no compilaba y siempre me aparecia el error 'setDateDs1307' was not declared in this scope tambien note que algunos comandos como por ejemplo "dayOfMonth" no se torna color naraja como las otras "dayOfWeek"quisiera saber si esto tiene solución. este es el codigo tal cual lo encontre, no movi nada.

#include <OneWire.h>  
#include <Wire.h>   
#include "RTClib.h" // Incluye la librería RTClib  
#define DS1307_I2C_ADDRESS 0x68 
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year; 
boolean HoraRetrasa; 

void setup() 
{ 
Serial.begin(9600); 
Wire.begin(); 
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;  
pinMode(9, OUTPUT); // ajudicamos esa salida a la serie (tip 141) 
 /* Solo queremos poner en hora el reloj una vez y luego quitar la llamada de setDateDs1307. Activar esta parte y luego quitarla */ 
/*   
 second = 00;  
 minute = 50;  
 hour = 17;  
 dayOfWeek = 5;  
 dayOfMonth = 28;  
 month = 3;  
 year = 14;  
 setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year);   
*/ 
} 

void loop()  
{ 
getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year); //Obtenemos la hora 
Pot(minute, hour); // declaramos fase,tiempos , hora y minutos para la fase 

if (minute != minutoMemory) //Si es un nuevo minuto comprobamos cambio de hora 
    { 
   ActualizaMinuto(); 
    } 
Luces(minute, hour); 
} 


void ActualizaMinuto() //Cambiar hora verano-invierno 
{ 
   //Adelanta la hora a partir del dia 25 de Marzo, busca el primer domingo 
   //y cuando se han las 2 de la noche adelanta el reloj una hora 
   if (month==3) 
   { 
      if (dayOfMonth >= 26) 
      { 
        if (dayOfWeek = 7)       
        { 
          if (hour==2) 
          { 
             hour = 3; 
             setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year); 
          } 
        } 
         
      } 
   } 
   //Retrasa la hora a partir del dia 25 de Octubre, busca el primer domingo 
   //y cuando se han las 2 de la noche retrasa el reloj una hora 
   if (month==10) 
   { 
      if (dayOfMonth >= 26) 
      { 
        if (dayOfWeek = 7)       
        { 
          if ((hour==2)&&(HoraRetrasa==false)) 
          { 
             hour = 1; 
             HoraRetrasa=true; 
             setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year); 
          } 
        } 
         
      } 
   } 
   if (hour==3) 
   { 
     HoraRetrasa=false; 
   } 
  minutoMemory=minute; 

} 



void Luces(int minutos, int horas) 
{ 
///////////tiempos de progamacion////////// 
int PotLED; 
int InicioAmanecerLED=720; //12:00 
int FinAmanecerLED=780; //13:00 // 
int InicioAnochecerLED=1320; //22:00// 
int FinAnochecerLED=1380; //23:00// 
int MaxLED=125; //Maximo que vamos a encender los LED sobre 255 
int Tiempo;  
Tiempo=horas*60+minutos; 

if (Tiempo < 60) 
 { 
  Tiempo=Tiempo+1440; 
 } 

//Noche 
if (Tiempo < InicioAmanecerLED )  
 { 
  PotLED=0; 
  Serial.println(PotLED); 
 } 

//Amanecer 
if (Tiempo >= InicioAmanecerLED && Tiempo <= FinAmanecerLED)  
 { 
  PotLED=map(Tiempo,InicioAmanecerLED,FinAmanecerLED,0,MaxLED); 
  Serial.println(PotLED); 
 } 

//Dia 
if ((Tiempo > FinAmanecerLED) && (Tiempo < InicioAnochecerLED))  
 { 
  PotLED=MaxLED; 
  Serial.println(PotLED); 
 } 

//Anochecer 
if (Tiempo >= InicioAnochecerLED && Tiempo <= FinAnochecerLED) 
 { 
  PotLED=map(Tiempo,InicioAnochecerLed,FinAnochecerLED,MaxLED,0); 
  Serial.println(PotLED); 
 } 
//Control 
if(PotLED < 0)  
 { 
  PotLED=0; 
 } 

if(PotLED >MaxLED)  
 { 
  PotLED=MaxLED; 
 } 
analogWrite(9, PotLED); 

delay(1000); 
} 

byte bcdToDec(byte val)  // Convierte BCD (binario decimal codificado) a números normales decimales  
{ 
 return ( (val/16*10) + (val%16) ); 
} 

void setDateDs1307 (byte second, // 0-59 
                                byte minute, // 0-59 
                                byte hour, // 1-23 
                                byte dayOfWeek, // 1-7 
                                byte dayOfMonth, // 1-28/29/30/31 
                                byte month, // 1-12 
                                byte year) // 0-99 

{ 
Wire.beginTransmission(DS1307_I2C_ADDRESS); 
Wire.send(0); 
Wire.send(decToBcd(second)); // 0 a bit 7 inicia el reloj 
Wire.send(decToBcd(minute)); 
Wire.send(decToBcd(hour));  
Wire.send(decToBcd(dayOfWeek)); 
Wire.send(decToBcd(dayOfMonth)); 
Wire.send(decToBcd(month)); 
Wire.send(decToBcd(year)); 
Wire.endTransmission(); 
} 

// Establece la fecha y el tiempo del ds1307 
void getDateDs1307 (byte *second, 
                                byte *minute, 
                                byte *hour, 
                                byte *dayOfWeek, 
                                byte *dayOfMonth, 
                                byte *month, 
                                byte *year) 

{ 
// Resetea el registro puntero 
Wire.beginTransmission(DS1307_I2C_ADDRESS); 
Wire.send(0); 
Wire.endTransmission(); 
Wire.requestFrom(DS1307_I2C_ADDRESS, 7); 
// Alguno de estos necesitan enmascarar porque ciertos bits son bits de control  
*second = bcdToDec(Wire.receive() & 0x7f); 
*minute = bcdToDec(Wire.receive()); 
*hour = bcdToDec(Wire.receive() & 0x3f);  
*dayOfWeek = bcdToDec(Wire.receive()); 
*dayOfMonth = bcdToDec(Wire.receive()); 
*month = bcdToDec(Wire.receive()); 
*year = bcdToDec(Wire.receive()); 
}

Hola. Tendrías que poner tu código, el que dices que ya tienes y sobre él trabajar para hacer ese cambio de horario. Este código parece ser hecho para el DS1307 y no sabemos si tienes la misma librería instalada.

Si tienes un reloj hecho imagino que has implementado el método para setear la hora sin tener que usar una computadora y cargar de nuevo el sketch, por lo que ajustar el horario de verano no sería un trastorno.

Saludos

Hola, gracias por tu respuesta, este es mi codigo. el que tengo ya cargado en mi arduino y que funciona. no tiene ninguna linea referente al cambio de horario por que la verdad no se me ocurre como hacerle.

#include <Wire.h>
#include "RTClib.h"
#include <LiquidCrystal_I2C.h>
RTC_DS1307 RTC; //crea el objeto RTC


LiquidCrystal_I2C lcd (0x27,16,2); //inicializa la interfaz I2c con protocolo 0x27 de un LCD 16x2

void setup() {
 Serial.begin (9600); //establece la velocidad de datos del puerto serie
 Wire.begin (); // inicia el puerto I2C
 RTC.begin(); // Inicia la comunicación con el RTC
 //RTC.adjust (DateTime (__DATE__, __TIME__));
 //si lo activamos se sincroniza con el reloj de la PC, 
 //posteriormente se tiene que volver a cargar el programa 
 //pero con encomillado para que no siga buscando una PC a la cual sincronizar                                           
                                              
 lcd.init();
 lcd.backlight();
 lcd.clear();
 lcd.setCursor(0,0);
 lcd.print("  Cargando...");
 delay (2000);
 lcd.clear();
 
}

void loop() {
 DateTime now = RTC.now ();  //obtiene la fecha y hora del RTC
 
 Serial.print(now.day (),DEC); //Imprimimos el Día
 Serial.print ('/');
 Serial.print(now.month(),DEC); //Imprimos el Mes
 Serial.print ('/');
 Serial.print (now.year(),DEC); //Imprimimos el Año
 Serial.print (' ');
 Serial.print (now.hour(),DEC); //Imprimimos La hora
 Serial.print (':');
 Serial.print (now.minute(),DEC); //Imprimimos los Minutos
 Serial.print (':');
 Serial.print (now.second(),DEC); //Imprimimos los Segundos
 Serial.print (':');

 lcd.clear();
 lcd.setCursor(0,0); //poner el cursor en la posición 0,0
 lcd.print("Fecha:");
 lcd.print(now.day(),DEC);
 lcd.setCursor(8,0);
 lcd.print('/');
 lcd.setCursor(9,0);
 lcd.print(now.month(),DEC);
 lcd.setCursor(11,0);
 lcd.print('/');
 lcd.setCursor(12,0);
 lcd.print(now.year(),DEC);
 lcd.setCursor(2,1);
 lcd.print("Hrs:");
 lcd.setCursor(6,1);
 lcd.print(now.hour(),DEC);
 lcd.setCursor(8,1);
 lcd.print(":");
 lcd.setCursor(9,1);
 lcd.print(now.minute(),DEC);
 lcd.setCursor(11,1);
 lcd.print(":");
 lcd.setCursor(12,1);
 lcd.print(now.second(),DEC);
 delay(1000); //la información se actualiza cada 1 segundo.
 lcd.setCursor(13,0);


}

A ver este código, usando el tuyo y la rutina que cambia la hora.

#include <Wire.h>
#include <RTCLIB.h>
#include <LiquidCrystal_I2C.h>
RTC_DS1307 rtc; //crea el objeto rtc

LiquidCrystal_I2C lcd (0x27,16,2); //inicializa la interfaz I2c con protocolo 0x27 de un LCD 16x2
int minutoMemory;
int second, minute, hour, dayOfWeek, day, month, year;
bool HoraRetrasa = false;

void setup() {
  Serial.begin (9600); //establece la velocidad de datos del puerto serie
  Wire.begin (); // inicia el puerto I2C
  if (! rtc.begin()) {
      Serial.println("No pude encontrar un RTC");
      while (1);
  }

  if (rtc.lostPower()) {
      Serial.println("RTC lost power, lets set the time!");
      // following line sets the rtc to the date & time this sketch was compiled
      rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
      // This line sets the rtc with an explicit date & time, for example to set
      // January 21, 2014 at 3am you would call:
      // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
  }                                        
                                              
 lcd.init();
 lcd.backlight();
 lcd.clear();
 lcd.setCursor(0,0);
 lcd.print("  Cargando...");
 delay (2000);
 lcd.clear();
}

void loop() {
  DateTime now = rtc.now ();  //obtiene la fecha y hora del rtc
  actualizo();
  if (now.minute() != minutoMemory) {//Si es un nuevo minuto comprobamos cambio de hora 
      ActualizaMinuto(); 
  }

  char buffer[20];
  // digital clock display of the time
  sprintf(buffer, "%02d:%02d:%02d %02d/%02d/%04d", now.hour(), now.minute(), now.second(), now.day(), now.month(), now.year());
  Serial.println(buffer);
 
  lcd.clear();
  lcd.setCursor(0,0); //poner el cursor en la posición 0,0
  sprintf(buffer, "Fecha %02d/%02d/%04d", now.day(), now.month(), now.year());
  lcd.print(buffer);

  lcd.setCursor(2,1);
  sprintf(buffer, "Hrs:%02d:%02d:%02d", now.hour(), now.minute(), now.second());
  lcd.print(buffer);
  delay(1000); //la información se actualiza cada 1 segundo.
  lcd.setCursor(13,0);
}
void ActualizaMinuto() {//Cambiar hora verano-invierno 
    //Adelanta la hora a partir del dia 25 de Marzo, busca el primer domingo 
    //y cuando se han las 2 de la noche adelanta el reloj una hora 
   
    if (month == 3) { 
        if (day >= 26)  { 
            if (dayOfWeek = 7)   { 
                if (hour==2) { 
                    hour = 3; 
                    rtc.adjust(DateTime(year, month, day, hour, minute, second));
                } 
            } 
        } 
    } 
    //Retrasa la hora a partir del dia 25 de Octubre, busca el primer domingo 
    //y cuando se han las 2 de la noche retrasa el reloj una hora 
    if (month ==10)    { 
        if (day >= 26)   { 
            if (dayOfWeek = 7)  { 
                if ((hour==2)&&(HoraRetrasa==false))  { 
                    hour = 1; 
                    HoraRetrasa=true; 
                    rtc.adjust(DateTime(year, month, day, hour, minute, second));
                } 
            } 
        } 
    } 
    if (hour==3)   { 
        HoraRetrasa=false; 
    } 
    minutoMemory = minute; 
}

void actualizo() {
  DateTime now = rtc.now ();
  hour      = now.hour();
  minute    = now.minute();
  second    = now.second();
  day       = now.day();
  month     = now.month();
  year      = now.year();
  dayOfWeek = now.dayOfTheWeek();
}

No esta probado asi que si no funciona tomate un tiempo y no hagas la facil de preguntar por el primer error.

Mira la librería y sus ejemplos y podras deducir muchas cosas.

El cambio de horario de verano suele hacerse por ley o decreto en un determinado día del año.
Tienes que preguntarte si lo quieres hacer manualmente o automáticamente.

Si es manualmente tienes que agregar un pulsador que sume una hora o la reste según sea el caso y prever que sea accionado accidentalmente. Esto podría implementarse en el setup, y al momento de cambiar el horario de verano apagar arduino, y encenderlo con el botón presionado.

Si es automáticamente tendrías que adaptar el código a la ley de cambio de horario, ver cuales son las condiciones en tu país. En el código que enviaste primero busca el ultimo día domingo de octubre y marzo. En esta opción deber pensar en la posibilidad que arduino este apagado (sin energía) cuando se cumple la condición y no limitarte como en el ejemplo a una hora determinada, sino que si el cambio de hora no se ha hecho, se pueda hacer en cualquier momento posterior a que arduino recupere la energía.

Para ambos casos necesitas una variable que indique si estas en horario de verano y la guardes en la memoria eeprom de arduino. En el primero código esta definida como: HoraRetrasa=true

Daniel_Arg:
El cambio de horario de verano suele hacerse por ley o decreto en un determinado día del año.
Tienes que preguntarte si lo quieres hacer manualmente o automáticamente.

Que quieres preguntarte?
El único que no lo entiende eres tu Daniel_Arg.

Titulo del hilo: Cambio de horario Verano/invierno

oscarhdez91:
... todo funciona bien, pero quiero agregar la funcion del camio de horario.

A quien quieres preguntarle algo?

Esta mas que claro.
No hace falta cuestionar la razón de las personas.
Estoy de acuerdo en hacerlo si es peligroso para si mismo o para los demás pero esto no lo es.

Paises como España no se desde cuando hace que tienen automatizado su cambio de horario pero desde que estoy en Arduino (2014) siempre lo ha habido.

surbyte muchas gracias por tus palabras y tu modificación al código, como dijiste cheque un ejemplo de la librería y ya se resolvió, moví los parámetros para que sucediera el cambio el dia de hoy 13/10/2018 y a la hr mas cercana 4:30pm para verificar que efectivamente se llevara acabo el cambio de hora y si resulto. estoy muy agradecido. también corrobore que aunque se pierda el suministro de energía antes de que la acción de atraso o adelanto de la hr se lleve acabo, igualmente ocurrirá cuando se vuelva a suministrar energia.
¿solo me podrían decir como sucede esto de que aun que no haya energía el cambio se lleva acabo apenas vuelva esta? se que funciona por que lo acabo de probar pero no se el COMO funciona.

Mira la rutina o parte de ella

    if (month == 3) { 
        if (day >= 26)  { 
            if (dayOfWeek = 7)   { 
                if (hour==2) { 
                    hour = 3; 
                    rtc.adjust(DateTime(year, month, day, hour, minute, second));
                } 
            } 
        } 
    }

mientras estes en el mes en este caso mes = 3 y no llegues a fin de mes sin energía o sea

dias 26, 27, 28, 29, 30, 31 (según corresponda para el mes, se entiende)
Solo hay que confirmar que estamos en dia domingo

Acabo de dame cuenta que algunas librerías toma a dayOfWeek domingo como 0 y no 7 Verifica eso!!!
En esas circunstancias la rutina tiene varias chances de ajustarse.

en el ejemplo que trae mi libreria de DS3231 viene

char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

según mi entender domingo seria "0" no?

y en lo que respecta a lo de la energía, si llegara el caso de estar del 26 al 31 del mes sin energía (espero que nunca me quede tanto tiempo sin energia) y pum! llegara la energía el día 1 de abril, no habría cambio de hr verdad?

No habría a menos que replantees el código.
Bastaría vigilar el flag que controle el cambio de horario en lugar de estar pendiente de un horario.
A ver si me explico mejor.

Ahora estas pendiente de una fecha sujeta a que se den ciertas condiciones pero como tu bien dijiste... supongamos que... se da todo mal. Arduino falla y se queda sin energia por la razón.
Bueno.. entonces el flag debería estar guardado en EEPROM por ejemplo y detectar que no se ha cambiado.

Arrancamos chequeamos, vemos que hay que haer cambio y no se hizo.. entonces CAMBIAR de lo contrario no se hace nada y se sigue normal.

hamm.. estuve viendo unos videos de como usar la memoria EEPROM y segun lo que entendi, con esto se arregla lo de la falta de energia serbyte, el sketch no me muestra ningun error pero quisiera saber si esta bien.

#include <Wire.h>
#include "RTClib.h"
#include <LiquidCrystal_I2C.h>
#include <EEPROM.h>   //Anexamos la libreria para usar la memora EEPROM de Arduino
RTC_DS3231 rtc; //crea el objeto rtc

LiquidCrystal_I2C lcd (0x27,16,2); //inicializa la interfaz I2c con protocolo 0x27 de un LCD 16x2
int minutoMemory;
int second, minute, hour, dayOfWeek, day, month, year;
bool HoraRetrasa = false;
//Variables para la memoria EEPROM
byte ee_valor0;
byte ee_valor1;

void setup() {
 Serial.begin (9600); //establece la velocidad de datos del puerto serie
 Wire.begin (); // inicia el puerto I2C
 if (! rtc.begin()) {
     Serial.println("No pude encontrar un RTC");
     while (1);
 }

 if (rtc.lostPower()) {
     Serial.println("RTC lost power, lets set the time!");
     // following line sets the rtc to the date & time this sketch was compiled
     rtc.adjust(DateTime(__DATE__, __TIME__));
     // This line sets the rtc with an explicit date & time, for example to set
     // January 21, 2014 at 3am you would call:
     // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
 }

 ee_valor0 = EEPROM.read (0); //lee el valor de la memoria eeprom en la direccion 0 y es asignado este valor a la variable ee_valor0
 ee_valor1 = EEPROM.read (1); //lee el valor de la memoria eeprom en la direccion 1 y es asignado este valor a la variable ee_valor1
                                             
lcd.init();
lcd.backlight();
lcd.clear();
lcd.setCursor(0,0);
lcd.print("  Cargando...");
delay (2000);
lcd.clear();
}

void loop() {
 DateTime now = rtc.now ();  //obtiene la fecha y hora del rtc
 actualizo();
 if (now.minute() != minutoMemory) {//Si es un nuevo minuto comprobamos cambio de hora 
     ActualizaMinuto(); 
 }

 char buffer[20];
 // digital clock display of the time
 sprintf(buffer, "%02d:%02d:%02d %02d/%02d/%04d", now.hour(), now.minute(), now.second(), now.day(), now.month(), now.year());
 Serial.println(buffer);

 lcd.clear();
 lcd.setCursor(0,0); //poner el cursor en la posición 0,0
 sprintf(buffer, "Fecha %02d/%02d/%04d", now.day(), now.month(), now.year());
 lcd.print(buffer);

 lcd.setCursor(2,1);
 sprintf(buffer, "Hrs:%02d:%02d:%02d", now.hour(), now.minute(), now.second());
 lcd.print(buffer);
 delay(1000); //la información se actualiza cada 1 segundo.
 lcd.setCursor(13,0);
}
void ActualizaMinuto() {//Cambiar hora verano-invierno 
   //Adelanta la hora a partir del dia 25 de Marzo, busca el primer domingo apartir del dia 26 (busca el ultimo domingo del mes)
   //y cuando se han las 2 de la noche adelanta el reloj una hora 
  if(ee_valor0==1){    //Compara el valor contenido en la posición 0 de la memoria eeprom si es 1 realiza el cambio de horario
   if (month == 3) { 
       if (day >= 26)  { 
           if (dayOfWeek = 7)   { 
               if (hour==2) {
                   hour = 3; 
                   rtc.adjust(DateTime(year, month, day, hour, minute, second));
               } 
           } 
       } 
   } 

  }
   //Retrasa la hora a partir del dia 25 de Octubre, busca el primer domingo 
   //y cuando se han las 2 de la noche retrasa el reloj una hora 
   if (ee_valor1==1){
   if (month ==10)    { 
       if (day >= 26)   { 
           if (dayOfWeek = 7)  { 
               if ((hour==2)&&(HoraRetrasa==false))  { 
                   hour = 1; 
                   HoraRetrasa=true; 
                   rtc.adjust(DateTime(year, month, day, hour, minute, second));
               } 
           } 
       } 
   } 
}
   if (hour==3)   { 
       HoraRetrasa=false; 
   } 
   minutoMemory = minute; 
}

void actualizo() {
 DateTime now = rtc.now ();
 hour      = now.hour();
 minute    = now.minute();
 second    = now.second();
 day       = now.day();
 month     = now.month();
 year      = now.year();
 dayOfWeek = now.dayOfTheWeek();
}

surbyte:
Que quieres preguntarte?
El único que no lo entiende eres tu Daniel_Arg.

Titulo del hilo: Cambio de horario Verano/invierno
A quien quieres preguntarle algo?

Esta mas que claro.
No hace falta cuestionar la razón de las personas.

¿Que parte de: "Tienes que preguntarte si lo quieres hacer manualmente o automáticamente" no entendes? o ¿acaso crees que el la ley o un decreto es quien cambia la hora? Son los ciudadanos obligados por la ley a cambiar el uso horario.

Lo que es párrafo dice es que no todos los países lo hacen, incluso el mismo día y a la misma hora. ¿En España lo hacen entre las 2AM y 3AM? En nuestro país se hacia a las 00AM. Entonces sugiero consultar la ley del país para adaptar el código a ella.

En ningún momento le cuestiono querer implementar un horario de verano, incluso en un código que aún no tiene como ponerse en hora manualmente y depende de una computadora y la carga del sketch. O sea que el reloj si puede ajustarse una hora cuando llega octubre pero no se puede ajustar los segundos y minutos manualmente por ejemplo si se quedó sin batería... resulta al menos extraño por no decir ridículo...

Ningún reloj comercial viene con la función de horario de verano (entiéndase reloj y no sistemas operativos) incluso no es una medida universal y esta en permanente debate.

Bruselas legislará para abolir el cambio de hora en la Unión Europea

Están equivocados si creen que este código se va a cumplir mas allá de la hora 2AM de un único último domingo de marzo.

  if (month == 3) {
        if (day >= 26)  {
            if (dayOfWeek = 7)   {
                if (hour==2) {
                    hour = 3;
                    rtc.adjust(DateTime(year, month, day, hour, minute, second));
                }
            }
        }
    }

Entonces una opción era directamente dar un clic y que el reloj se adelante o atrase una hora. El procedimiento manual que hace, en este caso, cada ciudadano español y otros tantos de la UE.

Yo se lo que pasa. Me tienes entre cejas y cada vez que me lees te sube la ira y nubla el razonamiento. Pero debo reconocer que tienes huevos y reconoces cuando te equivocas. No como el otro que anda por ahí escribiendo comentarios que luego los borra pero se olvida que llegan los correos electrónicos. Este último párrafo lo puedes borrar después de banearme.

oscarhdez91:
Hola, gracias por tu respuesta, este es mi codigo. el que tengo ya cargado en mi arduino y que funciona. no tiene ninguna linea referente al cambio de horario por que la verdad no se me ocurre como hacerle.

En el último mensaje de este hilo tienes un código que hice para lámpara de acuario que usa el 3221. Tiene todo el procedimiento para cambiar la hora mediante un simple encoder y está todo comentado.

http://forum.arduino.cc/index.php?topic=565291.60

Vamos a poner orden en este tema.

Debo admitir que hay un error y que hay situaciones que no se darán facilmente. Veamos
Teniendo en cuenta la situación en que se quede sin energía el reloj a las puertas del cambio horario que obviamente es AUTOMATICO.
veamos que dice la rutina

if (month == 3) {

Tenemos que estar si o si en Marzo.

if (day >= 26)  {

Tiene que ser luego del dia 26 hasta fin de mes por ahora

           if (dayOfWeek = 7)   {

Tiene que ser domingo asi que no tenemos muchas opciones

               if (hour==2) {

Y la mayor restricción es que se cambia a la 2AM como dijo @Daniel_Arg y yo obvié este punto.

Lo peor es esto.

                   hour = 3;
                    rtc.adjust(DateTime(year, month, day, hour, minute, second));

Que si por alguna razón lo anterior me dejara hacerlo en otro horario me pondía las 3AM lo que sería una falla
En todo caso la hora deberia incrementarse en 1.

Asi que lo que se me ocurre es pasar todo a formato UNIX (sugiero esto porque esta implementado) y de ese modo tienes una representacion que puede resultar fuera de lo común pero que te dara margen para comparar lo que sea luego de la fecha indicada. Asi que en cuanto tu arduino recupere energía lo hará porque el flag de cambio de hora no esta cambiado y la condición de la fecha se ha superado

Sin embargo toda esta explicación podría obviarse si consideramos que hay una librería que hace todo esto de manera correcta pero... habra que evaluarla

TimeZona Library

Si miras la explicación (espero entiendas inglés dice)

Define a TimeChangeRule as follows:

TimeChangeRule myRule = {abbrev, week, dow, month, hour, offset};

Where:

abbrev is a character string abbreviation for the time zone; it must be no longer than five characters.

week is the week of the month that the rule starts.

dow is the day of the week that the rule starts.

hour is the hour in local time that the rule starts (0-23).

offset is the UTC offset in minutes for the time zone being defined.

For convenience, the following symbolic names can be used:

week: First, Second, Third, Fourth, Last
dow: Sun, Mon, Tue, Wed, Thu, Fri, Sat
month: Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec

For the Eastern US time zone, the TimeChangeRules could be defined as follows:

TimeChangeRule usEDT = {"EDT", Second, Sun, Mar, 2, -240}; //UTC - 4 hours
TimeChangeRule usEST = {"EST", First, Sun, Nov, 2, -300}; //UTC - 5 hours

O sea que te permite cambiar la hora de acuerdo a los criterios que elijas y correspondan a tu país.

Te invito a que la pruebes y compartas su comportamiento.
Y luego evaluamos si hace falta o no alguna consideración para el caso de la falla de energía.

ArduMyth es cierto ya cheque el post si es parecido a lo que estoy tratando de desarrollar lo checare a fondo.
surbyte descargare la librería y checare los ejemplos que vienen en ella para poder implementarlo en mi código.
la introduccion de la libreria dice:

Un objeto de zona horaria usa TimeChangeRules para realizar conversiones y funciones relacionadas. También puede escribir sus TimeChangeRules en EEPROM, o leerlas desde EEPROM. Se pueden representar múltiples zonas horarias definiendo múltiples objetos de Zona horaria.

y entre ellas da una breve descripción de los ejemplos que trae la librería, hay 2 que tienen que ver con la eeprom solo que no se cual se adecua mejor, la que "LEE" o la que "Escribe" en la eeprom :S

Clock: A simple self-adjusting clock for a single time zone. TimeChangeRules may be optionally read from EEPROM.

WriteRules: A sketch to write TimeChangeRules to EEPROM.

ArduMyth gracias. con este código también se resuelve lo del problema de si en dado caso de quedarse sin luz la ultima semana de Marzo y llegase la luz el dia 1 de Abril, aun se efectuaria el cambio de hr?

Pero Oscar, te damos 5 respuestas y no te alcanzan?
Se supone que tu debes poner algo de tu parte.

Porque no pruebas cada propuesta tomándote tu tiempo, y evalúas si funcionan o no.
Y luego vienes con la experiencia y nos dices, esta si por tal cosa, la otra no por tal otra.

El único reloj con arduino que tengo usa NTP.
El mismo sincroniza la hora con un servidor NTP y no hay cambio verano/invierno porque en mi país no hay cambio de horario.

Esta libreria Librería RTC para reloj Dallas DS1307 y DS3231 - el blog de giltesa te soluciona automaticamente el cambio horario, que creo que ya te lo comentaron (el aquel post pasado se habló de ella y se ofreció como solución)