Convert an affordable ESP32-CAM module into a smart security hub. This project features high-resolution streaming, motion-triggered snapshots saved directly to a MicroSD card, and a web interface to monitor your home from any device on your network.
Traditional security cameras can be expensive and compromise privacy. With this ESP32-CAM solution, you have full control over your data. The camera remains in low-power mode until the PIR sensor detects movement, at which point it captures an image and initiates a live stream.
By saving snapshots to the onboard SD card, your security footage stays within your home network. No cloud subscriptions or external servers required.
| Part Name | Qty |
|---|---|
| ESP32-CAM (AI-Thinker Model) | 1 |
| HC-SR501 PIR Motion Sensor | 1 |
| MicroSD Card (16GB or 32GB) | 1 |
| FT232RL FTDI USB-to-Serial Adapter | 1 |
The ESP32-CAM lacks a USB port, so we use an FTDI adapter for programming. The PIR sensor triggers motion alerts on GPIO 13.
| Peripheral | Device Pin | ESP32-CAM Pin | Notes |
|---|---|---|---|
| PIR Sensor | OUT | GPIO 13 | Motion trigger |
| Serial Adapter | TX / RX | RX0 / TX0 | For programming |
| Power | VCC / GND | 5V / GND | Use stable 5V supply |
| Prog Mode | GPIO 0 | GND | Link during flash only |
#include "esp_camera.h"
#include <WiFi.h>
const char* ssid = "YOUR_WIFI_SSID";
const char* password = "YOUR_WIFI_PASSWORD";
#define PIR_PIN 13
void setup() {
Serial.begin(115200);
pinMode(PIR_PIN, INPUT);
// Camera configuration (AI-Thinker Pins)
camera_config_t config;
config.ledc_channel = LEDC_CHANNEL_0;
config.ledc_timer = LEDC_TIMER_0;
config.pin_d0 = 5; config.pin_d1 = 18;
config.pin_d2 = 19; config.pin_d3 = 21;
config.pin_d4 = 36; config.pin_d5 = 39;
config.pin_d6 = 34; config.pin_d7 = 35;
config.pin_xclk = 0; config.pin_pclk = 22;
config.pin_vsync = 25; config.pin_href = 23;
config.pin_sscb_sda = 26; config.pin_sscb_scl = 27;
config.pin_pwdn = 32; config.pin_reset = -1;
config.xclk_freq_hz = 20000000;
config.pixel_format = PIXFORMAT_JPEG;
esp_camera_init(&config);
WiFi.begin(ssid, password);
}
void loop() {
if (digitalRead(PIR_PIN) == HIGH) {
Serial.println("Motion Detected!");
camera_fb_t * fb = esp_camera_fb_get();
// Logic to save fb->buf to SD card goes here
esp_camera_fb_return(fb);
delay(5000); // Cooldown
}
}