PIR Retriggerable Motion Timer
Keep the onboard LED on while motion output is active, then hold it for ten seconds after the last HIGH reading.

Steps
Understand the two timers
The PIR module has its own output hold time. This sketch adds a separate ten-second software hold after the sensor output last reads HIGH. Total time from physical movement to LED-off can therefore exceed ten seconds. The PIR detects changes in infrared patterns; it does not reliably prove that a motionless person has left.
Connect the module
Disconnect USB. Read the HC-SR501 labels and connect VCC to UNO 5V, GND to UNO GND and OUT to D2. Pin order varies between boards. Use jumper wires that fit the module pins. This project drives only the onboard LED; there is no relay or mains lamp.
Set retrigger mode
If your module has H/L jumper markings, select H for retriggering. Set the module delay near its shorter end initially, without forcing a potentiometer past its travel limit. The software timer remains independent of this setting. Refer to the exact module markings where they differ.
Upload and wait for warm-up
Upload the sketch and open Serial Monitor at 115200 baud. It ignores the input for the initial 60 seconds while the sensor settles. Avoid touching the sensor lens. Once Ready for motion appears, walk across the sensor field rather than directly toward it.
Observe retriggering
A HIGH input turns on the onboard LED and continually refreshes lastHighAt. After OUT stays LOW for ten seconds, the LED turns off. Move again during that interval: the output and hold should extend. Repeat with different module delay settings and note how the hardware and software holds combine.
Test the timer without guessing
Watch both the module OUT state and the LED, using Serial messages and a meter if available. Verify that it turns off after ten seconds of LOW input, not ten seconds after the first motion. Moving warm objects, airflow and placement can affect results; this is a prototype, not an intrusion alarm.
Code
#include <Arduino.h>
const uint8_t PIR = 2;
const uint32_t WARMUP_MS = 60000UL, HOLD_MS = 10000UL;
uint32_t bootAt = 0, lastHighAt = 0;
bool active = false, warming = true;
void setup() {
Serial.begin(115200); pinMode(PIR, INPUT); pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW); bootAt = millis();
Serial.println("Allow 60 seconds for the PIR to settle.");
}
void loop() {
uint32_t now = millis();
if (warming) {
if (uint32_t(now - bootAt) < WARMUP_MS) return;
warming = false; Serial.println("Ready for motion.");
}
if (digitalRead(PIR) == HIGH) {
lastHighAt = now;
if (!active) { active = true; Serial.println("Motion: timer started."); }
}
if (active && uint32_t(now - lastHighAt) >= HOLD_MS) {
active = false; Serial.println("No HIGH input for 10 seconds: LED off.");
}
digitalWrite(LED_BUILTIN, active ? HIGH : LOW);
}
