adaptar un reloj RTC al horario peninsular (info)

Hola,
He montado un reloj RTC DS1307 (ebay 7,90 euros) con un atmega328 con los componentes mínimos, y funciona perfectamente. Voy a intentar que realice determinadas tareas en determinados días del calendario. Pero el problema que se me ha planteado es el calendario peninsular, adelantado una hora al horario solar en invierno, y adelantado en dos horas en verano.

He ajustado el DS1307 al horario solar (dos horas menos que lo que indica ahora el reloj del PC), y he pensado esta solución para que

  • el último domingo de marzo el Arduino se ajuste al horario de verano
  • el último domingo de octubre el Arduino se ajuste al horario de invierno
#define VERANO 2
#define INVIERNO 1

int adelanto;

setup()
{
   // realizar un primer ajuste por meses hasta que llegue un cambio de hora
   leer_hora();
   if(mes > MARZO && mes < NOVIEMBRE) adelanto = 2;
   else adelanto = 1;

}


loop()
{
leer_hora();
if(mes == MARZO && dia_mes > 24 && dia_semana == DOMINGO)
{
   if(adelanto == INVIERNO) adelanto = VERANO;
}

if(mes == OCTUBRE && dia_mes > 24 && dia_semana == DOMINGO)
{
   if(adelanto == VERANO) adelanto = INVIERNO;
}

El último domingo de un mes de 31 días es el domingo que toca a partir del día 25 ( si el 24 fuera domingo, también lo sería el 31)
En setup() se hace un primer ajuste por meses, para que sirva hasta que llegue la comprobación de marzo u octubre.
Seguro que esto estaba más que inventado, pero a mí me ha producido satisfacción el reinventarlo.
Acepto sugerencias para mejorar.

Eskerrik asko Curro92 por la info.

Es una informacion muy interesante y quepienso adaptar a mi reloj.

Pero me surge una duda, ¿si en el setup es donde verificamos el mes y resulta que el arduino lo hemos dejado conectado durante meses, no detectara el cambio no?

Quiero decir, a mi entender el setup solo lo ejecuta al inicio, y despues el arduino reproduce continuamente el loop, entonces, si pongo en marcha el proyecto 3 dias antes del cambio de mes y no lo apago en seis meses ¿Se cambiaria la hora? o por el contrario mantendria solo el valor inicial del mes.

Un saludo.

Hola,
En cada ciclo de loop() se ejecuta la función que he denominado "leer_hora()", pero que en realidad en el sketch se llama

getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);

Ok
Ahora si que lo veo claro.
Pues me reitero, muchas gracias por el codigo.
Un saludo

Añado como he cambiado mi reloj en funcion del codigo de Curro92 por si le vale a alguien. El RTC lo he dejado en la hora GMT, en España ahora mismo por ser verano tenemos GMT+2

Me queda la duda de si el RTC interpreta como primer dia de la semana el domingo o el lunes, creo que es el lunes.
Funcion de ajuste hora peninsular:

// ┌──────────────────────────────────────────────┐
// │  FUNCION Ajusta la hora peninsular                                              │
// └──────────────────────────────────────────────┘
void Hora_Peninsular(){
    DateTime now = RTC.now();
    if(now.month() == 3 && now.day() > 24 && now.dayOfWeek() == 7)
    {
    if(adelanto == INVIERNO) adelanto = VERANO;
    }

    if(now.month() == 10 && now.day() > 24 && now.dayOfWeek() == 7)
    {
     if(adelanto == VERANO) adelanto = INVIERNO;
    }
  }

Funcion que muestra la hora en el LCD

// ┌──────────────────────────────────────────────┐
// │  FUNCION Muestra Hora                                                           │
// └──────────────────────────────────────────────┘
void Muestra_hora(){
    Hora_Peninsular();
 
    // Hora real GMT sin los ajustes de +1 o +2 de invierno o verano
    DateTime now = RTC.now();      
    
    // Hora adelantada en funcion de verano o invierno
    DateTime future (now.unixtime() + 3600*adelanto); 

    // Muestra la fecha en la columna superior
    lcd.setCursor(0,0);
    lcd.print("Fecha 00-00-0000");
    
    if (future.day() < 10){lcd.setCursor(7,0);} else {lcd.setCursor(6,0);}
    lcd.print(future.day(), DEC);

    if (future.month() < 10){lcd.setCursor(10,0);} else {lcd.setCursor(9,0);}
    lcd.print(future.month(), DEC);

    lcd.setCursor(12,0);
    lcd.print(future.year(), DEC);

    // Muestra la hora en columna inferior
    lcd.setCursor(0,1);
    lcd.print("Hora       00:00");
    
    if (future.hour() < 10){lcd.setCursor(12,1);} else {lcd.setCursor(11,1);}
    lcd.print(future.hour(), DEC);
    
    if (future.minute() < 10){lcd.setCursor(15,1);} else {lcd.setCursor(14,1);}
    lcd.print(future.minute(), DEC);

    delay(900);
    lcd.setCursor(13,1);
    lcd.print(' ');
    delay(100);
}

La lectura de mi codigo es muy simple, no domino lo bastante como para comprimirlo en menos lineas ahora mismo, ya lo optimizare...

Hola,
en DS1307.h se definen los días,

#define MONDAY 1
#define TUESDAY 2
#define WEDNESDAY 3
#define THURSDAY 4
#define FRIDAY 5
#define SATURDAY 6
#define SUNDAY 7

El primero es el lunes, debe ser por aquello de "y al séptimo descansó"