Stop and restart void loop depending on ldr input

So I have created a circuit so that when an ldr is in the sunlight, LED’s light up and the motor is operating for X amount of seconds. After this, the motor then switches off. However, the loop will just keep playing. I want to stop this loop until the ldr is in the shade and another loop will be executed and vice versa.

I currently do not know how to do this ( apologies I’m releatively new to programming). I’ve added while(1); but this means that the loop will be executed once and then stop. Even if I change the input of the ldr, the whole program stops.

Here is my program:

int input1=3;
int input2=4;
const int led1=5;
const int led2=7;
const int ldr1=0;

void setup()
{
pinMode(input1, OUTPUT);
pinMode(input2, OUTPUT);
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(ldr1, INPUT);
}

void loop()
{
int ldrstatus=analogRead(ldr1);
if (ldrstatus<=300)
{
digitalWrite(led1, LOW);
digitalWrite(led2, LOW);
digitalWrite(input1, LOW);
digitalWrite(input2, HIGH);
delay(500);
digitalWrite(input2,LOW);
delay(500);
while(1);
}

else if (ldrstatus>300)
{
digitalWrite(led1, HIGH);
digitalWrite(led2, HIGH);
digitalWrite(input1, HIGH);
digitalWrite(input2, LOW);
delay(500);
digitalWrite(input1, LOW);
delay(500);
while(1);

}
}

Please add code tags when posting code.

You can of course stop execution (a while(1); will do) but you can't resume. You can put the device to sleep, but it doesn't know when the light levels drop.
So why do you even want to stop it from running at all? Why not continue to check light levels until it's low again, and then do whatever you have to do at low light?

Hi WVmarle,

Ok that sounds like a much better idea. How would i get Arduino to keep checking the LDR light levels so that when the light level is a certain level the loop will play again?

Would this be another if statement or would i need to use a boolean expression and set a variable to true??

When light above certain level, run a function,set a flag it’s done. Then when light drops below another level reset that flag, so when it goes above the level you can run it again. It’s a very simple state machine.

So:

bool doneHighLightStuff = false;

loop() {
  LDR = analogRead(A0);
  if (LDR > 300 && doneHighLightStuff == false) {
    doHighLightStuff();
    doneHighLightStuff = true;
  }
  if (LDR < 200) {
    doneHighLightStuff = false;
  }
}

So now doHighLightStuff() runs once the moment the level goes above 300, and will not run again before level dropped below 250, and then rises above 300 again.

Set these values and a sensible hysteresis based on trial and error. Hysteresis is important to prevent it from running time and again when your light level is around 300.

Hi,

I have tried this code however it doesn’t currently work.

here is how I’ve incorporated your code;

bool doneHighLightStuff=false;
int input1=3;
int input2=4;

const int led1pin=7;
const int led2pin=5;
const int led3pin=2;
const int ldr1pin=0;

void setup()
{
Serial.begin(9600);
pinMode(led1pin, OUTPUT);
pinMode(led2pin, OUTPUT);
pinMode(led3pin, OUTPUT);
pinMode(ldr1pin, INPUT);
pinMode(input1, OUTPUT);
pinMode(input2, OUTPUT);

}

void loop()
{
int ldrstatus=analogRead(ldr1pin);
{
if (ldrstatus>=300 && (doneHighLightStuff=false))
{
digitalWrite(led1pin, HIGH);
digitalWrite(led2pin, HIGH);
digitalWrite(led3pin, HIGH);
digitalWrite(input1, HIGH);
digitalWrite(input2, LOW);
delay(1000);
digitalWrite(input1, LOW);
delay(5000);

doneHighLightStuff=true;
}

if (ldrstatus<200)
{
digitalWrite(led1pin, LOW);
digitalWrite(led2pin, LOW);
digitalWrite(led3pin, LOW);
digitalWrite(input1, LOW);
digitalWrite(input2, HIGH);
delay(1000);
digitalWrite(input2, LOW);
delay(5000);
doneHighLightStuff=false;
}
}
}

At the moment, it doesn’t seem to understand what the Boolean expression is and will not execute the if statement when the ldr is above 300. It will however, execute the if statement when the ldr is lower than 200 however after the delay, this loop will just repeat.

What have I done wrong? Can someone correct me please?

Kind Regards

Zozo26:
if (ldrstatus>=300 && (doneHighLightStuff=false))

= and == are not the same.

Firstly, i would like to thank you.

When i changed the if statement to;

if(ldrstatus>300 && (doneHighLightStuff==false))

The program works. So when the ldr is in the sunlight, the loop will play once. The program will only resume when the ldr is in the shade, which is what i wanted. However, the loop (when the ldr is in the shade) keeps repeating. How do i get this loop to play once, stop and resume when the ldr is in the sunlight.

Kind Regards

Just add the same check for the low-light situation:

  if (ldrstatus<200 && doneHighLightStuff == true) {
    doneHighLightStuff = false;

So now this will also only run after the high light has been done already.

Just make sure that you initialise this flag correctly, whatever you want: set it to false if you want it to wait for high light to start doing anything, or to true for it to wait for low light first. Then perform the other state once in setup().