Escape Room reverse motion activated light sensor

Hey Guys & Gals thanks for taking the time to read this.
I’m a noob but I’m not looking for anyone to write code just point me in the right direction of what command I should be researching.
I’m building a motion activated light sensor for my Escape Room.

For testing code I’m just using the arduino uno 1 led & a PIR sensor

Here’s what I’ve been trying to do.
Start with led off.
Watch for motion for 20 seconds. (not wait 20 seconds & read the PIR)
Once 20 seconds pass without motion detected turn led back on.
Turn the led off immediately if motion is detected.

I’m struggling with coding the 20 second wait period.
I took my delay out of the code because all they do is wait to read which isn’t what I want.
I know there’s a simple code out there to fix this I just don’t know where to look. Am I correct that a Delay isn’t what I need?

I’m thinking I need to have the PIR read once a second, keeping a running count of low reads on the PIR and once that count reaches a number greater than 20 turn on the led. Any help at all is greatly appreciated.

int pir = 2;
int light = 13;

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

void loop()
{long sensor = digitalRead(pir);
  if(sensor == HIGH){
     digitalWrite (light, LOW);}
   else
   {digitalWrite (light, HIGH);}}

Look at the function millis(). It gives you a count of the number of milliseconds that have passed since last the board was reset. Read your sensor. You need a variable to hold the time of the last motion detected. Every time motion is detected, record millis there. On each pass through the loop, simply compare the current time returned by millis to that time to see if 20 seconds have passed and if so turn your led back on.

Put every { on a new line. Put every } on a new line. Use Tools + Auto Format. Useplentyofwhitespace.

Your code looks like crap.

** EDIT - Jumped the Gun on this post, I think I know what I did wrong though, I don't need hints**

Thanks Delta_G! It's working! All I needed to know was millis.

int pir = 2;
int light = 13;
int timePir;
int time;

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

void loop()
{
  long sensor = digitalRead(pir);
  time = millis();
  if(sensor == HIGH){
    timePir = millis();   
    digitalWrite (light, LOW);
  }
  else if (timePir > time - 20000)
  {
    digitalWrite (light, HIGH);
  }
}

As PaulS noticed I have almost no experience. Until asking this question everything I had learned was on my own. Sorry the code is so ugly, I was unaware and thought it looked more organized without all the white space. I'll make sure to use the auto format before posting again.

I changed my else if and added comments, but somethings still not quite right.

Is it possible that when I’m tripping the PIR sensor it’s not at that place in the loop and not recording the event to the timePir variable? It almost seems like a short motion trigger isn’t getting the 20 second delay while a bunch of motion does get the delay.

The 20 second delay works about 50% of the time the PIR is tripped but the other 50% of the time the light turns back on immediately. I’m ready for another hint.

int pir = 2;
int light = 13;
int timePir;
int time;

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

void loop()
{
  long sensor = digitalRead(pir);  //read the PIR
  time = millis();  //set variable time to millis time
  if(sensor == HIGH){  //if the PIR is detecting motion
    timePir = millis();   //set variable time PIR to millis time
    digitalWrite (light, LOW);  //turn the light off
  }
  else if (time > timePir + 20000) // if variable time is greater than variable timePir + 20 seconds
  {
    digitalWrite (light, HIGH);  //turn the light back on
  }
}
int timePir;

millis() returns an unsigned long. Your variables to hold time should also be unsigned long. With an int they work for about 30 seconds and then suddenly time is negative as the compiler tried to stuff an unsigned long value into the smaller signed int.

Delta_G you are my favorite. If you're ever in the St. Louis area and want to visit my escape room, tickets will be free to you and your friends.

kwest116: Delta_G you are my favorite. If you're ever in the St. Louis area and want to visit my escape room, tickets will be free to you and your friends.

I'm in St Louis every few weeks on business. If I have some free time I may hold you to that.

Also, why use a long to store a digitalRead() ? A byte will suffice, or avoid to store it at all :

void loop()
{
  
  time = millis();  //set variable time to millis time
  if(digitalRead(pir) == HIGH){  //if the PIR is detecting motion
    timePir = millis();   //set variable time PIR to millis time
    digitalWrite (light, LOW);  //turn the light off
  }
  else if (time > timePir + 20000) // if variable time is greater than variable timePir + 20 seconds
  {
    digitalWrite (light, HIGH);  //turn the light back on
  }
}

In a small sketch like this one doesn’t not make big difference of course, but avoid to waste the limited (especially for RAM) resource is a good coding pratice.

Cheers, Ale.