Building a DIY security camera system with ESP32-CAM is one of the most practical IoT projects you can undertake. Commercial CCTV systems cost ₹10,000-50,000+ for a multi-camera setup, but with ESP32-CAM modules costing under ₹500 each, you can build a fully functional multi-camera NVR (Network Video Recorder) system for a fraction of the price — with the added benefit of complete control over your data and customisation options.
Table of Contents
- System Overview and Architecture
- Hardware Requirements
- Setting Up ESP32-CAM Modules
- Motion Detection and Alerts
- NVR Setup with Raspberry Pi
- Remote Viewing and Mobile Access
- Advanced Features: Face Detection and Zones
- Frequently Asked Questions
- Conclusion
System Overview and Architecture
DIY Security Camera Architecture:
[ESP32-CAM #1] --WiFi--> |
[ESP32-CAM #2] --WiFi--> |-- Home WiFi Router
[ESP32-CAM #3] --WiFi--> |
[ESP32-CAM #4] --WiFi--> |
|
[Raspberry Pi 4]
- Frigate NVR / MotionEye
- Motion detection
- Recording to USB HDD
- Telegram/Email alerts
|
[Remote Access]
- VPN (WireGuard)
- Mobile browser
Each ESP32-CAM module streams MJPEG video over WiFi. A Raspberry Pi running NVR software (Frigate, MotionEye, or ZoneMinder) captures these streams, performs motion detection, records video, and sends alerts. You can view live and recorded footage from any device on your network or remotely via VPN.
Hardware Requirements
Per Camera
- ESP32-CAM module: With OV2640 camera (2MP). ₹350-500.
- ESP32-CAM-MB: USB programming board for easy flashing. ₹100-150.
- 5V 2A power adapter: Reliable power is critical. ₹100-200.
- Weatherproof enclosure: For outdoor cameras. ₹100-300 (or 3D-printed).
- External antenna (optional): IPEX connector antenna for better WiFi range. ₹50-150.
NVR Server
- Raspberry Pi 4 (4GB): Handles 4-6 camera streams. ₹4,000-6,000.
- USB 3.0 HDD/SSD: 1-2 TB for recording storage. ₹3,000-5,000.
- MicroSD card: 32 GB Class 10 for Pi OS. ₹300-500.
- Ethernet cable: Wired connection to router for reliable streaming.
Setting Up ESP32-CAM Modules
Flash each ESP32-CAM with a streaming firmware. The simplest approach uses the Arduino IDE:
// ESP32-CAM Security Camera Firmware
#include "esp_camera.h"
#include
#include "esp_http_server.h"
// WiFi credentials
const char* ssid = "YourWiFi";
const char* password = "YourPassword";
// Camera pin configuration for AI Thinker ESP32-CAM
#define PWDN_GPIO_NUM 32
#define RESET_GPIO_NUM -1
#define XCLK_GPIO_NUM 0
#define SIOD_GPIO_NUM 26
#define SIOC_GPIO_NUM 27
#define Y9_GPIO_NUM 35
#define Y8_GPIO_NUM 34
#define Y7_GPIO_NUM 39
#define Y6_GPIO_NUM 36
#define Y5_GPIO_NUM 21
#define Y4_GPIO_NUM 19
#define Y3_GPIO_NUM 18
#define Y2_GPIO_NUM 5
#define VSYNC_GPIO_NUM 25
#define HREF_GPIO_NUM 23
#define PCLK_GPIO_NUM 22
void startCameraServer();
void setup() {
Serial.begin(115200);
// Camera configuration
camera_config_t config;
config.ledc_channel = LEDC_CHANNEL_0;
config.ledc_timer = LEDC_TIMER_0;
config.pin_d0 = Y2_GPIO_NUM;
config.pin_d1 = Y3_GPIO_NUM;
config.pin_d2 = Y4_GPIO_NUM;
config.pin_d3 = Y5_GPIO_NUM;
config.pin_d4 = Y6_GPIO_NUM;
config.pin_d5 = Y7_GPIO_NUM;
config.pin_d6 = Y8_GPIO_NUM;
config.pin_d7 = Y9_GPIO_NUM;
config.pin_xclk = XCLK_GPIO_NUM;
config.pin_pclk = PCLK_GPIO_NUM;
config.pin_vsync = VSYNC_GPIO_NUM;
config.pin_href = HREF_GPIO_NUM;
config.pin_sccb_sda = SIOD_GPIO_NUM;
config.pin_sccb_scl = SIOC_GPIO_NUM;
config.pin_pwdn = PWDN_GPIO_NUM;
config.pin_reset = RESET_GPIO_NUM;
config.xclk_freq_hz = 20000000;
config.pixel_format = PIXFORMAT_JPEG;
config.frame_size = FRAMESIZE_VGA; // 640x480
config.jpeg_quality = 12; // 0-63 (lower = better)
config.fb_count = 2;
esp_err_t err = esp_camera_init(&config);
if (err != ESP_OK) {
Serial.printf("Camera init failed: 0x%x", err);
return;
}
// Connect to WiFi
WiFi.begin(ssid, password);
WiFi.setSleep(false); // Disable WiFi sleep for stable streaming
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("nWiFi connected");
Serial.print("Camera Stream: http://");
Serial.print(WiFi.localIP());
Serial.println(":81/stream");
startCameraServer();
}
void loop() {
delay(10000);
}
After flashing, each camera provides an MJPEG stream at http://camera-ip:81/stream and a still image at http://camera-ip/capture.
Camera Placement Tips
- Height: Mount 2.5-3 metres high, angled 15-30 degrees downward
- Coverage: VGA resolution is adequate for 3-5 metre coverage area
- Lighting: ESP32-CAM has a built-in flash LED, but external IR LEDs provide better night coverage
- WiFi range: Maximum 10-15 metres through walls. Use external antenna for outdoor cameras
- Power: Use quality 5V 2A adapters. Voltage drops over long USB cables cause instability
Motion Detection and Alerts
The ESP32-CAM itself can perform basic motion detection by comparing consecutive frames:
// Simple motion detection on ESP32-CAM
#include "esp_camera.h"
camera_fb_t *prevFrame = NULL;
bool detectMotion(camera_fb_t *currentFrame) {
if (prevFrame == NULL) {
prevFrame = currentFrame;
return false;
}
int changedPixels = 0;
int totalPixels = currentFrame->len;
int threshold = 30; // Pixel change threshold
for (int i = 0; i len, currentFrame->len); i += 10) {
if (abs(currentFrame->buf[i] - prevFrame->buf[i]) > threshold) {
changedPixels++;
}
}
float changePercent = (changedPixels * 10.0 / totalPixels) * 100;
// Free previous frame and store current
esp_camera_fb_return(prevFrame);
prevFrame = currentFrame;
return changePercent > 5.0; // 5% of image changed
}
For more robust motion detection, offload processing to the Raspberry Pi NVR where you have more CPU power and can use algorithms like background subtraction and optical flow.
Telegram Alert Bot
Send motion-triggered snapshots to Telegram for instant mobile notifications:
// Send snapshot to Telegram when motion detected
#include
#include
#define BOT_TOKEN "YOUR_TELEGRAM_BOT_TOKEN"
#define CHAT_ID "YOUR_CHAT_ID"
WiFiClientSecure client;
UniversalTelegramBot bot(BOT_TOKEN, client);
void sendAlertPhoto() {
camera_fb_t *fb = esp_camera_fb_get();
if (fb) {
bot.sendPhotoByBinary(CHAT_ID, "image/jpeg",
fb->len, fb->buf, true, "Motion Detected!");
esp_camera_fb_return(fb);
}
}
NVR Setup with Raspberry Pi
Option 1: MotionEye (Easiest)
MotionEye provides a web-based interface for managing multiple camera streams:
# Install MotionEye on Raspberry Pi OS
sudo apt update
sudo apt install -y python3-pip python3-dev libcurl4-openssl-dev
sudo pip3 install motioneye
# Start MotionEye
sudo motioneye_init
# Access web interface at http://pi-ip:8765
# Default login: admin (no password)
Add each ESP32-CAM as a network camera using the MJPEG stream URL. Configure motion detection zones, recording schedules, and email/Telegram notifications through the web interface.
Option 2: Frigate (Advanced, AI-Based)
Frigate uses TensorFlow Lite for AI-powered object detection (person, car, animal) instead of simple motion detection. This dramatically reduces false alarms from wind, shadows, and animals.
# Install Frigate via Docker on Raspberry Pi
# Requires Pi 4 with 4GB+ RAM
docker run -d --name frigate
--restart unless-stopped
-v /path/to/config.yml:/config/config.yml
-v /media/recordings:/media/frigate
-p 5000:5000
ghcr.io/blakeblackshear/frigate:stable
Remote Viewing and Mobile Access
Access your cameras from anywhere using a VPN:
# Install WireGuard VPN on Raspberry Pi
sudo apt install wireguard
# Generate keys
wg genkey | tee privatekey | wg pubkey > publickey
# Configure /etc/wireguard/wg0.conf
[Interface]
PrivateKey =
Address = 10.0.0.1/24
ListenPort = 51820
[Peer]
PublicKey =
AllowedIPs = 10.0.0.2/32
# Enable and start
sudo systemctl enable wg-quick@wg0
sudo systemctl start wg-quick@wg0
Install the WireGuard app on your phone, configure the peer, and you can access your NVR dashboard and camera streams from anywhere. This is more secure than exposing your cameras to the public internet.
Advanced Features: Face Detection and Zones
The ESP32-S3 can run basic face detection on-device using Espressif’s human face detection model. For more advanced recognition, stream to the Raspberry Pi and use OpenCV or DeepFace for identification.
Other advanced features you can implement:
- Motion zones: Define specific areas of the frame to monitor (ignore trees, focus on doors)
- Scheduled recording: Record only during specific hours (night-only, away-from-home)
- Time-lapse: Capture one frame per minute for a time-lapse of the day
- Object counting: Count people entering/leaving for occupancy tracking
- Integration with Home Assistant: Trigger lights, alarms, or locks based on camera events
Frequently Asked Questions
How many cameras can one ESP32-CAM WiFi network handle?
A typical home WiFi router handles 4-6 ESP32-CAM streams comfortably at VGA resolution. Beyond 6 cameras, network congestion causes frame drops. Use a dedicated WiFi access point for cameras or switch to wired Ethernet (using an Ethernet module with ESP32).
What is the video quality of ESP32-CAM?
The OV2640 sensor captures up to 1600×1200 (UXGA) stills and 640×480 (VGA) video at ~12 FPS over WiFi. Quality is acceptable for security purposes at short distances (3-5 metres) but does not match commercial IP cameras. For higher quality, consider using Raspberry Pi with USB cameras.
Can ESP32-CAM work outdoors in Indian weather?
The ESP32-CAM itself operates at -40 to +85°C, but needs protection from rain, dust, and direct sunlight. Use a weatherproof enclosure (IP65+ rated) and ensure adequate ventilation for heat dissipation. Avoid pointing the camera at direct sunlight, which can damage the sensor.
How much storage do I need for recording?
At VGA resolution with motion-only recording, expect ~500 MB to 1 GB per camera per day. Continuous recording uses 2-4 GB per camera per day. A 1 TB drive stores approximately 30-60 days of 4-camera recordings with motion detection.
Is this system legal in India?
Installing security cameras on your own property is legal in India. You must display a notice informing visitors that CCTV is in operation. Do not point cameras at public roads, neighbours’ properties, or areas where privacy is expected (bathrooms, changing rooms). Audio recording has additional legal restrictions.
Conclusion
A DIY security camera system with ESP32-CAM modules offers remarkable value — 4 cameras with motion detection, NVR recording, and remote access for under ₹5,000 in total hardware cost. While it does not match commercial systems in video quality or reliability, it is more than adequate for home monitoring, workshop surveillance, and learning about computer vision and IoT.
Start with one camera, get comfortable with the setup, then expand to a multi-camera NVR. The skills you learn — embedded programming, networking, Linux administration, and video processing — are valuable far beyond this single project.
Get all the components you need at Zbotic’s online store and start building your DIY security system today.
Add comment