Problema encendido led con TimeAlarms y/o con pulsador

La idea es encender un led con las alarmas que proporciona la librería TimeAlarms, hasta ahí bien, el problema me surje al intentar encender el mismo led con un pulsador.
Meto código en el loop para comprobar el estado del pulsador, si el pulsador no está actuado y la alarma de encendido está disparada, el led se enciende y apaga sin esperar a la alarma de apagado.
Ya estoy un poco liado, os agradecería si alguno me pudiérais orientar para que el loop no me apague el led...
Ahí va el código
Saludos

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

int LED = 13;    // Define pin donde está el LED
int BOTON = 2;   // Define pin donde está el BOTON 


void setup()
{
  pinMode(LED,OUTPUT);
  pinMode(BOTON,INPUT);
  
  Serial.begin(9600);
  Wire.begin();
  setSyncProvider(RTC.get);   // esta función obtiene la hora del RTC
    if(timeStatus()!= timeSet)
      Serial.println("NO es posible sincronizar con RTC");
    else
      Serial.println("RTC ha ajustado la hora Arduino");
  //setTime(8,29,0,1,1,11); // set time to Saturday 8:29:00am Jan 1 2011
  // Crear las alarmas 
  Alarm.alarmRepeat(23,46,0,EveningAlarm);  // Cada día
  Alarm.alarmRepeat(23,47,0,MorningAlarm);  // Cada día
  
  Alarm.alarmRepeat(dowSunday,20,33,30,WeeklyAlarm);  // Cada Domingo 
Alarm.delay(500); 
 
  Alarm.timerRepeat(15, Repeats);            // timer for every 15 seconds    
  Alarm.timerOnce(10, OnceOnly);             // called once after 10 seconds 
}

void  loop(){  
  
  digitalClockDisplay();
  Alarm.delay(1000); // espera un segundo para mostrar cambio de hora
  if (digitalRead(BOTON) == HIGH)
  {digitalWrite(LED,HIGH);}
  else
  {digitalWrite(LED,LOW);}

}  
  

// Funciones que serán llamadas cuando disparen las alarmas:

void MorningAlarm(){
  Serial.println("Alarma: - Apagar luces");
  digitalWrite(LED,LOW);
}

void EveningAlarm(){
  Serial.println("Alarma: - Encender luces");
  digitalWrite(LED,HIGH);
}

void WeeklyAlarm(){
  Serial.println("Alarma: - Domingo tarde");      
}

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

void Repeats(){
  Serial.println("Temporizado ciclo de 15 segundos");         
}

void OnceOnly(){
  Serial.println("Este temporizado solo actua una vez");  
}

void digitalClockDisplay()
{
  // Mostrar la hora por el Monitor Serial
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.println(); 
}

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

No entiendo bien la librería de la alarma que decis. Tampoco entiendo bien, que debería pasar si al estar la alarma activada, presionas el botón. Pero el problema en tu código está acá creo:

if (digitalRead(BOTON) == HIGH)

Debería ser algo como:

if (digitalRead(BOTON) == HIGH && alarma == algo)

Osea, si el botón fué presionado y además considerar como está la alarma en ese momento. Pero no entiendo esa librería como para decirte exactamente que habría que poner, pero dentro del IF debes ver eso y no sólo el estado del botón.

Gracias por tu ayuda

Para ser más explícito, se trata de encender o apagar un led en un intervalo programado, así como poder hacerlo fuera de ese intervalo. La librería TimeAlarms me permite programar la hora de disparo para encender el led y la de apagado fácilmente, para ello creo dos alarmas, en una enciende y en la otra apaga. En el loop he probado con varias piezas de código que me comprueban el estado del led cuando pulso el botón manualmente y cuando no lo pulso, a saber:
--Botón pulsado y led apagado --> encender led
--Botón pulsado y led encendido --> encender led
--Botón no pulsado y led apagado --> apagar led
--Botón no pulsado y led encendido -> encender led (aquí es donde tengo el problema)

El último caso se correspondería con la actuación de la alarma de disparo (el led está encendido y el botón no pulsado), sucede que si pulso el botón, al soltarlo, el led queda encendido permanentemente (sólo lo apaga una alarma de apagado).

Si en el último caso determino apagar el led, sucede que al actuar una alarma de disparo el led enciende pero al momento se apaga.

En cuanto a trabajar con un objeto que me compruebe si la alarma está en el intervalo de disparo del led, no sé como se hará con esta librería, con lo que estoy explorando otras formas de realizar una tarea que aparentemente es sencilla pero que me está haciendo calentarme la cabeza, (jeje, cosa que no es malo).

Sugerencias serán bien recibidas.

Saludos

Sep, mas o menos entiendo la idea, y creo que tengo un código similar. Veré si lo puedo adaptar para lo que estás haciendo.

PD: En la descripción del código que haces me mareas un poco :stuck_out_tongue: no nombras la alarma en este.

--Botón pulsado y led apagado --> encender led
--Botón pulsado y led encendido --> encender led
--Botón no pulsado y led apagado --> apagar led
--Botón no pulsado y led encendido -> encender led (aquí es donde tengo el problema)

(¿Dónde dices "y led encendido" o "y led apagado", sería "alarma" cierto?)

PD2: ¿Es un botón "temporal" o usas uno que si lo pulsas se queda pulsado?

Efectivamente, donde digo led encendido me refiero a alarma; en cuanto al botón, la primera idea es usarlo como pulsador (pulsado actúa y en cuanto suelto abre) pero se podría explorar una solución de tipo enclavado (pulsado actúa y ahí se queda al soltar, si pulso una segunda vez abre y se mantiene abierto).

Ahí encontré las 3 librerías. Veré si eso me ayuda a entender mejor el código.

PD: Igual el código me tirará error, porque no tengo el dispositivo que le provee la hora al Arduino, pero al menos para intentar probar lo demás.

Creo que ya caí en la cuenta de como hacerlo.

¿La alarma enciende el Led en el período que está activa cierto?

Probemos esto:

  digitalClockDisplay();
  Alarm.delay(1000); // espera un segundo para mostrar cambio de hora
  if (digitalRead(BOTON) == HIGH) //Sin importar el estado de la alarma, el led debe ser encendido
  {digitalWrite(LED,HIGH);}
  else //El botón no está precionado
  {
if (onbyAlarm == 1) { } //Está encendido por la alarma (no lo apagamos nosotros)
else { digitalWrite(LED,LOW);} //No está encendido por la alarma, lo apagamos
}

Y en las funciones las modificas para que queden así:

void MorningAlarm(){
  Serial.println("Alarma: - Apagar luces");
  digitalWrite(LED,LOW);
  onbyAlarm = 0; //Apagado por la alarma
}

void EveningAlarm(){
  Serial.println("Alarma: - Encender luces");
  digitalWrite(LED,HIGH);
  onbyAlarm = 1; //Encendido por la alarma
}

En el inicio incluir

boolean onbyAlarm = 0;

No lo he probado, pero debería funcionar.

Probado y funcionando perfecto. Una solución muy elegante.
Muchísimas gracias.

:slight_smile: Que bueno que le di a la primera :stuck_out_tongue:

Si, es la mejor forma, siempre que se quiera "rastrear" el estado de algún pin o lo que sea, lo mejor es asignarlo a una variable, de esa forma es simple usarla en los IF y actuar en consecuencia.

También se puede leer el estado de dicho pin en ese momento, pero en este caso no hubiera servido, ya que al soltar el botón, el estado del pin del led, siempre iba a devolver que estaba encendido, pero nosotros no sabríamos si había sido encendido por el botón, o si previamente ya estaba encendido por la alarma :wink: