Go Down

Topic: Slow Response from PIR Sensor (Read 2374 times) previous topic - next topic


Hi everyone,

I'm very new to coding and Arduino so I'm not positive about how I've modified the following sketch.  In essence, what i'm trying to create is a silent motion detection alarm.  This code and the general setup is borrowed from http://makeprojects.com/Project/PIR-Sensor-ArduinoAlarm/72/1#.USFWG6WsiSo.  Instead of the piezo buzzer I'm using a small vibration motor like the one shown here http://www.radioshack.com/product/index.jsp?productId=2914700.  The idea is to detect motion, turn on the LED, and make the vibration motor pulse very quickly.  When motion is no longer detected everything stops in 3 seconds.

For the most part, everything is working.  My problem is that it takes the LED and PIR about 1 full second to start working once motion has been detected.  My question is whether it's possible to correct that?  The code I've used / written is as follows.

Code: [Select]

// Uses a PIR sensor to detect movement, sets off vibration motor.
// more info here: makeprojects.com/Project/PIR-Sensor-ArduinoAlarm/72/1
// email me, John Park, at jp@jpixl.net

// based upon:
// PIR sensor tester by Limor Fried of Adafruit
// tone code by michael@thegrebs.com

int ledPin = 13;                // choose the pin for the LED
int inputPin = 2;               // choose the input pin (for PIR sensor)
int pirState = LOW;             // we start, assuming no motion detected
int val = 0;                    // variable for reading the pin status
int pinVibmotor = 10;            //Set up a vibration motor on a PWM pin (digital 9, 10, or 11)
void setup() {
  pinMode(ledPin, OUTPUT);      // declare LED as output
  pinMode(pinVibmotor, OUTPUT); // declare vibration motor as output
  pinMode(inputPin, INPUT);     // declare sensor as input

void loop(){
  val = digitalRead(inputPin);  // read input value
  if (val == HIGH) {            // check if the input is HIGH
    digitalWrite(ledPin, HIGH); // turn LED ON
    digitalWrite(pinVibmotor, HIGH);     // turn vibration motor on
    delay(100);    // pause for .5 second
    digitalWrite(pinVibmotor, LOW);  // turn the vibration motor off
    delay(100);  // pause for .5 second
    /* the idea is to make the vibration motor pulse on and off very
    if (pirState == LOW) {
      // we have just turned on
      Serial.println("Motion detected!");
      // We only want to print on the output change, not state
      pirState = HIGH;
  else {
    digitalWrite(ledPin, LOW); // turn LED OFF
    digitalWrite(pinVibmotor, LOW);     // turn vibration motor off
    delay(3000);               // turn vibration motor off     
    if (pirState == HIGH){
      // we have just turned off
      Serial.println("Motion ended!");
      // We only want to print on the output change, not state
      pirState = LOW;     

Thanks for taking a look!


If you take out the delay(3000) in the case where no motion is detected, it would get round to checking for motion more quickly.

I assume this was intended to be how the vibration continues for three seconds after the motion stops.

The elegant way to handle this, which gives an approach to handling events independently and scales up to systems as complex as you want, would be to change the overall structure of your sketch so that it is non-blocking, and uses the approach demonstrated in the Blink without Delay example sketch to turn the motor and LED on and off as required.

In the specific case of this sketch, assuming you don't want to be able to add in any other behaviour, you could get the behaviour you want with a less drastic change.

In loop() read the motion sensor. If motion is detected, turn the LED on and pulse the motor for three seconds. Design the motor pulse sequence so that when you run the sequence repeatedly you get an even continuous sequence of pulses. If no motion is detected, turn the LED off. With this approach loop() would take three seconds to complete when motion was detected, and almost no time at all when there was no motion; it would pick up new motion very quickly.

Go Up