How to make a PIR sensor more sensitive?

Hello all,
I'm a total noob at electronics and I've followed some of the basic tutorials, and I recently started on my first project: an intrusion alarm. I've copied some code off of a authentic and legitimate site (ladyada.net) and the program works with my sensor...however it isn't very sensitive. Like the only way to turn on the LED connected to the Arduino is to literally touch the sensor. I'm sure that placement has something to do with it, but I'm putting the sensor on a flat surface (slightly tilted) and it is pointing towards the ceiling. My wiring is correct. Does anyone have any methods on coding or placement that makes a PIR more sensitive?

If neccesary, I will post code and pictures.

Thanks,

Eric

EDIT: I'm using Arduino Uno. If that makes a difference...I really don't know.

If neccesary, I will post code and pictures.

Please do

As you wish!

/////////////////////////////
//VARS
//the time we give the sensor to calibrate (10-60 secs according to the datasheet)
int calibrationTime = 45;        

//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 = 2;    //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);

  //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");
    delay(50);
  }

////////////////////////////
//LOOP
void loop(){

     if(digitalRead(pirPin) == HIGH){
       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"); 
         delay(50);
         }         
         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");
           delay(50);
           }
       }
  }

Again, I wrote none of this, all credit to http://www.ladyada.net

Pic:

Thanks

Eric

Hi Eric,

please modify your post, select the code and press the # button => code view Looks so much better ..

TIA,
Rob

My wiring is correct. Does anyone have any methods on coding or placement that makes a PIR more sensitive?

Which PIR sensor do you have? A lot (most?) require 12 volts to operate properly, and can not be driven directly by the Arduino.

Connect a resistor in series with LED, if it's not "chip-led" .

Rob- thanks for the tip. I should've seen that before.

Paul-I'm using an SE-10 Sparkfun PIR Motion Sensor. You're right about the operating voltage. I'll hook it up via breadboard then?

Magician: How could I hook this up to the arduino? Could you point me to an example or a tutorial online that explains this? I know what resistors do, but I'm not sure how I would make this circuit (I'm as nooby as they get.)

To any one who can help, here is the data sheet.

If anyone can make sense of anything that could be helpful to my question, that would be extremely helpful.

Thanks guys for your help.

Eric

The output of the PIR is also 12Volt (I assume? can you confirm)

Make a voltage divider with on the one end PIR output, and on the other end GND. Connect the Arduino to the middle

Now you have to choose R1 and R2 so that 12 / (R1+R2) = 5 / (R2) and R1+R2 = 10..50K e.g. R1 = 22K and R2 = 15K
Take care that the voltage on the digital is 4..5Volt not higher, so better round R2 downwards.

       PIR OUTPUT
         +
         |   
        +-+  
        | |  
        | |  R1
        | |  
        +++  
         +
         +-------+ Arduino DigitalIn
        +++    
        | |    
        | |  R2   
        | |    
        +++    
         |     
         +     
        GND

Magician: How could I hook this up to the arduino? Could you point me to an example or a tutorial online that explains this? I know what resistors do, but I'm not sure how I would make this circuit

There is a picture:
http://arduino.cc/en/Tutorial/PhysicalPixel

Thanks for the help Rob, very informative post. Output is 12 volts. I understand the logic and I believe I know how to make this divider. (R stands for resistor right?? :fearful: ) Unless I can get away with a slightly different value on a resistor, I may have to buy some resistors online if that's the case.
I also have a hard time visualising what this looks like on a breadboard. Do you know of any good sources that offer easy tutorials on voltage dividers?

Magician: What should the resistor value be for my project? Also, is the end of the resistor attached to the end of the LED? Sorry If I'm not catching on very quickly, I'm just trying to figure things out.

Thanks for the help guys, I appreciate it.

Eric

R = resistor indeed.
You can test the resistor divider with a voltmeter. Any output between 4 and 5 volt wil do. If it is higher you should either increase R1 or decrease R2.

Be sure not to connect the arduino's pin to voltages > 5V !!

The sum of the resistors should be in the order of 10-50K to keep the current low. 12V/10K ~~ 1 mAmpere 12V/50K ~~0.2 mA

Rob

Thanks for the pointers guys! Looks like I'm going to have to buy some resistors. I should've made this post before I bought the sensor. Anyway, I will try both of the methods you guys have described.

Thanks a lot,

Eric

You shouldn't need 12V. I used that same sensor as part of an art installation that ran just fine off 3 AAs. In fact the artist had to block out part of the sensor field with paper to reduce the sensitivity. I may have bypassed the onboard regulator to bring the 4.5V in more directly.

I believe the output is merely open collector, connect it to +5V thru a 10K resistor, I found the internal pullups wouldn't quite do it.

So if I connect it through this 10k resistor, in the same method as Magician has described, it will become more sensitive?

Sorry for the late reply

Thanks,

Eric

"So if I connect it through this 10k resistor"

Connect what? Magician only seemed to be discussing the LED.

The PIR has an open collector output- that means the output is the collector of a transistor that is not connected to anything.
You connect that to your arduino input pin, then to that same pin connect a 10K resistor, and connect the other side of the resistor to +5.

As for sensitivity, I believe the PIR has an onboard power regulator, supplying it with more than 5V just makes it hotter.
Let me see if I can find the SE-10 datasheet to confirm ...

From Sparkfun's page:

"This unit works great from 5 to 12V (datasheet shows 12V). You can also install a jumper wire past the 5V regulator on board to make this unit work at 3.3V. Sensor uses 1.6mA@3.3V."
I did that to have it run from 3 AA batteries - not sure it made a difference -the 10K pullup sure did - the arduino input pullup resistor is not sufficient. The artist using it had to block off the field of view to make it less sensitive.
The smaller chip in the picture is the regulator, the larger is an op-amp.

"The alarm pin is an open collector meaning you will need a pull up resistor on the alarm pin. The open drain setup allows multiple motion sensors to be connected on a single input pin. If any of the motion sensors go off, the input pin will be pulled low."

"open collector" implies NPN transistor
"open drain" implies N-channel MOSFET
So which is it really? functionally no difference.
I don't have one here to look at, wife wants to get a couple and make cat detectors for when we can't see them waiting at the door to go on or out.

So if I connect it through this 10k resistor, in the same method as Magician has described, it will become more sensitive?

No, connecting resistor to LED you would not make a PIR more sensitive, but you will prevent arduino board from destruction. And this is more important thing, IMHO, than sensitivity.

Assuming this is the parallax pir sensor it worked fine for me out of the box at 5v. look for a really simple example sketch to test your hardware.

Here's a simple sketch. Okay, could be a little simpler, but it works from USB power, and works from 3 AAA batteries also.
Here's a video clip - kinda big (28M), haven't figured out video editing yet
http://www.crossroadsfencing.com/MVI_1899.AVI

Connect a couple of resistors/LEDs to the noted pins in the blue & red arrays in void setup so you can that it's working.
After power up, you have 3 seconds to get out of scan range, then the PIR scans the room to set a baseline, and scans for 10 seconds, if no activity the arduino goes to sleep until interrupted by the PIR and then flashes the lights a few seconds, goes back to sleep.
You need a 10K pullup on Pin 2, and the PIR open collector connects there also.

#include <avr/sleep.h>      // powerdown library
#include <avr/interrupt.h>  // interrupts library

#define NUM_OFF 3
#define DELAY 50
#define PWM_MIN 10
#define PWM_MAX 128

int blue[5];
int red[5];
int interrupt = 2; // hardware interrupt, Motion Detector Open Collector pulls low
unsigned long awake_time = 0; // capture time when wake up from sleep
unsigned long elapsed_time = 0;  // time that have been awake for

//***************************************************
// *  Name:        pin2Interrupt, "ISR" to run when interrupted in Sleep Mode
void pin2Interrupt()
{
  /* This brings us back from sleep. */
}

//***************************************************
// *  Name:        enterSleep
void enterSleep()
{
  /* Setup pin2 as an interrupt and attach handler. */
  attachInterrupt(0, pin2Interrupt, LOW);
  delay(50); // need this?
  /* the sleep modes
   SLEEP_MODE_IDLE - the least power savings
   SLEEP_MODE_ADC
   SLEEP_MODE_PWR_SAVE
   SLEEP_MODE_STANDBY
   SLEEP_MODE_PWR_DOWN - the most power savings
   */
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);  // setting up for sleep ...
  sleep_enable();                       // setting up for sleep ...
  sleep_mode();                         // now goes to Sleep and waits for the interrupt

  /* The program will continue from here after the interrupt. */
  // detachInterrupt(0);                 //disable interrupts while we wake up 

  /* First thing to do is disable sleep. */
  sleep_disable(); 

  // then go to the void Loop()
}

// ***********************************************************************
// set up the pins as Inputs, Outputs, etc.
void setup()
{
  blue[0] = 4;
  blue[1] = 5; // PWM
  blue[2] = 7;
  blue[3] = 6; // PWM
  blue[4] = 8;
  
  red[0] = 12;
  red[1] = 10; // PWM
  red[2] = 14;
  red[3] = 11; // PWM
  red[4] = 15; 

  for(int i=0;i<5;i++) {
    pinMode(blue[i], OUTPUT);
    pinMode(red[i], OUTPUT);
  }
  pinMode (interrupt, INPUT);  // hardware interrupt for waking up
  digitalWrite (interrupt, HIGH);  // internal pullup enabled

  randomSeed(analogRead(0));  

awake_time = millis(); // capture wakeup time
//Serial.begin (19200); // for debug
delay (3000); // turn on, scan room
}

// ****************************************
// setup is done, start program
void loop()
{
  // flashl lights in police sequence
  allOn();
  
  analogWrite(blue[1], random(PWM_MIN, PWM_MAX));
  analogWrite(blue[3], random(PWM_MIN, PWM_MAX));
  analogWrite(red[1], random(PWM_MIN, PWM_MAX));
  analogWrite(red[3], random(PWM_MIN, PWM_MAX));

  for(int i=0;i<NUM_OFF;i++) {
    digitalWrite(blue[random(5)], LOW);
    digitalWrite(red[random(5)], LOW);
  }
  delay(DELAY);

// check if awake 10 seconds, then call sleep mode
elapsed_time = millis() - awake_time;  // see if 10 seconds gone by
//Serial.println (elapsed_time);
if (elapsed_time >=10000){  
  allOff();                    // turn all light off
  delay (3000);                // time to walk away 
  enterSleep();               // call Sleep function to put us out
                              //  THE PROGRAM CONTINUES FROM HERE after waking up in enterSleep()
awake_time = millis();        // capture the time we woke up  
}
} // end void loop


// ****************************************
// function to turn all lights on
void allOn() {
  for(int i=0;i<5;i++) {
    digitalWrite(blue[i], HIGH);
    digitalWrite(red[i], HIGH);
  }
}

// ****************************************
// function to turn all lights off
void allOff() {
  for(int i=0;i<5;i++) {
    digitalWrite(blue[i], LOW);
    digitalWrite(red[i], LOW);
  }
}