Programming of PIR (delay?)

I have a PIR connected to an Arduino Uno. The output is a buzzer. This is a very simple setup. But I am brand new to the code aspect of it so I need some help....

For the sake of avoiding false alarms, I do not want the PIR to trigger an alarm status (sound the buzzer) at the very second that motion is detected. Based on the application that I am setting this project up in, I only want the PIR to trigger the buzzer if the PIR detects motions for maybe 3 seconds or so.

I know that the "delay" command exists, but if I understand the idea behind that command correctly wouldn't the delay command only delay how long it takes for the buzzer to trigger? Meaning a 3 second delay would only delay the buzzer 3 seconds before sounding as opposed to delaying 3 seconds to see if the input trigger (PIR) is triggered for all 3 seconds of the delay?

Or, if I put a delay into the commands would the buzzer not trigger if the PIR returned back to a normal state in under however many seconds I have programmed?

Is there a way to do this?

And again, I am brand new to this so if this is possible, what would be the actual line(s) of code to make that happen.

My buzzer is on pin 12. My trigger wire for the PIR is on pin 2. I currently have the basic code in place for the buzzer sounding as soon as the PIR sees motion. I'm just looking for a way to tell the Arduino to not sound the buzzer until the PIR sees 3 seconds worth of motion.

There is a simple way to do this using millis() but you should show us your code first.

To post code and/or error messages:

  1. Use CTRL-T in the Arduino IDE to autoformat your complete code.
  2. Paste the complete autoformatted code between code tags (the </> button)
    so that we can easily see and deal with your code.
  3. Paste the complete error message between code tags (the </> button)
    so that we can easily see and deal with your messages.

Before posting again, you should read the three locked topics at the top of the Programming Questions forum, and any links to which these posts point.

If your project involves wiring, please provide a schematic and/or a wiring diagram and/or a photograph of the wiring.

Good Luck!

Sorry for not following rules. My current code is as follows.... And this code works fine as far as triggering the buzzer as soon as the PIR sees motion. I am needing to require the PIR to see roughly 3 consecutive seconds worth of motion in order to trigger the buzzer though.

const int buzzerPin= 12;
const int inputPin= 2'

void setup () {
pinMode (buzzerPin, OUTPUT);
pinMode(inputPin, INPUT);
}

void loop () {
int value= digitalRead(inputPin);
if (value == LOW)

{
digitalWrite(buzzerPin, HIGH);
}
}

I am very new to this so if you could please make any code that I have to add or change as dummy proof as possible for me I would very much appreciate it.

thanks!!

There is an example, BlinkWithoutDelay BWD, that comes with IDE.

Here is an example using this technique:

//Simple BWD BlinkWithoutDelay examples
 
//Timer variables used
unsigned long currentMillis;
unsigned long pin13Millis;
unsigned long pin12Millis;
unsigned long SwitchMillis;
 
//if these are not changed in the sketch, they can be const
unsigned long debounceMillis = 50UL;  //50ms
unsigned long ledOnTime      = 500UL; //500ms seconds
 
byte lastSwitchState = HIGH;
byte buttonState     = HIGH;
 
//enable/disable flags
boolean flag13 = true;
boolean flag12 = false;
 
const byte Switch = 2; //pushed = LOW
 
//**********************************************************************
 
void setup()
{
  Serial.begin(9600);
 
  digitalWrite(13,LOW);
  pinMode(13, OUTPUT);
  
  digitalWrite(12,LOW);
  pinMode(12, OUTPUT);
 
  pinMode(Switch, INPUT_PULLUP); //pushed = LOW
 
} //  >>>>>>>>>>>>>> E N D  O F  s e t u p ( ) <<<<<<<<<<<<<<<<<
 
void loop()
{
  //save the current time
  currentMillis = millis();
 
  //*************************************
  //Heartbeat LED
  //Toggle LED on and off. Helps show if there is blocking code
  if (flag13 == true && currentMillis - pin13Millis >= ledOnTime)
  {
    pin13Millis = millis();            //re-initialize Timer
    digitalWrite(13,!digitalRead(13)); //toggle LED condition
  }
 
  //*************************************
  if (flag12 == true && currentMillis - pin12Millis >= 5*1000UL)
  {
    //Turn off pin 12
    digitalWrite(12,LOW); //Turn off LED
    flag12 = false;       //disable timing
  }
 
  //*************************************
  //is it time to check the switches?
  if (currentMillis - SwitchMillis >= debounceMillis)
  {
    //code here runs every debounceMillis ms
    SwitchMillis = millis(); //re-initilize Timer
    //go and check the switches
    checkSwitches();   
  }
 
  //*********************************
  //put other non-blocking stuff here
  //*********************************
 
} //  >>>>>>>>>>>>>> E N D  O F  l o o p ( ) <<<<<<<<<<<<<<<<<
 
 
//======================================================================
//                      F U N C T I O N S
//======================================================================
 
 
//****************** c h e c k S w i t c h e s ( ) *********************
//switches are checked every debounceValue milli seconds
//no minimum switch press time is validated with this code (i.e. No glitch filter)
void checkSwitches() 
{
  //re-usable for all the switches 
  boolean thisState;   
 
  //check if this switch has changed state
  thisState = digitalRead(Switch);
  if (thisState != lastSwitchState)
  { 
    //update the switch state
    lastSwitchState = thisState; 
 
    //this switch position has changed so do some stuff
    //"LOW condition code"
    //has switch gone from HIGH to LOW?
    if(thisState == LOW)                         
    {
      //Do some LOW switch stuff here 
      flag12 = true;          //allow timing
      digitalWrite(12, HIGH); //turn on LED
      pin12Millis = millis(); //initialize Timer
    }
 
  } //END of Switch code
 
  //***************************************** 
  // similar code for other switches goes here
  //***************************************** 
 
} //END of checkSwitches()
 
//**********************************************************************
 
//======================================================================
//                      E N D  O F  C O D E
//======================================================================

.

I appreciate the response Larry, but the problem is I don't understand any of that. I'm not an electronic / circuitry guy by any stretch of the imagination and got thrown on this project by my boss. I only found the basic code that I posted via google searching arduino pir coding.

I unfortunately kind of need an exact dummy version of the lines of code that I have to add / change.

My apologies for being difficult on this.

Try adjusting the "sensitivity" pot on the PIR sensor fully anti-clockwise.
That seems to be a delay control, not a sensitivity pot as the label suggests.

Hard to fix this in software, because the PIR triggers for a minimum of a few seconds when the "time" pot is fully anti-clockwise. And the PIR might almost instantly re-trigger.

You could experiment with counting triggers in a short timespan.
One trigger, no alarm. Two or more, alarm.
Leo..

So there's not a simple way to do this using millis() like vaj4088 said?

Ugh.

Have you looked at the BWD example in the IDE.

.

I have, but I don't understand how to incorporate that into my situation. I'd be more than happy to try it but I'm far too unfamiliar with this stuff to know what I need to change or tweak in the example to make it fit my situation.

I hate saying this but I virtually need the code written for me to essentially just copy. I have no background in this type of stuff.

I'd be fine scrapping the original code that I posted if there was a better way to accomplish what I was looking to do. I just frankly don't even know where to start in writing it. I am a 100% rookie with no background in this.

All I can say is I currently have the buzzer on pin 12 and pir on pin 2

Is this for school?

.

Is this for school?

Let's take this one step at a time.

Is there anything in the following code segment you don't understand?

unsigned long startMillis;
boolean timingFlag = false;

const int buzzerPin = 12;
const int inputPin = 2;

void setup ()
{
  pinMode (buzzerPin, OUTPUT);
  pinMode(inputPin, INPUT_PULLUP);

} // END of setup()

void loop ()
{
  int value = digitalRead(inputPin);

  if (timingFlag == false && value == LOW)
  {
    timingFlag = true;
    startMillis = millis();
  }

//  More code to come here

} // END of loop()

No, not for school. this is a situation im dealing with at work. We are dealing with some theft issues from employees right now and because I used to work as a customer service rep for a security system company that somehow made the boss think I was the guy for the project lol.

And I understand the general idea of what the code you just wrote is saying. With no experience in this area though I could never write this on my own.

Explain these lines of code from my response #12 :

unsigned long startMillis;

boolean timingFlag = false;

if (timingFlag == false && value == LOW)

startMillis = millis();

.

That would mean to trigger the buzzer if the signal from PIR is low, which is the alarm state of the pir, and the timing flag occurs (which I'm assuming is that 3 seconds of motion detection I am looking for?)

Like I mentioned, I get the general gist of it. It's just figuring out what to write and where to write it.

I get the general gist of it.

No general gist allowed :wink:

Tell us what each line of code mentioned does.

.

Honestly, forget it. If I understood this stuff I wouldn't be asking the questions that I'm asking. It's pushing 11pm and I am not going to drag this on any longer. I appreciate the responses though. Thank you.

OK here is what I think you want.
If you don't understand what is happening ask.

unsigned long startMillis;
boolean timingFlag  = false;

const int buzzerPin = 12;
const int inputPin  = 2;

void setup () 
{
  pinMode (buzzerPin, OUTPUT);
  pinMode(inputPin, INPUT_PULLUP);
}

void loop () 
{
  int value = digitalRead(inputPin);

  if (timingFlag == false && value == LOW)
  {
    timingFlag = true;     //enable timing
    startMillis = millis();
  }

  //make sure there is still PIR detection
  if (timingFlag == true && millis() - startMillis < 3000UL && value == HIGH)
  {
    //the PIR timed out with in the three seconds so cancel timing
    timingFlag = false;    //disable timing
  }

  //when three seconds has gone by with consistant detection turn on buzzer
  if (timingFlag == true && millis() - startMillis >= 3000UL)
  {
    //There has now been three seconds of constant PIR detection
    timingFlag = false;    //disable timing
    digitalWrite(buzzerPin, HIGH);
  }
  
} // END of loop()
1 Like

Larry, I appreciate your help. I will try this tomorrow and let you know how it goes.

I do actually really appreciate you trying to help me understand it. That's very cool of you. And I will have some questions for you tomorrow evening after I try your suggestion.... I've been racking my brain on this all day today though and am ready to call it a night that's why I was kind of frustrated.

Very appreciated though. I'll give this a try tomorrow and once I see how it goes I'll let you know and I'll let you know how much of it makes sense, lol.

Has buzzer duration added:

unsigned long startMillis;
unsigned long buzzerMillis;

unsigned long pirDuration    =  3*1000UL; //3 seconds
unsigned long buzzerDuration = 10*1000UL; //10 seconds

boolean timingFlag  = false; //false = not timing
boolean buzzerFlag  = false; //false = buzzer disabled

const int buzzerPin = 12;    //HIGH turns on buzzer
const int inputPin  =  2;    //LOW on PIR detection

void setup ()
{
  pinMode(buzzerPin, OUTPUT);
  pinMode(inputPin, INPUT_PULLUP);
}

void loop ()
{
  int value = digitalRead(inputPin);

  //if we are not 'timing' and there is a PIR detection
  if (timingFlag == false && value == LOW)
  {
    timingFlag = true;     //enable timing
    startMillis = millis();
  }

  //make sure there is still PIR detection
  if (timingFlag == true && millis() - startMillis < pirDuration && value == HIGH)
  {
    //the PIR timed out within the 3 seconds so cancel timing
    timingFlag = false;    //disable timing
  }

  //when 3 seconds has gone by with consistant detection, turn on buzzer
  if (timingFlag == true && millis() - startMillis >= pirDuration)
  {
    //there has been three seconds of constant PIR detection
    timingFlag = false;    //disable timing
    buzzerFlag = true;     //enable the buzzer
    buzzerMillis = millis();
    digitalWrite(buzzerPin, HIGH); //turn buzzer ON
  }

  //allows the buzzer to sound for 10 seconds (set to what is needed)
  if (buzzerFlag == true && millis() - buzzerMillis >= buzzerDuration)
  {
    digitalWrite(buzzerPin, LOW); //turn buzzer OFF
    buzzerFlag = false;           //disable the buzzer
  }

} // END of loop()
2 Likes