LDR based Day / Night light relay

I am trying to operate relay based on LDR reading and potentiometer use to adjust the Day and Night thresholds. I try to cover following two logics:
1 ) On and off at two different set point. Like Relay ON at 70% and OFF at 20% darkness.
2) Hold for few second and than react. Like when detect darkness hold 3 sec if still dark than relay ON / OFF.

Below is my so-called sketch.

Its working as expected. only there is confusion in day and night logic its work opposite.
Alternate solution and modification also welcome.

const int Relay_Pin = 2;  // the number of the LED pin
int inputPin_Day = A0;
const int numReadings = 50;
unsigned long TimeOfLastPower_Day = 0;  // Globals default to zero but making it explicit is not harmful
unsigned long TimeOfLastPower_Night = 0;  // Globals default to zero but making it explicit is not harmful
int LL = A1;
int HH = A2;

int LL_Value = 0;  // variable to store the value coming from the sensor
int HH_Value = 0;  // variable to store the value coming from the sensor

bool Day;
bool Night;

int readings_DAY[numReadings];  // the readings from the analog input
int readIndex_Day = 0;          // the index of the current reading
int total = 0;                  // the running total
int average = 0;                // the average
int Re_Scale = 0;

int PotVal_Day = 0;
int PotVal_Night = 0;

boolean logic = 0;

void setup() {
  Serial.begin(9600);
  pinMode(Relay_Pin, OUTPUT);
  for (int thisReading = 0; thisReading < numReadings; thisReading++) {
    readings_DAY[thisReading] = 0;
  }
}

void loop() {

  LL_Value = analogRead(LL);
  int PotVal_Day = 0;
  PotVal_Day = map(LL_Value, 0, 1023, 0, 100);
  HH_Value = analogRead(HH);
  PotVal_Night = map(HH_Value, 0, 1023, 0, 100);

  total = total - readings_DAY[readIndex_Day];
  readings_DAY[readIndex_Day] = analogRead(inputPin_Day);
  total = total + readings_DAY[readIndex_Day];
  readIndex_Day = readIndex_Day + 1;
  if (readIndex_Day >= numReadings) {
    readIndex_Day = 0;
  }

  average = total / numReadings;
  Re_Scale = map(average, 0, 1023, 0, 100);

  ////////////////////------------------------/////////////////

  if (Re_Scale >= PotVal_Day) {
    TimeOfLastPower_Day = millis();
  }
  // Has it been more than 30 seconds since we last saw power?
  if (millis() - TimeOfLastPower_Day > 3000UL) {
    Night = true;
    // Turn on the relay
  } else {
    Night = false;
  }


  if (Re_Scale <= PotVal_Night) {
    TimeOfLastPower_Night = millis();
  }
  if (millis() - TimeOfLastPower_Night > 3000UL) {
    Day = true;
  } else {
    Day = false;
  }

  Serial.print("D : ");
  Serial.print(PotVal_Day);
  Serial.print("          ");
  Serial.print("N : ");
  Serial.print(PotVal_Night);
  Serial.print("          ");
  Serial.print("  LDR  : ");
  Serial.print(Re_Scale);
  Serial.print("          ");


  if (Night || Day) {

    if (Re_Scale >= PotVal_Day && logic == 0) {  // Night detect
      LightON();
      logic = 1;
    } else if (Re_Scale >= PotVal_Day && logic == 1) {
      LightON();

    } else if (Re_Scale <= PotVal_Night) {  // Day Detect
      LightOFF();
      logic = 0;
    }
  }
  Serial.println("    ");
}

///////////////////////--------------------------------/////////////////////////////////////

void LightON() {
  digitalWrite(Relay_Pin, HIGH);  // Many relay modules are Active Low
  Serial.print(" : ");
  Serial.print("Night");
}

void LightOFF() {
  digitalWrite(Relay_Pin, LOW);  // Many relay modules are Active Low
  Serial.print(" : ");
  Serial.print("Day");
}

Serial output as :

N : 48          D : 40            LDR  : 57           : Night    
N : 48          D : 40            LDR  : 55           : Night    
N : 48          D : 40            LDR  : 53           : Night    
N : 48          D : 40            LDR  : 50           : Night    
N : 48          D : 40            LDR  : 48           : Night    
N : 48          D : 40            LDR  : 46              
N : 48          D : 40            LDR  : 43              
N : 48          D : 40            LDR  : 41              
N : 48          D : 40            LDR  : 39              
N : 48          D : 40            LDR  : 38              
N : 48          D : 40            LDR  : 37              
N : 48          D : 40            LDR  : 37              
N : 48          D : 40            LDR  : 37              
N : 48          D : 40            LDR  : 37              // 3 Sec serial cut
N : 48          D : 40            LDR  : 37              
N : 48          D : 40            LDR  : 37              
N : 48          D : 40            LDR  : 37              
N : 48          D : 40            LDR  : 37              
N : 48          D : 40            LDR  : 37              
N : 48          D : 40            LDR  : 37              
N : 48          D : 40            LDR  : 37              
N : 48          D : 40            LDR  : 37                         
N : 48          D : 40            LDR  : 37              
N : 48          D : 40            LDR  : 37           : Day    
N : 48          D : 40            LDR  : 37           : Day    
N : 48          D : 40            LDR  : 37           : Day    
N : 48          D : 40            LDR  : 37           : Day    
N : 48          D : 40            LDR  : 37           : Day    
N : 48          D : 40            LDR  : 37           : Day   
void LightON() {
  digitalWrite(Relay_Pin, HIGH);  // Many relay modules are Active Low
  Serial.print(" : ");
  Serial.print("Night");
}

If this function is intended to turn the relay on then take note of the comment

1 Like

I have drought in below part

    if (Re_Scale >= PotVal_Day && logic == 0) {  // Night detect
      LightON();
      logic = 1;
    } else if (Re_Scale >= PotVal_Day && logic == 1) {
      LightON();

    } else if (Re_Scale <= PotVal_Night) {  // Day Detect
      LightOFF();
      logic = 0;
    }

Does the relay turn on when you set its control pin HIGH or does it turn on when you set it LOW ?

Note that it will click either way so don't rely on it just making a noise, test what happens with the relay contacts

At this stage I am operating LED only. When I connect the relay I will change this.

Pending the check of the relay/LED as suggested, one other possibility is the LDR. Assuming you have it as one half of a voltage divider, swap its position with the pot to see if that corrects the operation.

Are you sure that expression evaluates the way you want?

Unless you're 101% sure you fully understand all the precedence & association rules, some brackets would be wise; eg,

   if( (Re_Scale >= PotVal_Day) && (logic == 0) ) {  // Night detect

BTW "logic" doesn't seem a very descriptive name for that variable - what does it indicate? :thinking:

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.