If you need a room-scale occupancy trigger for a 5V mains-powered project, buy the HC-SR501. If you are building a compact, battery-powered ESP32 node running on 3.3V, buy the AM312. PIR (Passive Infrared) modules are notoriously finicky when mismatched to a microcontroller's logic levels or placed near RF sources. This guide breaks down the exact hardware behavior, timing math, and interference mitigation you need to get reliable triggers without false positives.
How PIR Motion Sensor Detecting Actually Works
PIR sensors do not measure absolute temperature; they measure changes in infrared radiation. The core component is a pyroelectric crystal (typically lithium tantalate) housed in a metal TO-5 can. When a warm object—like a human body at 37°C—moves across the sensor's field of view, the crystal absorbs the shifting IR energy and generates a proportional surface charge. This charge is converted into a voltage spike by an internal JFET impedance converter.
To prevent false triggers from ambient room heating, the sensor window masks the crystal into two distinct slots. The sensor only outputs a signal when one slot sees a different IR level than the other, meaning a warm body must physically cross the detection zones. A plastic Fresnel lens sits over the can to focus distant IR radiation onto these tiny slots, effectively multiplying the sensor's physical range from a few inches to several meters. For a deeper look at the underlying physics of pyroelectric materials, Adafruit's PIR sensor guide provides an excellent breakdown of the internal crystal lattice behavior.
Pinouts, Wiring, and Logic Levels
The most common mistake makers make is feeding a 5V HC-SR501 output directly into a 3.3V ESP32 GPIO, which can degrade or destroy the pin over time. Always match your module's output logic level to your microcontroller.
| Module | VCC Range | Output Logic High | Delay Time | Best Use Case |
|---|---|---|---|---|
| HC-SR501 | 4.5V – 20V | ~VCC (e.g., 5V) | Adjustable (0.3s – 20s+) | Arduino Uno/Mega, 5V relay boards, mains lighting |
| AM312 | 2.7V – 6V | ~VCC (e.g., 3.3V) | Fixed (~2.5s) | ESP32/ESP8266, battery IoT nodes, wearables |
| SR602 | 2.7V – 6V | ~VCC (e.g., 3.3V) | Fixed (~2.0s) | Ultra-compact enclosures, hidden PCB mounts |
VIN pin (assuming USB 5V input), but route the OUT pin through a simple voltage divider (e.g., 2kΩ and 3.3kΩ resistors) or a logic level converter before hitting the ESP32 GPIO.
Output Signal Math: Mapping Raw State to Time and Distance
Unlike analog sensors (e.g., MQ-135 gas sensors), a PIR module's output is strictly digital push-pull. There is no ADC raw reading to map to a physical unit like distance or temperature. The output pin simply drives HIGH (motion) or LOW (clear). Therefore, the "math" for a PIR sensor involves translating the physical timing components and lens geometry into usable detection parameters.
Timing Math (The BISS0001 Formula)
The HC-SR501 uses the BISS0001 PIR controller IC. The physical delay time ($T_x$) that the output pin stays HIGH after detecting motion is governed by the external resistor and capacitor on the IC's timing pin. The formula from the SparkFun PIR Hookup Guide and datasheet is:
T_x ≈ 2048 × R_10 × C_6
On a stock HC-SR501, $C_6$ is typically a 10nF (103) ceramic capacitor, and $R_{10}$ is a 1MΩ trimpot in series with a fixed resistor. If you turn the delay pot to its maximum resistance (~1MΩ), the output pulse width is:
2048 × 1,000,000 Ω × 0.00000001 F = ~20.48 seconds.
If you need a 5-minute delay for a closet light, you must physically desolder the 10nF capacitor and replace it with a 47nF or 100nF capacitor to scale the multiplier.
Distance and Cone Geometry
The physical detection range is not adjustable via code; it is fixed by the Fresnel lens. A standard dome lens provides a ~120° horizontal cone and ~90° vertical cone, with a maximum focal distance of 7 meters. If a target is 7 meters away, they must move laterally across the cone to trigger the dual-slot differential. If they walk directly toward the sensor, the IR signature remains uniform across both slots, and the sensor will fail to detect them until they are within 1-2 meters.
Interference Sources and Calibration
False triggers are the primary failure mode in PIR deployments. Before you write complex debounce code in your firmware, eliminate these physical interference sources:
- 2.4GHz RF Interference: The ESP32's WiFi antenna emits strong 2.4GHz radiation. If placed within 3cm of the HC-SR501's high-impedance JFET amplifier, the RF energy rectifies and mimics a pyroelectric voltage spike. Fix: Keep the ESP32 antenna at least 5cm away from the PIR dome, or solder a 0.1µF (104) bypass capacitor directly across the sensor's VCC and GND pins.
- HVAC and Drafts: Rapid changes in ambient air temperature from AC vents will trigger the dual-slot differential. Fix: Never mount a PIR sensor directly opposite or below a forced-air vent.
- Pet Immunity: Standard lenses will trigger on dogs and cats. Fix: If you need pet immunity, you must physically mask the bottom segments of the Fresnel lens with electrical tape, or mount the sensor higher (2.5m+) and angle it slightly upward so the lower detection zones do not intersect the floor.
- Sunlight and IR Heaters: Direct sunlight sweeping across the room, or the cycling of a quartz space heater, will blind or falsely trigger the sensor. Fix: Avoid line-of-sight to windows and thermal appliances.
Decision Tree: Which PIR Module Should You Buy?
Stop guessing based on whatever is cheapest in your AliExpress haul. Use this decision matrix to select the exact part number for your bill of materials.
| Project Constraint | Condition | Concrete Pick |
|---|---|---|
| Microcontroller Logic | Using 5V Arduino Uno, Mega, or direct 5V relay control? | HC-SR501 |
| Microcontroller Logic | Using 3.3V ESP32, ESP8266, or Raspberry Pi Pico? | AM312 or SR602 |
| Power Source | Battery powered (LiPo/18650) where quiescent current matters? | SR602 (draws ~10µA vs HC-SR501's ~50mA) |
| Timing Control | Need user-adjustable delay and sensitivity pots on the board? | HC-SR501 |
| Timing Control | Need a fast, fixed ~2-second reset for rapid re-triggering? | AM312 |
| Form Factor | Must fit inside a < 15mm diameter enclosure or PCB mount? | SR602 (lens is integrated flat on the SMD board) |
The Default Recommendation: If you are building a modern IoT occupancy sensor using an ESP32-WROOM-32 on a 18650 battery sled, the SR602 is the definitive choice. Its 10µA quiescent draw will not drain your battery pack, its 3.3V native output requires no level shifting, and its fixed 2-second delay is perfectly matched to standard MQTT keep-alive and WiFi deep-sleep wake cycles. Buy the HC-SR501 only if you are wiring a standalone 5V closet light relay with no microcontroller involved.
Quick ESP32 Interrupt Implementation
When using the SR602 or AM312 with an ESP32, do not use digitalRead() in your main loop. The 2-second pulse can be missed if the ESP32 is busy handling WiFi stacks. Use a hardware interrupt:
const int PIR_PIN = 14; // GPIO 14
volatile bool motionDetected = false;
void IRAM_ATTR handleMotion() {
motionDetected = true;
}
void setup() {
Serial.begin(115200);
pinMode(PIR_PIN, INPUT_PULLDOWN);
attachInterrupt(digitalPinToInterrupt(PIR_PIN), handleMotion, RISING);
}
void loop() {
if (motionDetected) {
Serial.println("Motion detected! Sending MQTT...");
motionDetected = false; // Reset flag
// Insert MQTT publish code here
}
delay(10); // Prevent watchdog barking
}





