Controlling two leds with two LDRs without delay

So I wanted to design a program for arduino in which I had two Light dependent resistors that each controlled their own LEDs. In this program the LED is usually on . Whenever light is shined on the LDR , the arduino waits 8 seconds then switches off the LED and when there is no light on the LDR it waits 4 seconds and switches on the LED. Each LDR controls its own LED and doesn't not influence the other LED. I wrote my program without delay because I wanted to multitask.

int LDR=0;
int LDR2=0;
int LED_PIN = 12;
int LED_PIN2 = 10;
int LED_ON = 8000;      
int LED_OFF = 4000;
int LED_ON2 = 8000;      
int LED_OFF2 = 4000;

unsigned long ms=0;        //time from millis()
unsigned long msLast=0;    //last time the LED changed state

unsigned long ms2=0;        //time from millis()
unsigned long msLast2=0;    //last time the LED changed state

void setup(void)
{
   
   pinMode(LED_PIN, OUTPUT);
   pinMode(LED_PIN2, OUTPUT);
  
}

void loop(void)
{
    ms = millis();
    ms2= millis();
    LDR=analogRead(A4);
    LDR2=analogRead(A1);

    if (LDR>500) blinkLED();
    else if (LDR<500) blinkLED2();
     
    if (LDR2>500)blinkLEDa();         
    else if (LDR2<500) blinkLEDa2();
     
   
     
    

}

void blinkLED(void)
{
    if (ms - msLast > LED_ON) {        
        digitalWrite(LED_PIN, LOW);
        msLast = ms;
    }
}

void blinkLED2(void)
{
     if (ms - msLast > LED_OFF) {        
        digitalWrite(LED_PIN, HIGH);
        msLast = ms;
    }

    
}

void blinkLEDa(void)
{
    if (ms2 - msLast2 > LED_ON2) {
        digitalWrite(LED_PIN2, LOW);
        msLast2 = ms2;
    }
}

void blinkLEDa2(void)
{
     if (ms2 - msLast2 > LED_OFF2) {         
        digitalWrite(LED_PIN2, HIGH);
        msLast2 = ms2;
        
    }

    
}

Now my problem is both LDRs affect the other LEDs. Say for example I shine light on one LDR but I don't do the full 8 seconds, instead I only do 4 seconds and then I move towards the second LDR and shine a light on it. It will switch its own LED OFF ONLY AFTER 4 SECONDS instead of the full 8 seconds. This is because its adding its own timer to that of the other LDR. How can I prevent this. In short how can I make sure that the timer for one LED-LDR system doesn't affect the other.

That's because you use the same timing variable for both to hold the last time...

Also, one you start numbering variables it's time for an array. Or at least number ALL :wink: But an array would reduce the whole program to probably <30 lines.

Thank you for answering septillion.

Which variable are you talking about ? for the first LDR-LED system. I used ms for currenttime and mslast for Previoustime while the second LED-LDR system I used ms2 and mslast2.

Also I will look into using arrays.

ibrahim991:
Whenever light is shined on the LDR , the arduino waits 8 seconds then switches off the LED

Does that mean that you want the light to shine continuously on the LDR for 8 seconds before turning the LED off? If so that is not what your program does.

To check if something is on continuously for a period you need code like this pseudo code

if the light is off
   lastLightOffMIllis = millis(); // reset the clock
}

if (millis() - lastLightOfMillis >= 8000) {
    //light has been on for 8 secs
    // do stuff
}

...R

Thank you Robin2 actually I wrote a second program for that

if((LDR > 500) && (currentMillis - previousMillis1 > OnTime1))
  {
    ledState1 = LOW;  // Turn it off
    previousMillis1 = currentMillis;  // Remember the time
    digitalWrite(ledPin1, ledState1);  // Update the actual LED
  }
   
  if ((LDR < 500) && (currentMillis - previousMillis1 > OffTime1))
  {
    ledState1 = HIGH;  // turn it on
    previousMillis1 = currentMillis;   // Remember the time
    digitalWrite(ledPin1, ledState1);    // Update the actual LED
  }

But I still faced the same problem of LDRs affecting the other

Ow man, because of the counting I got lost...

But better define when to turn on and when to turn off.

Is it like this?

  • Turn ON if light is applied
  • Turn OFF if light is on for 8 seconds
  • Turn OFF when light is removed?

@septillion. Ok

State 1 LED is on
Light is shone onto the LDR for 8 seconds
State 2 LED is switched off
Light is removed, LDR is dark for 4 seconds
back to State 1 LED is on

now I want to do this but for 2 systems. That means one we have LDR1 that controls LED1 and LDR2 that controls LED2. But am having issues since LDR1 sometimes affects LED2 or LDR2 sometimes affects LED1. That is when I shine light on LDR1 for 4 seconds instead of the full 8 seconds and then I move to light LDR2 for 4 seconds instead of the full 8. The arduino takes the previous time of Ldr1 (4 seconds) and adds it to the latter time of LDR2 which then makes the program switch on LED2.

:confused: am also getting confused but I hope this explanation works

Also the light on the LDR in this case comes from a flashlight and not the LED

Okay, so:

Turn led OFF when light is applied for >8 sec
I assume reset time when light is removed?
Turn led ON when light is removed for 4 seconds.

I was about to make that... But in the process noticed you use the same input for LDR and LDR2.... Again, learn to count. And second, no wonder the do the same if they look at the same pin.

The input pin for LDR is A4 and LDR2 is A1.

ibrahim991:
The input pin for LDR is A4 and LDR2 is A1.

You code shows different :wink:

Think the follow does what you want and is scalable to "infinite" number of couples.

const byte LedPins[] = {12, 10};
const byte NrLeds = sizeof(LedPins);
const byte LdrPins[NrLeds] = {A4, A1};

//easy to make an array of this as well but as they are the same I didn't
const unsigned int TurnOffTime = 8000;
const unsigned int TurnOnTime = 4000;
const int LightThreshold = 500;

unsigned long millisLeds[NrLeds];
bool lastLightStates[NrLeds];

void setup(){
  for(byte i = 0; i < NrLeds; i++){
    pinMode(LedPins[i], OUTPUT);
    digitalWrite(LedPins[i], HIGH);
  }
}

void loop(){
  updateLdrLed();
}

void updateLdrLed(){
  for(byte i = 0; i < NrLeds; i++){
    const bool CurrentLightState = (analogRead(LdrPins[i]) > LightThreshold);
    if(lastLightStates[i] != CurrentLightState){
      millisLeds[i] = millis();
    }
    
    
    if( digitalRead(LedPins[i]) && 
        CurrentLightState && 
        (millis() - millisLeds[i] >= TurnOffTime))
    {
      digitalWrite(LedPins[i], LOW);
    }
    if( !digitalRead(LedPins[i]) && 
        !CurrentLightState && 
        (millis() - millisLeds[i] >= TurnOnTime))
    {
      digitalWrite(LedPins[i], HIGH);
    }
    
    lastlastLightStates[i] = CurrentLightState;
  }
}

But yeah, untested. But it shows the idea :slight_smile: