ESP32-CAM Motion Detection & Snapshot-to-Cloud
Two Ways to Detect Motion
- PIR sensor (hardware-based): a cheap PIR module wired to a GPIO pin, triggering capture only on actual detected motion — lower CPU overhead, works even if the camera isn't actively streaming.
- Frame differencing (software-based): comparing consecutive camera frames for pixel changes — no extra hardware needed, but meaningfully more CPU-intensive on a chip that's already busy with camera + WiFi.
For most projects, PIR + camera is the more reliable and simpler combination — this guide focuses on that approach.
Wiring a PIR Sensor
ESP32-CAM has limited free GPIO (most pins are committed to the camera interface) — GPIO 13 or GPIO 12 are commonly available depending on your specific board's exact pinout; check your board's silkscreen/documentation, since AI-Thinker variants can differ slightly.
- PIR VCC → 5V (most PIR modules are 5V tolerant even on 3.3V logic boards, but check your specific module)
- PIR GND → GND
- PIR OUT → chosen GPIO pin
Basic Motion-Triggered Capture Code
#define PIR_PIN 13 void setup() { pinMode(PIR_PIN, INPUT); // ... standard camera init from the setup guide ... } void loop() { if (digitalRead(PIR_PIN) == HIGH) { camera_fb_t* fb = esp_camera_fb_get(); if (fb) { uploadToCloud(fb->buf, fb->len); esp_camera_fb_return(fb); } delay(5000); // debounce — avoid spamming captures during continued motion } }Uploading to Cloud Storage
Simplest reliable option: HTTP POST to a webhook/storage endpoint. If you're already running Home Assistant (see the HA setup guide), it can receive and store these directly, or trigger a notification with the image attached, without needing separate third-party cloud storage at all:
void uploadToCloud(uint8_t* imageData, size_t len) { HTTPClient http; http.begin("http://your-ha-instance:8123/api/webhook/motion_snapshot"); http.addHeader("Content-Type", "image/jpeg"); http.POST(imageData, len); http.end(); }Reducing False Triggers
- PIR sensors are sensitive to temperature changes, not just motion — direct sunlight hitting the sensor, or placement near HVAC vents, causes false triggers unrelated to actual movement.
- Most PIR modules have onboard sensitivity and delay-time potentiometers — tune these physically rather than only in software; a well-tuned sensor reduces the software debounce burden significantly.
Battery/Low-Power Considerations
If this is running on battery rather than continuous power, put the ESP32 into deep sleep between PIR triggers using the PIR output as a wake source (esp_sleep_enable_ext0_wakeup) — see the dedicated ESP32 deep sleep guide for the full pattern. Continuous polling as shown above is fine for mains-powered installs but drains a battery fast.
Related Guides
- How to Use the ESP32-CAM: Video Streaming, Motion Detection, and Time-Lapse
- ESP32-CAM Complete Setup Guide: Flashing, FTDI Wiring, First Boot
- ESP32-CAM Streaming Server: MJPEG, RTSP, and Home Assistant Integration
- ESP32-CAM AI Vision: Face Detection & TensorFlow Lite on Device
- ESP32-CAM as a Doorbell/Mailbox Camera with Notifications