Orientacion e inicializacion codigo Horas/fechas

He leido bastante el foro, en varios idiomas y en casi todos he visto que preguntan por crear programas que partiendo de una fecha (dia, mes, año, hora, minutos) concreta al dia siguiente se active o se desactive algo unos minutos antes o despues. Sobre todo lo he visto en temas de animales (acuarios, terrarios, aviarios..etc)

Puede ser algo muy simple, pero para mi no lo es, bien por falta conocimientos o por la edad, me propuesto intentar crear un codigo para ello y documentarlo para futuras visitas buscando esa informacion.

En el codigo muy basico que he escrito, parto de un primer dia de un mes, en el mes siguiente hay 2 dias ( es la parte que no se hacer) y de otro grupo de dias de un tercer mes.

la idea seria que partiendo de la hora clave encendiera por ejemplo 2 minutos antes y apagara 2 minutos despues el dia siguiente y asi los aumentara cada dia, pero al cambiar de mes, como sabe a que hora ha de hacerlo???, esa es la parte donde me pierdo......

#include <Wire.h>
#include "RTClib.h"
byte N = 2;// variacion de mas o menos

RTC_DS1307 RTC;

//**********************primer dia*************************

byte horaInicio = 18;
byte minutoInicio = 24;
byte horaFin = 18;
byte minutoFin = 30;
byte mesInicio = 9;//septiembre
byte diaInicio = 29;// dia inicio

//**********************ultimo dia*****************************

byte horaInicioFinal = 18;
byte minutoInicioFinal = 55;
byte horaFinal = 19;
byte minutoFinal = 10;
byte mesFinal = 11;//noviembre
byte diaFinal = 3;// dia final


void setup () {

  Wire.begin();
  RTC.begin();
  pinMode(5, OUTPUT);

}//fin setup

void loop () {

  DateTime now = RTC.now();
  int momentoAhora = (now.hour() * 60) + now.minute();

  int momentoInicio = ( horaInicio * 60) + minutoInicio;
  int momentoFin = (horaFin * 60) + minutoFin;

  int momentoInicioFinal = ( horaInicioFinal * 60) + minutoInicioFinal;
  int momentoFinal = (horaFinal * 60) + minutoFinal;




  if (now.month() == mesInicio) { //septiembre

    if (now.day() == diaInicio) { //dia 29

      if ((momentoInicio <= momentoAhora) && (momentoAhora < momentoFin)) digitalWrite(5, HIGH);


      else {
        digitalWrite(5, LOW);
      }


    }//fin dia 29

    if (now.day() == diaInicio + 1) { //dia 30

      if ((momentoInicio - N <= (momentoAhora )) && (momentoAhora  < momentoFin + N)) digitalWrite(5, HIGH);


      else {
        digitalWrite(5, LOW);
      }


    }//fin dia 30


  }//fin mes septiembre

  //************************************************************* resolver el problema///////////////////
  if (now.month() == mesFinal - 1) or (now.month() == mesInicio + 1) { //octubre

    if (now.day() == ?? ) { //dia X mes octubre, en teoria dia 1

      if ((momentoInicio - 2 * N <= momentoAhora) && (momentoAhora < momentoFin + 2 * N)) digitalWrite(5, HIGH);


      else {
        digitalWrite(5, LOW);
      }
    }//fin dia X

    if (now.day() == ?? ?? ) { //dia Y octubre, en teoria dia 31

      if ((momentoInicio - 3 * N <= momentoAhora ) && (momentoAhora < momentoFin + 3 * N)) digitalWrite(5, HIGH);


      else {
        digitalWrite(5, LOW);
      }
    }//fin dia Y
  }//fin mes octubre

  //*******************************************fin resolver el problema///////////////////
  if (now.month() == mesFinal ) { //noviembre

    if (now.day() == diaFinal - 2 ) { //dia 1

      if ((momentoInicioFinal + 2 * N <= momentoAhora) && (momentoAhora < momentoFinal - 2 * N)) digitalWrite(5, HIGH);


      else {
        digitalWrite(5, LOW);
      }
    }//fin dia 1

    if (now.day() == diaFinal - 1 ) { //dia 2

      if ((momentoInicioFinal + N <= momentoAhora)) && (momentoAhora  < momentoFin - N)) digitalWrite(5, HIGH);


        else {
          digitalWrite(5, LOW);
        }
    }//fin dia 2

    if (now.day() == diaFinal ) { //dia 3, dia final

      if ((momentoInicioFinal <= momentoAhora ) && (momentoAhora  < momentoFinal)) digitalWrite(5, HIGH);

      else {
        digitalWrite(5, LOW);
      }
    }//fin dia 3
  }//fin mes noviembre

}//fin loop

Seguramente haya mil maneras de hacerlo mucho mas facil y mejor que esta, si alguien me quiere orientar me gustaria intentarlo, solo es por entretenimiento y por dejar 1 granito de arena en el foro.


Habia pensado otra manera para meses completos o semicompletos y seguidos, que el programa contara los dias que pasan desde la fecha de inicio hasta la fecha de final, mas o menos son las ideas que han dado a quien ha preguntado en el foro, pero no han llegado a resolver y no se por donde empezarlo.

@Surbyte igual el tema es una tonteria, pero veo que lo han preguntado y no han concluido nada, seria un aporte muy bueno hacerlo y documentarlo por entero.

De nuevo si has leído tanto habrás encontrado respuestas mías donde hablo de una librería que lo hace 10 puntos pero también se puede hacer manualmente digamos.

La libreria se llama TimeAlarms, creo que es lo que necesitas.

El otrro método es similar a lo que tu estabas haciendo.
Convertir el tiempo en segundos y hacer consultas en función de eso. La librería hace lo mismo pero agrega un manejo mas elaborado
Si conviertes la hora, min, seg actuales a segundos tienes siempre un número
Si conviertes tu horario de arranque-parada solo debes consultar si estas o no dentro de ese lapso de tiempo.
Es mas fácil que hacerlo con tantas consultas como veo en tu código, pero tu código esta bien.

Crea una función que devuelva un valor en segundos del dia o mes, empecemos algo diario y luego expandamos a meses.

long conviertoTiempo(int hora, int min, int seg) {
      long tmp =hora*3600+min*60+seg;
      return tmp;
}

Ahora en tus consultas solo estableces la hora de consulta digamos 8:00:00 arranca y 10:30:30 apaga

long arranca = conviertoTiempo(8,0,0);
long apaga = conviertoTiempo(10,30,30);

Acá se visualiza que usar una structura que arrastre todo lo relevante sería muy util. Algo como esto

structure _tiempos {
    long start;
    long stop;
    bool status;
}

En las deficiones globales.

// defines asi
_tiempos tiempoControl;

En el setup puedes definir esto

// con estos pasos asigno los valores a mi estructura 
tiempoControl.start = conviertoTiempo(8,0,0);
tiempoControl.stop = conviertoTiempo(10,30,30);
tiempoControl.status = false; // indico que no se ha usado.

y en el loop tus acciones

long ahora = conviertoTiempo(now.hour(), now.minute(), now.second();
if ( ahora >= tiempoControl.start && !tiempoControl.status) {
   // enciendes lo que corresponda
   tiempoControl.status = true;  // me sirve para accionarlo 1 sola vez
}

if ( ahora > =tiempoControl.stop && tiempoControl.status) {
   // apagas lo que corresponda
   tiempoControl.status = false;  // me sirve para apagarlo 1 sola vez
}

EDITO: Estoy observando que TimeAlarms no contempla el uso de meses asi que en principio no te servirá.
Queda ampliar la idea que te he dado si es que resuslta de tu agrado..
Viendo la librería observo que eran intención del programador continuar y crear estas opciones

// new time based alarms should be added just before dtLastAlarmType
typedef enum {
  dtNotAllocated,
  dtTimer,
  dtExplicitAlarm,
  dtDailyAlarm,
  dtWeeklyAlarm,
  dtLastAlarmType
} dtAlarmPeriod_t ; // in future: dtBiweekly, dtMonthly, dtAnnual

Pero se aburrió, hace 4 años que no la modifica o mejora.
Sería un trabajo interesante para que nuestro foro completara.

Ya te lo han respondido @PeterKanTropus en el otro hilo que para mi es lo mismo que este pero como yo lo cerré y luego alguien pidió que lo reabriera para hacerte mas sugerencias comentarios no he considerado este como doble posteo pero de hecho lo es.

Respecto de TimeAlarms yo he comentado que el autor no sigue la idea pero el foro podría hacerlo pero no hubo respuesta y yo no tengo tiempo.

Te aclaro una cosa, en el otro hilo te conteste como hacer fácilmente lo estas buscando en este ¿por que te conteste en el otro hilo? porque cuando termine de programar el ejemplo busque el hilo y como son casi lo mismo te conteste en el otro.