PIR sensor

Ligação de um sensor de movimento ao Arduino.

 

Características do Sensor "PIR Motion sensor module":

Input Voltage: DC 4.5-20V

Static current: 50uA

Output signal: 0,3V or 5V (Output high when motion detected)

Sentry Angle: 110 degree

Sentry Distance: max 7 m

Shunt for setting overide trigger: H - Yes, L - No

Simples esquema para testar se o sensor está a funcionar correctamente:

Ao detectar movimento acende o LED

No teste realizado com o Arduino, foi adicionado um buzzer:

Código adaptado:

/* 

 * //////////////////////////////////////////////////

 * //making sense of the Parallax PIR sensor's output

 * //////////////////////////////////////////////////

 *

 * Switches a LED according to the state of the sensors output pin.

 * Determines the beginning and end of continuous motion sequences.

 *

 * @author: Kristian Gohlke / krigoo (_) gmail (_) com / http://krx.at

 * @date:   3. September 2006 

 *

 * kr1 (cleft) 2006 

 * released under a creative commons "Attribution-NonCommercial-ShareAlike 2.0" license

 * http://creativecommons.org/licenses/by-nc-sa/2.0/de/

 *

 *

 * The Parallax PIR Sensor is an easy to use digital infrared motion sensor module. 

 * (http://www.parallax.com/detail.asp?product_id=555-28027)

 *

 * The sensor's output pin goes to HIGH if motion is present.

 * However, even if motion is present it goes to LOW from time to time, 

 * which might give the impression no motion is present. 

 * This program deals with this issue by ignoring LOW-phases shorter than a given time, 

 * assuming continuous motion is present during these phases.

 *  

 */

/////////////////////////////

//VARS

//the time we give the sensor to calibrate (10-60 secs according to the datasheet)

int calibrationTime = 30;        

//the time when the sensor outputs a low impulse

long unsigned int lowIn;         

//the amount of milliseconds the sensor has to be low 

//before we assume all motion has stopped

long unsigned int pause = 5000;  

boolean lockLow = true;

boolean takeLowTime;  

int pirPin = 3;    //the digital pin connected to the PIR sensor's output

int ledPin = 13;

/////////////////////////////

//SETUP

void setup(){

  Serial.begin(9600);

  pinMode(pirPin, INPUT);

  pinMode(ledPin, OUTPUT);

  digitalWrite(pirPin, LOW);

  

pinMode(4, OUTPUT); // set a pin for BUZZER output  

  //give the sensor some time to calibrate

  Serial.print("calibrating sensor ");

    for(int i = 0; i < calibrationTime; i++){

      Serial.print(".");

      delay(1000);

      }

    Serial.println(" done");

    Serial.println("SENSOR ACTIVE");

buzz(4, 2400, 500); // buzz the buzzer 

delay(1000); // wait a bit 

  }

////////////////////////////

//LOOP

void loop(){

     if(digitalRead(pirPin) == HIGH){

       buzz(4, 2400, 500); // buzz the buzzer 

       delay(50); // wait a bit 

         

       digitalWrite(ledPin, HIGH);   //the led visualizes the sensors output pin state

       if(lockLow){  

         //makes sure we wait for a transition to LOW before any further output is made:

         lockLow = false;            

         Serial.println("---");

         Serial.print("motion detected at ");

         Serial.print(millis()/1000);

         Serial.println(" sec"); 

         buzz(4, 1000, 400); // buzz the buzzer 

         delay(50); // wait a bit

                 }         

         takeLowTime = true;

       }

     if(digitalRead(pirPin) == LOW){       

       digitalWrite(ledPin, LOW);  //the led visualizes the sensors output pin state

       if(takeLowTime){

        lowIn = millis();          //save the time of the transition from high to LOW

        takeLowTime = false;       //make sure this is only done at the start of a LOW phase

        }

       //if the sensor is low for more than the given pause, 

       //we assume that no more motion is going to happen

       if(!lockLow && millis() - lowIn > pause){  

           //makes sure this block of code is only executed again after 

           //a new motion sequence has been detected

           lockLow = true;                        

           Serial.print("motion ended at ");      //output

           Serial.print((millis() - pause)/1000);

           Serial.println(" sec");

           buzz(4, 2400, 500); // buzz the buzzer 

         delay(50); // wait a bit 

           }

       }           

  

}

  void buzz(int targetPin, long frequency, long length) {

  long delayValue = 1000000/frequency/2; // calculate the delay value between transitions

  //// 1 second's worth of microseconds, divided by the frequency, then split in half since

  //// there are two phases to each cycle

  long numCycles = frequency * length/ 1000; // calculate the number of cycles for proper timing

  //// multiply frequency, which is really cycles per second, by the number of seconds to 

  //// get the total number of cycles to produce

 for (long i=0; i < numCycles; i++){ // for the calculated length of time...

    digitalWrite(targetPin,HIGH); // write the buzzer pin high to push out the diaphram

    delayMicroseconds(delayValue); // wait for the calculated delay value

    digitalWrite(targetPin,LOW); // write the buzzer pin low to pull back the diaphram

    delayMicroseconds(delayValue); // wait againf or the calculated delay value

  }

  }

Resultado:

Obs: No caso de não usarmos a 'pullup resistor' interna do arduino ( pinMode(pirPin, INPUT); digitalWrite(pirPin, LOW); ), e para se obter leituras correctas de sinal do sensor, é necessário colocar uma resistência de 10k (pullup resistor) entre o sinal e os 5V.  Ver esquema : http://bildr.org/2011/06/pir_arduino/