HC-SR501 PIR Sensor with Arduino Uno: Motion Detection, Wiring and Code
Review draft — incomplete: confirm the supplied module revision, pin markings and current/timing specifications before approval. The downloadable code attachment is pending; the full copyable program is included below. Arduino compilation and physical testing have not been performed.
Build a simple motion-input monitor with the HC-SR501 PIR sensor and Arduino Uno R3. After a startup wait, the built-in LED follows the sensor output and Serial Monitor prints each change. This is a useful first exercise in reading a digital sensor without flooding the serial window.
What you will build
You will connect three wires, upload a complete sketch and compare the module output with its LED indication. No extra LED, breadboard, library or cloud account is required. Allow about 30 minutes for assembly and observations.
Contents
- How it works
- Parts and purchase links
- Pinout, schematic and visual wiring
- Assembly and IDE setup
- Complete program
- Upload and test
- Troubleshooting and FAQs
How it works
A passive infrared sensor responds to changes in infrared radiation across its sensing zones. The module processes that signal and provides a digital output. It does not send a distance value or identify a person. A stationary person may not produce continuing changes, so a LOW output cannot prove a room is empty.
The supplier reference describes a startup period of roughly a minute and a nominal 3.3 V HIGH output. Its H jumper mode retriggers the hold timer; L selects a single trigger. A delay trimmer controls the output hold time. There can also be a blocking interval after an output pulse. These details explain why the LED need not turn off as soon as you stop moving. Exact timings vary by revision.
Parts and purchase links
| Component | Required | Specification / pack size |
|---|---|---|
| HC-SR501 PIR module | 1 | SKU ANU-HC-SR501; store lists 4.5–20 V supply, 3.3 V TTL output and 0.6 mA average current. Use 5 V in this project. Sold as one module. |
| Arduino Uno R3 | 1 | 5 V ATmega328P board; USB-B connector and built-in LED. |
| Male-to-female jumper wires | 3 leads | 20 cm; purchase pack contains 40 leads. Female ends fit the PIR male header; male ends fit Uno sockets. |
| USB A-to-B data cable | 1 | USB-B at Uno and USB-A at computer; use an appropriate computer adapter if needed. |
Have a computer ready. The store current figure is a listing specification, not a measured result or a guaranteed maximum. The supplier guide contains inconsistent current, polarity and timing statements, and the store does not identify its manufacturer revision. These require review; do not use them to estimate battery life.
Pinout and connections
| PIR pin label | Uno pin | Purpose |
|---|---|---|
| VCC | 5V | Sensor power |
| OUT | D2 | Digital signal to Uno |
| GND | GND | Shared reference |
Circuit schematic

Visual module wiring

Both board drawings are symbolic. Follow the actual printed pin labels, not the illustrated physical positions. Check the underside of your module; if the labels are absent or ambiguous, obtain the matching pinout before powering it. The schematic shows the module interface, not the circuitry under its lens.
Disconnect USB while wiring. Use the Uno 5V supply pin, not VIN or a GPIO. Keep VCC and GND correctly oriented. The ATmega328P reference gives a normal digital-input HIGH threshold of 0.6 × VCC: 3.0 V at a 5.0 V supply. A nominal 3.3 V PIR output is suitable for this short-wire input connection, but leaves limited noise margin. D2 stays in INPUT mode; do not drive it as an output or enable a 5 V pull-up.
Assembly and Arduino IDE setup
- With power disconnected, identify the three labelled pins and connect them using the table. Use the fitted male header; loose unconnected inputs give unreliable readings.
- Place the module on an insulating surface with a clear view of the test area. Keep the connections short and secure.
- Identify the trigger jumper and trimmers from the matching module documentation. For the first test, use a short hold time. Do not force a trimmer beyond its end stop or assume a rotation direction from an unrelated module photo.
- Install Arduino IDE from the official Arduino website. Install Arduino AVR Boards in Boards Manager if necessary, then select Arduino Uno and the connected port.
- Create a sketch named
uno_pir_motionand paste the program below. Connect the Uno with the USB data cable.
Complete Arduino program
Copy the entire sketch. A downloadable attachment is pending hosting.
// Original Anu Electronics tutorial: HC-SR501 + Arduino Uno R3.
// VCC -> 5V, GND -> GND, OUT -> D2. Use fitted pin labels.
const byte PIR_PIN = 2;
const unsigned long WARMUP_MS = 60000UL;
unsigned long startupMs;
bool ready = false;
int previousState = -1;
void setup() {
pinMode(PIR_PIN, INPUT); // No 5V internal pull-up on sensor OUT.
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
Serial.begin(9600);
startupMs = millis();
Serial.println(F("WARMUP: wait 60 seconds"));
}
void loop() {
if (!ready) {
if ((unsigned long)(millis() - startupMs) < WARMUP_MS) {
return;
}
ready = true;
Serial.println(F("READY"));
}
int state = digitalRead(PIR_PIN);
digitalWrite(LED_BUILTIN, state);
if (state != previousState) {
Serial.println(state == HIGH ? F("PIR HIGH") : F("PIR LOW"));
previousState = state;
}
}
What the code does
-
WARMUP_MSignores input for 60 seconds after setup. The LED stays off during that interval. Increase it if your module needs longer to settle. - The subtraction uses unsigned arithmetic. The readiness flag latches once, so the startup gate is not repeated when the millis counter later wraps.
-
previousState = -1forces the first input level to be printed after startup, even if it is LOW. - The LED follows every sampled level; serial text appears only on a change. A long HIGH pulse produces one HIGH line, not repeated messages.
- This program reports the sensor level. It does not count visitors or separate several movements inside one held pulse.
Upload and test
- Click Verify and Upload in Arduino IDE. Open Serial Monitor at 9600 baud. Reset the Uno if you missed the startup message; opening the monitor can also reset an Uno.
- Expect
WARMUP: wait 60 seconds. Leave the sensor undisturbed during startup. This wait is a starting point, not proof of stabilization. - After the wait, expect READY followed by the current PIR HIGH or PIR LOW state. The built-in L LED should follow that state.
- Move across the sensor view, then leave it undisturbed. Note when HIGH appears and how long it takes to return LOW. Do not expect the LED to follow each footstep.
- Disconnect power before changing the jumper. Repeat the test in H and L modes, waiting again after power-up. Compare a single movement with several movements during an active pulse.
- Record your actual results separately. If the output never settles, review wiring and module settings before relying on it.
Expected output

The animation is a simulated, compressed sequence. It illustrates startup, state changes and a held output; it is not a recording of tested hardware.
Troubleshooting
| Symptom | Check |
|---|---|
| LED remains off during startup | This is intentional. Wait for READY before judging the input response. |
| LED stays on | Wait out the hold delay, reduce repeated movement and check the trigger mode. Inspect OUT and GND connections if it never returns LOW. |
| Unstable output | Check power, common ground and loose leads. Allow more startup time. Compare behaviour in a quiet test area with a steady background. |
| No serial text after the first state | The program prints changes only. Move across the view; confirm 9600 baud and the correct port. |
| Upload fails | Select Arduino Uno, use a data-capable cable and close other software using the serial port. |
FAQs
Can the program shorten the module hold time?
It can change how your application reacts, but reading faster cannot recover separate movements hidden inside one HIGH pulse. Adjust the hardware control and test the result.
Why not add a separate LED and resistor?
The Uno already has an indicator for this exercise. Using it keeps the wiring to three leads and avoids an unnecessary external load on the sensor.
Can this be used as a people counter or security alarm?
This demonstration reports input states only. It does not establish direction, identity, occupancy or dependable alarm coverage. Validate a suitable system for any application that needs those features.
Related projects and components
Compare this digital input with the Arduino LDR light-sensor project, or explore distance with the HC-SR04 Arduino tutorial.
Start your build with the HC-SR501 PIR module and Arduino Uno R3. Compatible wires and USB cable are linked in the parts table.
Sources and validation
- Handson Technology HC-SR501 supplier reference — startup and trigger behaviour; not proof of the stocked module manufacturer.
- Arduino Uno R3 documentation
- Arduino language reference
- Microchip ATmega328P reference, DC characteristics
Writing, code and diagrams are original. CircuitDigest informed the tutorial structure only. The branded cover uses the store product image as visual reference. Simulated logic checks cover startup and state reporting; no compiler or physical hardware validation has been performed. Confirm the exact module revision and specifications before approving this draft.