Skip to content
beginnerESP32esp32-campir-sensormotion-detection

ESP32-CAM PIR Motion Detection Camera

Wake the ESP32-CAM from deep sleep with a PIR sensor, snap a photo the instant motion is detected, and save it to microSD -- built for battery-powered use.

10/17/2026 10 min read 0 views

A camera that's awake and streaming around the clock is the wrong tool for watching a driveway or a side gate -- most of what it captures is an empty frame, and if it's battery-powered, continuous operation drains it in hours rather than the weeks or months a motion-triggered setup can manage. This project wires a PIR (passive infrared) motion sensor to wake the ESP32-CAM from deep sleep, capture one photo the instant it detects movement, save it to microSD, and go straight back to sleep. Idle current in deep sleep drops to a fraction of a milliamp, which is the entire reason this approach can run for weeks on batteries where continuous streaming would need a wall outlet.

ESP32-CAM and PIR sensor mounted together, watching a driveway entrance from deep sleep between triggers

This is intended for outdoor and semi-outdoor placements where mains power isn't always convenient -- a shed, a driveway post, a gate. A quiet interior hallway or a workshop desk usually has an outlet close enough that battery operation is more effort than it's worth; the deep sleep design in this guide earns its complexity specifically for the cases where it doesn't.

Hardware Needed

Components

6 items
NameQtyLink
ESP32-CAM (AI-Thinker) board×1—
HC-SR501 PIR motion sensor×1—
microSD card, 32GB or smaller, Class 10×1—
FTDI USB-to-serial adapter (3.3V) for flashing×1—
5V power source -- wall supply or battery pack, depending on deployment×1—
Weatherproof enclosure (for any outdoor mounting)×1—

Need these parts? Get this build sheet by email

Parts list with buy links, plus new builds as they're published. By subscribing you agree to our Privacy Policy. Unsubscribe anytime.

HC-SR501 PIR sensor next to the ESP32-CAM before wiring

Wiring the PIR Sensor

The HC-SR501 has three pins -- VCC, GND, and a digital OUT that goes HIGH when it detects motion. That OUT pin connects to a GPIO capable of waking the ESP32 from deep sleep, which narrows the choice more than you'd expect: only the RTC GPIOs support this, and on the AI-Thinker board, most of those are already claimed by the camera interface.

PIR PinESP32-CAM PinNotes
VCC5VThe sensor needs 5V, not 3.3V, to operate reliably
GNDGNDCommon ground
OUTGPIO 13One of the few RTC-capable GPIOs not already claimed by the camera

GPIO 13 is the practical choice here specifically because it's RTC-capable and free -- most of the other free-looking pins on this board either aren't wake-capable or are shared with the SD card interface covered in the Photo Capture & microSD Storage guide.

Wiring diagram showing the PIR sensor's VCC, GND, and OUT pins connected to the ESP32-CAM

Why Deep Sleep, Not a Polling Loop

It's tempting to skip deep sleep entirely and just poll the PIR pin in a normal loop() -- check if it's HIGH, capture if so, repeat. That works, and it also keeps the CPU, camera driver, and (if WiFi is initialized) radio all powered continuously, which defeats almost the entire point of building this as a motion-triggered camera rather than a streaming one. The whole appeal of a PIR-gated design is that the board spends the overwhelming majority of its time in a state drawing next to nothing, only fully waking for the few seconds it takes to capture and save a photo after genuine motion.

Deep sleep resets the board completely on wake -- setup() runs fresh every single time, exactly like the pattern used in the ESP32-CAM Timelapse Recorder. The difference here is what triggers the wake: instead of a fixed timer, esp_sleep_enable_ext0_wakeup() tells the chip to wake specifically when GPIO 13 goes HIGH, which is exactly the PIR's motion-detected signal.

Comparison of current draw over time between a continuously polling loop and a PIR-triggered deep sleep design

The Code

C++

Every element of this loop-avoidance pattern matters for battery life: esp_camera_deinit() before sleeping releases the camera's resources cleanly rather than leaving them half-initialized across a sleep cycle, and photoCount uses RTC_DATA_ATTR so it survives across deep sleep the same way it does in the timelapse project -- the small slice of RAM deep sleep doesn't wipe.

Serial Monitor output showing the board waking on PIR trigger, capturing a photo, and returning to sleep

Tuning PIR Sensitivity and Delay

The HC-SR501 has two small onboard potentiometers most people never touch, and both matter more than the wiring for getting reliable, non-annoying triggers:

PotentiometerControlsPractical setting
SensitivityDetection range, roughly 3-7 metersStart low and increase gradually -- overly sensitive settings trigger on curtains moving in a draft
Time delayHow long OUT stays HIGH after the last detected motionShortest setting for this project -- a long delay just means longer awake time per trigger without added benefit

There's also a jumper on most HC-SR501 boards, often unlabeled or easy to miss, that switches between "single trigger" and "repeatable trigger" mode. Repeatable trigger mode -- OUT resets and can re-fire immediately on continued motion -- is almost always the right choice here; single trigger mode requires OUT to fully return to LOW before it can trigger again, which delays your next photo more than expected if someone lingers in frame.

Close-up of the PIR sensor's sensitivity and delay potentiometers, with the trigger-mode jumper visible

⚠️ Warning

PIR sensors need roughly 30-60 seconds after power-up to stabilize their internal readings. A trigger recorded in the first minute after power-on is very often a false one from the sensor still settling, not a genuine detection -- worth knowing before assuming a test setup is broken.

Mounting for Reliable Range and Fewer False Triggers

PIR sensors detect changes in infrared radiation crossing their field of view -- they respond to movement across the sensor's zones more reliably than movement directly toward or away from it, which affects mounting angle more than people expect. A sensor aimed straight down a driveway, watching a car approach head-on, often triggers less reliably than the same sensor angled to catch the car crossing left-to-right at some point in its approach.

A few placement details worth getting right before mounting permanently:

  • Avoid aiming across a heat source -- a nearby AC unit's exhaust, a sun-heated driveway shifting temperature through the day, or a heating vent all cause intermittent false triggers that are genuinely difficult to diagnose after the fact
  • Mount at 2-2.5 meters height, angled slightly downward -- high enough to avoid small animals triggering it constantly, low enough to still catch a person's torso reliably
  • Keep the lens clear of spiderwebs and debris -- a surprisingly common cause of a PIR sensor that "stopped working" outdoors after a few weeks; a web strand moving in the wind directly in front of the lens triggers it repeatedly
Recommended PIR mounting height and angle for reliably catching cross-motion rather than head-on approach

Power Options for a Battery-Powered Build

This is where the deep sleep design actually pays off. A rough current budget: deep sleep idle draw sits around 10-30 microamps depending on the specific board revision, while an active capture-and-write cycle spikes to 200-300mA for a few seconds. At a realistic rate of, say, 20 triggers a day, the board spends the overwhelming majority of its time in that microamp-level sleep state -- which is the difference between a battery pack lasting a few hours (continuous operation) and one lasting weeks to months (PIR-triggered).

Power sourceRough runtime estimateNotes
5V wall adapterIndefiniteSimplest option if outlet access is available near the mounting spot
18650 Li-ion cell + boost converterDays to a couple weeksNeeds a boost converter to bring 3.7V up to a stable 5V
Battery pack (multiple 18650s or a power bank)Weeks to a couple monthsScales roughly linearly with capacity; diminishing returns past a certain pack size due to self-discharge
Solar panel + battery bufferEffectively indefiniteAdds real complexity -- charge controller, panel sizing for your climate -- but removes the recharge cycle entirely

These numbers vary meaningfully with trigger frequency, so a driveway that sees 100 triggers a day burns through a battery noticeably faster than a quiet side gate seeing 5. Worth logging actual trigger counts for the first week of a real deployment before committing to a battery size for the long term.

18650 battery pack with boost converter, one of several power options for an untethered PIR camera deployment

Weatherproofing for Outdoor Mounting

Neither the ESP32-CAM nor the HC-SR501 is weather-rated out of the box -- both need an enclosure for anything mounted outdoors beyond a covered porch. The PIR sensor specifically needs its dome exposed to the air for accurate detection, which rules out fully sealing it behind solid plastic or glass; a vented enclosure with the PIR dome poking through a fitted hole, sealed around the edge, is the common approach. The camera lens similarly needs a clear, ideally slightly recessed opening to avoid rain sitting directly on the lens surface and distorting captures until it evaporates or is wiped away.

PIR camera mounted in a vented weatherproof enclosure, with the sensor dome and camera lens both exposed through fitted openings

Combining PIR with Face Detection for Fewer Wasted Captures

A plain PIR trigger fires on any motion -- a passing car, a cat, a tree branch in wind -- not specifically a person. For a build where only human presence matters, pairing this PIR-wake pattern with the face detection covered in the ESP32-CAM Face Detection guide adds a second filtering stage: PIR wakes the board cheaply and coarsely, and rather than saving every PIR-triggered frame automatically, a brief face-detection check runs first and only saves the photo if a face is actually present in it.

This costs a bit more awake time per trigger -- running detection takes longer than a single immediate capture -- but meaningfully cuts down on saved photos of nothing in particular, which matters more on a battery-powered build where every wasted SD write is also a wasted battery cycle. It's a natural next step once the basic PIR-triggered version here is working reliably.

Common Mistakes

Skipping the PIR settling time during testing. Triggers in the first minute after power-up are often false readings from the sensor still stabilizing, not a real problem with the wiring or code.

Using a polling loop instead of deep sleep for a battery build. This defeats the entire purpose -- continuous polling keeps the board fully powered, which a battery-powered deployment can't sustain for long.

Mounting the PIR facing directly toward expected motion instead of across it. Head-on approach is detected less reliably than motion crossing the sensor's field of view.

Choosing a GPIO for OUT that isn't RTC-capable. Not every GPIO can wake the ESP32 from deep sleep -- GPIO 13 works on this board specifically because it's both free and RTC-capable; a different pin might compile fine and simply never wake the board.

Sealing the PIR sensor's dome behind solid material in an enclosure. It needs open air exposure to detect infrared changes -- fully sealing it behind glass or solid plastic significantly reduces or eliminates detection range.

Troubleshooting

SymptomLikely CauseFix
Board never wakes on motionWrong GPIO selected for OUT, or not RTC-capableConfirm GPIO 13 wiring; verify the pin is genuinely RTC-capable on your board revision
Constant false triggersSensitivity too high, or a heat source in viewLower the sensitivity potentiometer; check for AC units, sun-heated surfaces, or moving foliage in the field of view
First photo after power-up is unusablePIR still stabilizing in its first 30-60 secondsExpected behavior -- ignore triggers in the first minute after power-on
Runtime much shorter than expected on batteryTrigger rate higher than estimated, or a code path keeping the board awake longer than necessaryLog actual trigger counts for a few days; check for anything preventing esp_deep_sleep_start() from being reached
Photo captured but very dark or motion-blurredMotion caught mid-frame with default exposure settingsConsider a locked, slightly faster exposure setting if capturing fast-moving subjects specifically

Frequently Asked Questions

How far can the PIR sensor reliably detect motion? The HC-SR501 is rated up to about 7 meters at maximum sensitivity, though real-world reliable range is often closer to 4-5 meters once accounting for mounting angle and environmental factors.

Can I use this with WiFi enabled for remote alerts instead of just SD storage? Yes -- the same wake-capture-sleep pattern works fine with a WiFi connection and a Telegram or HTTP push added into captureAndSave(), though initializing WiFi on every wake adds a few seconds and meaningfully more power draw per trigger compared to the SD-only version here.

Does cold weather affect PIR sensor performance? Somewhat -- PIR sensors detect the infrared difference between a moving subject and the background, and a very cold background (winter) can actually make a warm-bodied subject easier to detect, while a hot summer day can reduce the contrast and range slightly.

Is there a minimum time between triggers I should worry about? The code above has no artificial cooldown -- each trigger fully wakes, captures, and sleeps again independently. For a high-traffic area generating a lot of very close-together triggers, adding a stored "last trigger time" check (similar to the alert cooldown pattern in the security camera project) can reduce redundant near-identical captures.

Will the PIR sensor still work if partially exposed through a window rather than mounted outdoors? Poorly, in most cases -- glass blocks a significant portion of the infrared wavelengths PIR sensors depend on, so a sensor shooting through window glass typically loses most of its effective range even if the camera itself sees through the glass perfectly fine.

Can multiple PIR sensors feed into one ESP32-CAM for wider coverage? Yes, in principle -- wire a second sensor's OUT to another RTC-capable GPIO and use esp_sleep_enable_ext1_wakeup() instead of ext0, which supports waking on multiple pins. Each wake still only tells you a sensor triggered, not which one, unless the code checks pin states immediately after waking to distinguish them.

Where to Go Next

For a WiFi-connected version with instant phone alerts instead of SD-only logging, the ESP32-CAM Face Detection Security Camera covers the Telegram integration pattern this project could be extended with. For general SD storage details, see Photo Capture & microSD Storage.

Q&A is currently disabled site-wide.

Related projects