Ayuda para temporizar

Hola, en esta época navideña he creado un programa para que las luces de fuera de la casa se enciendan cuando es de noche. Pero no me interesa que estén toda la noche encendidas.
He creado un programa con una LDR para que, a partir de un valor me active una salida. Esta salida activará un relé de estado solido.
Pero lo que no se hacer es que a las 4 o 5 horas de activarse la salida, se desactive. Y al día siguiente cuando se vuelva a hacer de noche se encienda.

Este es el programa que tengo para que se encienda cuando es de noche:

int ldr = 0;
int ldr_value = 0;
int bombilla = 12;

void setup()
{
pinMode (bombilla, OUTPUT);
Serial.begin(9600);
digitalWrite (bombilla, LOW);
}

void loop()
{
ldr_value = analogRead(ldr);
Serial.println(ldr_value);
delay(200);
if (ldr_value>=300){
digitalWrite(bombilla, HIGH);
}
else{
digitalWrite(bombilla,LOW);
}
}

Hola, recuerda leer las normas del foro y usar los tags para enlaces y códigos y comentarios de otros usuarios.

Este es el código reformado, supongo que TU código funciona bien, solo inserto un retardo de apagado de 4horas que puedes cambiar a gusto.

Para probarlo ponele un tiempo de 1 minuto a ver si funciona 1x60x1000 en RETARDO_APAGADO

#define RETARDO_APAGADO 4*60*60*100 // 4 hs x 60 min x 60 seg x 1000 mseg = 14.400.000 mseg

const byte ldrPin    = A0;         
const byte bombilla  = 12;   
int ldr_value        = 0;   
bool mantenerON = false;
bool ultimoEstado = false;
unsigned long time;

void setup()
{
  pinMode (bombilla, OUTPUT);
  Serial.begin(9600);
  digitalWrite (bombilla, LOW);
  time = millis();
}

void loop()
{
  ldr_value = analogRead(ldrPin);
  Serial.println(ldr_value);
  delay(200);
  
  if (ldr_value >= 300){
     if (millis() - time < RETARDO_APAGADO) 
        mantenerON = true;    // mientras 
     else  {
        mantenerON = false;
        time = millis();
     }
 
     if (mantenerON != ultimoEstado) {
        if (mantenerON ) 
           prender();
        else
           apagar();
      }
      ultimoEstado = mantenerON ;
  }
  else 
      apagar();
}

void prender() {
  digitalWrite(bombilla, HIGH);
}

void apagar() {
  digitalWrite(bombilla, LOW);
}

Espero funcione… esta hecho al vuelo.

surbyte gracias por la ayuda pero lo he puesto cada 10 segundos y a los 10 segundos se apaga pero se vuelve a encender al instante.

en principio tienes razón y claro que la tienes, pero dime como vuelves a disparar la lámpara?
Porque el sistema vuelve a encender porque la LDR tiene > 300 de luz, pero de noche, prueba a oscuras...
y veras que no vuelve a encender.

Supuestamente un valor > 300 según tus pruebas, es oscuridad. Asegúrate que este bien.

Luego si estamos a oscuras tu quieres que la luz este prendida el RETARDO_APAGADO que hemos fijado. Okay.

Veamos que hice mal!!

Ya veo que esa mal pero tendre un momento de incertidumbre cuando estemos en esa situación de oscuridad y claridad. De modo que hay que agregarle una histerisis y un reset para que se prepare para la siguiente oscuridad.
Lo corrijo y lo subo.

Exacto cuando mas aumenta el valor de la LDR, mas oscuridad ah. El valor 300 no es el definitivo, solo era para probar el programa.
Gracias por la ayuda, pensaba que sería mas sencillo realizar el programa.

Al principio pensé en poner un contador que aumente en 1 cada segundo. Cuando el contador tenga X valor que se encienda la salida y cuando tenga Y que se apague (No se ni si se puede hacer ya que soy nuevo en Arduino jaja) ¿Eso sería posible?
Saludos

Esta en 4 segundos 4 * 1000

#define RETARDO_APAGADO 4*1000 // 4 hs x 60 min x 60 seg x 1000 mseg = 14.400.000 mseg

const byte ldrPin    = A0;         
const byte bombilla  = 12;   
int ldr_value        = 0;   
int ldr_valueAnt      = 0;   
bool mantenerON = false;
bool mantenerAnt = false;
bool rearmarDisparo = true;     // Arranco en ON porque en cuanto tenga oscuridad prendo la Lampara.
unsigned long time;

void setup()
{
  pinMode (bombilla, OUTPUT);
  Serial.begin(9600);
  digitalWrite (bombilla, LOW);
  time = millis();
}

void loop()
{ char str[40];


  ldr_value = analogRead(ldrPin);
  if (ldr_value != ldr_valueAnt) {
      sprintf(str, "ADC = %d\n", ldr_value);
      Serial.println(str);
      ldr_valueAnt = ldr_value;
  }
  delay(200);
  
  if (ldr_value >= 500){
     if (!mantenerON && rearmarDisparo) 
         time = millis();
     
     if ((millis() - time > RETARDO_APAGADO)) {
        mantenerON = false;    // mientras 
        rearmarDisparo = false;
     } 
     else {
        mantenerON = true;
     }
    if (mantenerON) {
        sprintf(str, "T mseg =%ld\n", 4000 - millis() + time);
        Serial.println(str);     
    }
    if (mantenerON != mantenerAnt) {   
       if (mantenerON ) {
          prender();         
       }else
          apagar();
       mantenerAnt = mantenerON;
    }
  }
 
  if (ldr_value < 400) { // Volvió la claridad y entonces libero la posibilidad de que pueda volver a dispararse la bombilla
     rearmarDisparo = true; 
  }
}

void prender() {
  digitalWrite(bombilla, HIGH);
}

void apagar() {
  digitalWrite(bombilla, LOW);
}