Need help with a "simple" dark sensor sketch with 'Delay()'.

Hi! I’m having some issues with the sketch I’m working on and have resorted to joining this forum in hopes of gaining some helpful tips and possibly, in the future, giving tips back to the community. Just to get it out in the open, I’m sort of a beginner with Arduino sketching/programming. I think I’ve done just enough projects by reading how-to guides and books to properly get myself in DIY trouble. Actually, The sketch I’m working on isn’t that bad from my standpoint–I just need some pointers on how to make it do what I want. So here’s the scoop:

Parts:
I’m doing the project on a UNO board. The three main components being used are 1)1 LED 2)1 LDR/Photocell, and 3) 1 Piezo buzzer. I won’t bother posting what pins these go to, as the sketch below will detail that information. And of course, everything has the proper resistors and is hooked up properly, how I like, so no issues there!

How it should work:
The project I’m working on is a simple “fridge alarm” or dark-sensor with a delay. I’ve seen these very commonly thru’ various sources on the internet and decided I should make my own design without any help from the internet. Afterall, how hard could it be, right? (So here I am! Lol :P). How I’ve been trying to get it to work is, first, when it sees a light source, the LED should flash once, indicating that it’s working, then after 10 seconds, IF the LDR senses dark again, the LED and buzzer will be set to LOW and the loop should reset and wait until the next time it senses light. If, on the other hand it does sense light after the delay of 10 seconds, both the LED and buzzer should flash/buzz in unison on a delay of 100 until it senses darkness again–when it should be reset to start the loop from the top.

What it’s doing:
Ok, so the PROBLEM is that every time I upload the sketch, if I wait 10 seconds in the light, it works like a charm and beeps and flashes exactly how I want. However, when I cover the LDR during the 10 sec delay, it beeps and flashes once (Even with my finger over it) then it stops. When I take my finger off, or expose it to light, it continues exactly where it left off and beeps immediately until I cover the LDR again. So what I’m looking for is help to identify the problem with the delay primarily and how to reset the loop. I appreciate pointers, but I’m not really looking for an overhaul in my coding unless it’s absolutely necessary. Thank’s a bunch!

int ledPin      = 13; //Pin for monitoring LED
int buzzPin     = 11; //Pin for Piezo buzzer
int light        = 0; //Var for LDR
int x            = 0; //Placeholder variable
int alarmDelay   = 0; //Optional time
int delayTime = 10000; //How long it takes before buzzer sounds
//Below variables can be adjusted per LDR
const int ambient   = 700; //LDR Ambient Level
const int threshold = 800; //LDR Threshold level


void setup()
{
  pinMode(ledPin, OUTPUT);
  pinMode(buzzPin, OUTPUT);
  pinMode(light, INPUT);
}

void loop()
{
  light = analogRead(A0);
   
  if (light < ambient){
   digitalWrite(ledPin, HIGH);
   delay(100);
   digitalWrite(ledPin, LOW);
   delay(delayTime);
   delayTime = 0;
}
  if (light < ambient && delayTime == 0){ 
   x = 0;

   digitalWrite(ledPin, HIGH);
   delay(100); //Controls speed between LED flashes and buzzes  
     
     if(light > ambient || light >= threshold){
        digitalWrite(ledPin, LOW);
        digitalWrite(buzzPin, LOW); 
     }
     
     if (x == 0){  
        digitalWrite(buzzPin, HIGH);
        digitalWrite(ledPin, HIGH);
        delay(100);
        digitalWrite(buzzPin, LOW);
        digitalWrite(ledPin, LOW);
        delay(100);
     }  
   
     if (light >= threshold && light > ambient){
        x = 1;
        digitalWrite(ledPin, LOW);
        digitalWrite(buzzPin, LOW); 
     }
  }
}

After a cursory look, I see two things that look like they'll cause trouble:

  • delayTime gets set to zero when it sees light, and never changes after that. I think you wanted to reset it to its original value, sooner or later.
  • You don't read the LDR after the initial 10-second delay. That means that the program will think the light is still bright after the delay is over, and won't notice that you've darkened it until loop() executes again.

Try strategically adding some Serial.print()'s to see the values of your variables. That'll give you a clue as to what's not doing what you expect.

Open your IDE and select File->Examples->02.Digital->BlinkWithoutDelay

Load it. Run it. Mess with it. Learn it.

Once you understand that one you can have your delay and watch the LDR for the light level to change *** at the same time ***. It should change your whole view of how to do the project.

It's not perfect btw, but it works. ALL the variables dealing with time there should be type unsigned long but it will take over 23 days for the glitch in that version to show up.

Thanks for the help. Now that I sit back and look at it, tmd3, it makes better sense to me. :)

GoForSmoke, I have checked out that example file earlier and didn't know exactly how to implement it. I just tried it with my code and I already came up with some promising results. Will play with that also... Thanks! :)

You can make pieces of code that pretty much act independently yet affect each other through shared variables. Read a sensor to make a number that another task/process uses to control a window shade for example. You don't need a bunch of interwoven code that way. You can debug by printing out the control variables at different stages and change those variable assignments instead of weaving logic statements. I know because I did enough of both over many years!

When you're ready, start reading about finite state engines. The basic idea is simple but then so is the alphabet, you can write simple notes to complex works with either but if you keep it down to what's needed and practical you shouldn't make any monsters.