The PIR sensor is very sensitive and is known to be creating false triggers, i.e. it will occasionally go LOW to indicate that there is no movement, even though there is movement.
The sketch in the PIR lecture of Arduino Step by Step Getting Started is very simple. It merely reports what the sensor is telling it, and does not try to compensate for its limitations.
There are two things you can do to create a more reliable detection system (and this can deliver the functionality you are asking for).
1. Calibrate the sensor.
Notice that there are two orange knobs on one side of the sensor. Have a look at this picture where I am marking the role of each knob.
The one on the left is for distance. Turn it clockwise to make it possible to detect movement up to 7 meters away from the sensor. I tend to keep this turned almost all the way anticlockwise since all my experiment are short distance.
The one on the right is for sensitivity. Turn it clockwise to decrease sensitivity, meaning that for the device to trigger, a longer movement is required. I keep this turned all the way anticlock-wise, producing a very sensitive signal, and manage erroneous trigger in the sketch.
There is also a jumper that controls the trigger mode. Make sure you have this in H-mode (see picture). In H-mode, the sensor will trigger repeatedly when it “thinks” that there is movement.
2. Add some logic to the sketch to help deal with the imperfections of the sensor.
In this example (heavily borrowing from a sketch I found in the Arduino playground), I define a cutoff time. Any LOW triggers from the sensor within this cuttof time are ignored as false and the Arduino continues to think that there is movement.
/* * PIR sensor tester */ int ledPin = 13; // choose the pin for the LED int inputPin = 3; // choose the input pin (for PIR sensor) int pirState = true; // we start, assuming no motion detected int val = 0; // variable for reading the pin status int minimummSecsLowForInactive = 5000; // If the sensor reports low for // more than this time, then assume no activity long unsigned int timeLow; boolean takeLowTime; //the time we give the sensor to calibrate (10-60 secs according to the datasheet) int calibrationTime = 30; void setup() { pinMode(ledPin, OUTPUT); // declare LED as output pinMode(inputPin, INPUT); // declare sensor as input Serial.begin(9600); //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); } void loop(){ val = digitalRead(inputPin); // read input value if (val == HIGH) { // check if the input is HIGH digitalWrite(ledPin, HIGH); // turn LED ON if (pirState) { // we have just turned on pirState = false; Serial.println("Motion detected!"); // We only want to print on the output change, not state delay(50); } takeLowTime = true; } else { digitalWrite(ledPin, LOW); // turn LED OFF if (takeLowTime){ timeLow = millis(); takeLowTime = false; } if(!pirState && millis() - timeLow > minimummSecsLowForInactive){ pirState = true; Serial.println("Motion ended!"); delay(50); } } }