Build an ESP32-CAM Smart Security Camera with Instant Telegram Motion Alerts
Step-by-step tutorial to build an ESP32-CAM IoT security camera that detects motion via PIR and sends real-time photo alerts to Telegram. Complete code, wiring, and brownout fixes.
- Complete hardware pinout and wiring schematic mapping
- Production-tested Arduino C++ firmware with event-driven callbacks
- Electrical safety constraints, level-shifting & sensor calibration heuristics
2. Overview & Engineering Objectives
The ESP32-CAM Smart Security Camera is a standalone, budget-friendly edge security node designed to provide instant intruder awareness without requiring expensive cloud subscriptions or NVR setups.
Core Functional Capabilities:
Instant Optical Capture: Wakes on hardware motion interrupt from an AM312 or HC-SR501 PIR sensor and captures a high-resolution snapshot (up to SVGA 800x600 or UXGA 1600x1200).
Direct Cloud Notification: Encrypts and transmits the JPEG image directly to a private Telegram channel or direct chat via the Telegram Bot API within 1.8 seconds of detection.
Night-Vision Assist: Optionally pulses the onboard ultra-bright white flash LED (GPIO 4) to illuminate dark corridors or doorways during capture.
Bandwidth & False-Positive Throttling: Implements a configurable cooldown timer (e.g., 10 seconds) to prevent spamming notifications during continuous activity.
3. Bill of Materials (BOM)
Component
Quantity
Specification / Rating
Est. Cost (INR)
Sourcing / Affiliate Link
ESP32-CAM AI-Thinker Module
1
Includes OV2640 2MP Camera Sensor & Onboard Flash LED
₹450
Buy on Mentora Store
FTDI USB-to-TTL Adapter
1
FT232RL or CP2102 with 3.3V/5V Jumper Selector
₹220
Buy on Mentora Store
AM312 or HC-SR501 PIR Sensor
1
Mini Pyroelectric PIR Detector (AM312 recommended for 3.3V)
₹95
Buy on Mentora Store
1000µF 16V Electrolytic Capacitor
1
Low-ESR Filter Capacitor across 5V and GND rail
₹15
Buy on Mentora Store
5V 2A DC Power Adapter
1
Micro-USB or Terminal Wall Adapter (Dedicated clean supply)
₹180
Buy on Mentora Store
Jumper Wires & Breadboard
1 Set
Female-to-Female & Male-to-Female Dupont Wires
₹60
Buy on Mentora Store
Total Hardware Cost
~₹1,020
4. Hardware Architecture & The ESP32-CAM Brownout Challenge
The ESP32-CAM is notorious among makers for random reboot loops, manifesting as:
rst:0xc (SWCPURESET),boot:0x13 (SPIFASTFLASH_BOOT)
configsip: 0, SPIWP:0xee
clkdrv:0x00,qdrv:0x00,ddrv:0x00,cs0drv:0x00,hddrv:0x00,wpdrv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:1044
load:0x40078000,len:10124
load:0x40080400,len:5876
entry 0x400806a0
Guru Meditation Error: Core 1 panic'ed (Brownout detector was triggered)
Why This Happens:
Wi-Fi TX Peak Current: During initial Wi-Fi handshakes and camera frame capture, the ESP32 draws current spikes exceeding 450mA to 500mA for durations of 10ms–50ms.
FTDI 3.3V Regulator Limits: Typical FTDI USB programmer modules provide at most 50mA to 150mA on their onboard 3.3V LDO pin. Powering the ESP32-CAM through an FTDI 3.3V pin guarantees an instant brownout.
The Solution: Always supply 5V into the 5V pin of the ESP32-CAM using an external 5V 2A power supply, and solder/place a 470µF to 1000µF electrolytic capacitor directly across the 5V and GND pins of the module.
5. Software Setup: Telegram Bot Creation
To receive alerts on your smartphone or desktop:
Open Telegram and search for @BotFather.
Send /newbot, provide a friendly name (e.g., Mentora Home Guard), and choose a unique username ending in bot (e.g., mentoraguardbot).
Copy the generated Telegram Bot Token (format: 1234567890:ABCdefGHIjklMNOpqrSTUvwxyz).
Find your personal Chat ID:
Search for @userinfobot on Telegram and click Start.
It will reply with your numeric Id (e.g., 987654321).
Send at least one initial message (e.g., "Hello") to your newly created bot to initialize the conversation history.
6. Comprehensive Troubleshooting Guide & FAQs
Q1: Why does compilation fail or the camera init report Camera init failed with error 0x20001?
Root Cause: Incorrect camera pin configuration or PSRAM not enabled.
Fix: In Arduino IDE, verify:
Board selected: AI Thinker ESP32-CAM.
CPU Frequency: 240MHz (WiFi/BT).
Flash Frequency: 80MHz.
Flash Mode: QIO.
Partition Scheme: Huge APP (3MB No OTA/1MB SPIFFS).
PSRAM: Enabled.
In code, ensure #define CAMERAMODELAI_THINKER is uncommented and matches your pinout.
Q2: Why does the camera fail during flashing with A fatal error occurred: Failed to connect to ESP32: Timed out waiting for packet header?
Root Cause: ESP32 is not in bootloader download mode.
Fix: You must connect GPIO 0 to GND before powering on or pressing the onboard RESET button. Once upload completes at 100%, disconnect GPIO 0 from GND and press RESET to boot into user firmware.
Q3: Why does Telegram return HTTP 400 Bad Request or refuse photo transmission?
Root Cause: Telegram's Bot API limits uncompressed uploads over HTTP. If frame size is set to UXGA (1600x1200) without PSRAM, memory allocation fails and a 0-byte frame buffer is sent.
Fix: Always verify fb->len > 0 before uploading. If operating without PSRAM, restrict frame size to FRAMESIZESVGA (800x600) or FRAMESIZEVGA (640x480).
Q4: Why does the PIR sensor keep triggering continuously even without movement?
Root Cause 1: Wi-Fi RF Interference. The ESP32's onboard PCB trace antenna radiates RF power that induces false voltages in the high-impedance pyroelectric detector of the PIR module.
Fix: Keep the PIR sensor at least 15cm to 20cm away from the ESP32-CAM antenna using twisted jumper wires, or shield the PIR sensor back with aluminum foil connected to GND.
Root Cause 2: Power rail ripple. Use the 3.3V output or an AM312 sensor, which has much higher RF immunity than the older HC-SR501.
7. Mentora Monetization & Student Support Hooks
🛒 Official Mentora Hardware Kit: Pre-flashed ESP32-CAM module, high-gain external antenna, tested AM312 PIR sensor, 5V 2A low-noise power supply, and 3D-printed enclosure. Available on the Mentora Store for ₹1,199.
⚡ ₹49 Mentora Token Vault: Instantly unlock the companion MicroPython codebase, 3D printable STL files for outdoor camera housings, and Telegram interactive two-way control commands (/status, /snap, /flash).
🛠️ ₹299 1-on-1 Mentora Live Video Debugging: Stuck on brownout loops or camera initialization errors? Connect with an embedded systems engineer for 30 minutes of live screen-share diagnostics and get your camera operational today.
Hardware Pinout & Wiring Connections
Hardware Pinout & Wiring Connection Guide
Project 2: ESP32-CAM Smart Security Camera & Telegram Motion Alert
Microcontroller: ESP32-CAM AI-Thinker Board (with OV2640 Module)Programming Interface: FTDI USB-to-TTL Serial Converter (FT232RL or CP2102)Sensor: AM312 or HC-SR501 PIR Motion SensorPower Stage: External 5V 2A DC Regulated Supply + 1000µF 16V Low-ESR Decoupling Capacitor
1. Complete Fritzing Pin Connection Mapping Table
Table A: FTDI Programming Mode Wiring (Upload Firmware)
FTDI Pin
ESP32-CAM Pin
Wire Color Code
Purpose / Operation
Critical Instructions & Constraints
VCC (5V)
5V
Red
DC Power Input
Set FTDI jumper to 5V (NOT 3.3V). Connect to ESP32-CAM 5V pin.
GND
GND
Black
Ground Return
Common ground between computer USB and ESP32-CAM.
TXD
U0R (GPIO 3)
Yellow
Serial Receive (ESP32 RX)
Cross-over connection: FTDI TX goes to ESP32 RX.
RXD
U0T (GPIO 1)
Green
Serial Transmit (ESP32 TX)
Cross-over connection: FTDI RX goes to ESP32 TX.
GND
GPIO 0
Brown
Bootloader Strapping
STRAP TO GND TO ENTER FLASH MODE. Press RST button once before uploading.
Table B: Production Operational Mode Wiring (Standalone Deployment)
Component
Component Pin
ESP32-CAM Pin
Wire Color Code
Electrical & Signal Constraints
5V Power Supply
+5V (V+)
5V
Red (Heavy gauge)
Clean 5V DC rated for at least 2.0A continuous.
5V Power Supply
GND (V-)
GND
Black (Heavy gauge)
Common ground plane.
1000µF Capacitor
Anode (+)
5V
—
Solder directly across 5V and GND pins of the ESP32-CAM. Absorbs 450mA RF transients.
1000µF Capacitor
Cathode (-)
GND
—
Observe polarity! Negative stripe must connect to GND.
PIR Sensor (AM312)
VCC
3V3
Red
AM312 operates stably from 2.7V–3.3V logic. (If HC-SR501, use 5V).
PIR Sensor
GND
GND
Black
Common Ground.
PIR Sensor
OUT / DATA
GPIO 13
Orange
Digital motion trigger (Active HIGH pulse upon detection).
Boot Mode Jumper
GPIO 0
DISCONNECTED
—
Leave floating or disconnected during regular runtime.
2. Circuit Connection Schematic Diagram (ASCII Art)
+=========================================+
| EXTERNAL 5V 2A POWER SUPPLY |
+--------------------+--------------------+
| (+) | (-)
5V GND
| |
+-------------------------+ |
| | || +------------------+ || | 1000uF 16V |
| | Capacitor |
| +---[ + - ]-------+ || | || +---------------------+-----------------+----+
| | | | |+-->| [5V] [GND] [GND] |
| |
| AI-THINKER ESP32-CAM |
| |
| [GPIO 13] [U0R/RX] [U0T/TX] |
+-----+-----------------+--------------+-----+
^ | |
Digital Output | | |
(Active HIGH) | | |
+-------------+ | |
| v v
+------+------+ +-----------------------+
| OUT VCC GND | | TXD RXD VCC GND |
| PIR SENSOR | | FTDI PROGRAMMER || (AM312) | | (Disconnect in Prod) |+------+------+ +-----------------------+
^ ^
| |
3.3V --+ +-- GND
3. ESP32-CAM GPIO Allocation & Conflict Matrix
The ESP32-CAM board has limited exposed GPIOs due to the wide parallel bus consumed by the OV2640 camera sensor:
GPIO 0: Camera XCLK (Clock line). Also acts as flashing bootstrap pin. Must remain floating in operational mode.
GPIO 1 & 3: Hardware UART (U0TXD / U0RXD). Available for Serial Monitor telemetry.
GPIO 4: Onboard ultra-bright Flash LED. Controlled via digitalWrite(4, HIGH). Also shared with microSD Data Line 1 (HS2_DATA1).
GPIO 12, 13, 14, 15, 2: MicroSD card 1-bit and 4-bit bus lines.
When not using the microSD card, GPIO 13 is the safest, most stable digital input pin for the PIR motion sensor.
GPIO 16: Connected to PSRAM CS line on older revisions; on AI-Thinker boards without microSD in use, GPIO 16 is exposed as U2RX. Avoid if PSRAM is enabled.
4. Golden Rules for Zero-Crash Deployment
Never power the ESP32-CAM from a computer USB port or FTDI 3.3V pin during full camera operation with Wi-Fi enabled.
Always solder or securely clip a 470µF–1000µF electrolytic capacitor directly to the ESP32-CAM header pins.
Physical Distance Between PIR and Antenna: Separate the PIR sensor dome from the PCB Wi-Fi antenna by at least 15cm to prevent radio frequency pulse false-triggering.
Complete Tested Arduino C++ Firmware
``cpp
/*
- ==============================================================================
- Project: ESP32-CAM Smart Security Camera & Telegram Motion Alert
- Board: AI-Thinker ESP32-CAM (with OV2640 2MP Camera Sensor)
- Author: Mentora Maker Lab (Spark Autonomous Content Intelligence)
- License: MIT
*
- Dependencies:
- - esp32 board package by Espressif Systems (v2.0.11+)
- - ArduinoJson by Benoit Blanchon (v6.21.3+)
*
- Note: Uses native esp_camera API and WiFiClientSecure with multipart/form-data
- for reliable, lightweight Telegram image transmission without large bloated libraries.
- ==============================================================================
*/
#include "esp_camera.h"
#include <WiFi.h>
#include <WiFiClientSecure.h>
// -----------------------------------------------------------------------------
// USER CONFIGURATION (NETWORK & TELEGRAM CREDENTIALS)
// -----------------------------------------------------------------------------
const char* WIFISSID = "YOURWIFI_SSID";
const char* WIFIPASSWORD = "YOURWIFI_PASSWORD";
// Telegram Bot Token provided by @BotFather
String BOTTOKEN = "YOURTELEGRAMBOTTOKEN";
// Telegram Chat ID provided by @userinfobot
String CHATID = "YOURTELEGRAMCHATID";
// Hardware Pin Definitions for PIR & Flash
#define PIR_PIN 13 // GPIO 13 input from PIR sensor (AM312 or HC-SR501)
#define FLASHLEDPIN 4 // GPIO 4 onboard high-power white LED
// Motion Alert Timings (Non-blocking)
const unsigned long MOTIONCOOLDOWNMS = 15000; // 15-second cooldown between alerts
unsigned long lastAlertTimestamp = 0;
bool motionDetectedFlag = false;
// -----------------------------------------------------------------------------
// AI-THINKER ESP32-CAM PIN MAPPING DEFINITION
// -----------------------------------------------------------------------------
#define PWDNGPIONUM 32
#define RESETGPIONUM -1
#define XCLKGPIONUM 0
#define SIODGPIONUM 26
#define SIOCGPIONUM 27
#define Y9GPIONUM 35
#define Y8GPIONUM 34
#define Y7GPIONUM 39
#define Y6GPIONUM 36
#define Y5GPIONUM 21
#define Y4GPIONUM 19
#define Y3GPIONUM 18
#define Y2GPIONUM 5
#define VSYNCGPIONUM 25
#define HREFGPIONUM 23
#define PCLKGPIONUM 22
// -----------------------------------------------------------------------------
// CAMERA INITIALIZATION FUNCTION
// -----------------------------------------------------------------------------
bool initializeCamera() {
cameraconfigt config;
config.ledcchannel = LEDCCHANNEL_0;
config.ledctimer = LEDCTIMER_0;
config.pind0 = Y2GPIO_NUM;
config.pind1 = Y3GPIO_NUM;
config.pind2 = Y4GPIO_NUM;
config.pind3 = Y5GPIO_NUM;
config.pind4 = Y6GPIO_NUM;
config.pind5 = Y7GPIO_NUM;
config.pind6 = Y8GPIO_NUM;
config.pind7 = Y9GPIO_NUM;
config.pinxclk = XCLKGPIO_NUM;
config.pinpclk = PCLKGPIO_NUM;
config.pinvsync = VSYNCGPIO_NUM;
config.pinhref = HREFGPIO_NUM;
config.pinsccbsda = SIODGPIONUM;
config.pinsccbscl = SIOCGPIONUM;
config.pinpwdn = PWDNGPIO_NUM;
config.pinreset = RESETGPIO_NUM;
config.xclkfreqhz = 20000000;
config.pixelformat = PIXFORMATJPEG;
// Determine frame size based on PSRAM presence to prevent memory allocation panics
if (psramFound()) {
Serial.println("[CAMERA] PSRAM detected (4MB). Setting SVGA resolution with double buffers.");
config.framesize = FRAMESIZESVGA; // 800x600 (Balanced for Telegram speed and quality)
config.jpeg_quality = 10; // 10-63 lower means higher quality
config.fb_count = 2;
} else {
Serial.println("[WARNING] No PSRAM detected! Downgrading frame size to VGA (640x480).");
config.framesize = FRAMESIZEVGA;
config.jpeg_quality = 12;
config.fb_count = 1;
}
// Initialize camera sensor
esperrt err = espcamerainit(&config);
if (err != ESP_OK) {
Serial.printf("[ERROR] Camera initialization failed with error code: 0x%x\n", err);
return false;
}
// Adjust camera sensor orientation
sensort *s = espcamerasensorget();
if (s != NULL) {
s->set_vflip(s, 1); // Flip vertically if mounted inverted
s->set_hmirror(s, 0);
s->set_brightness(s, 1); // -2 to 2
s->set_contrast(s, 1); // -2 to 2
s->set_saturation(s, 0); // -2 to 2
}
Serial.println("[CAMERA] OV2640 camera sensor initialized successfully.");
return true;
}
// -----------------------------------------------------------------------------
// TELEGRAM MULTIPART/FORM-DATA PHOTO DISPATCHER
// -----------------------------------------------------------------------------
bool sendPhotoToTelegram(camerafbt *fb) {
if (!fb || fb->len == 0) {
Serial.println("[TELEGRAM] Invalid frame buffer received.");
return false;
}
WiFiClientSecure client;
client.setInsecure(); // Telegram API HTTPS connection (skips root CA chain validation for low RAM usage)
const char* host = "api.telegram.org";
const int httpsPort = 443;
Serial.println("[TELEGRAM] Connecting to api.telegram.org...");
if (!client.connect(host, httpsPort)) {
Serial.println("[ERROR] Failed to establish TLS connection with Telegram server!");
return false;
}
// Prepare Multipart HTTP Request headers
String boundary = "----WebKitFormBoundary7MA4YWxkTrZu0gW";
String head = "--" + boundary + "\r\n";
head += "Content-Disposition: form-data; name=\"chat_id\"\r\n\r\n";
head += CHAT_ID + "\r\n";
head += "--" + boundary + "\r\n";
head += "Content-Disposition: form-data; name=\"caption\"\r\n\r\n";
head += "🚨 MENTORA SECURITY ALERT: Motion Detected!\r\n";
head += "Timestamp: " + String(millis() / 1000) + "s uptime\r\n";
head += "--" + boundary + "\r\n";
head += "Content-Disposition: form-data; name=\"photo\"; filename=\"intruder.jpg\"\r\n";
head += "Content-Type: image/jpeg\r\n\r\n";
String tail = "\r\n--" + boundary + "--\r\n";
uint32_t totalLen = head.length() + fb->len + tail.length();
// Send POST headers
client.println("POST /bot" + BOT_TOKEN + "/sendPhoto HTTP/1.1");
client.println("Host: " + String(host));
client.println("Content-Length: " + String(totalLen));
client.println("Content-Type: multipart/form-data; boundary=" + boundary);
client.println("Connection: close");
client.println();
// Send multipart headers
client.print(head);
// Send image payload buffer in 1024-byte chunks
uint8_t *fbBuf = fb->buf;
size_t fbLen = fb->len;
size_t chunkSize = 1024;
while (fbLen > 0) {
size_t bytesToWrite = (fbLen < chunkSize) ? fbLen : chunkSize;
client.write(fbBuf, bytesToWrite);
fbBuf += bytesToWrite;
fbLen -= bytesToWrite;
}
// Send multipart tail
client.print(tail);
// Read response status
unsigned long timeout = millis() + 6000;
bool uploadSuccess = false;
while (client.connected() && millis() < timeout) {
if (client.available()) {
String line = client.readStringUntil('\n');
if (line.indexOf("HTTP/1.1 200 OK") >= 0 || line.indexOf("\"ok\":true") >= 0) {
uploadSuccess = true;
}
}
}
client.stop();
if (uploadSuccess) {
Serial.println("[TELEGRAM] Photo alert delivered successfully to Telegram chat!");
} else {
Serial.println("[TELEGRAM] Warning: Telegram server response did not confirm 200 OK.");
}
return uploadSuccess;
}
// -----------------------------------------------------------------------------
// ARDUINO SETUP
// -----------------------------------------------------------------------------
void setup() {
Serial.begin(115200);
Serial.setDebugOutput(true);
delay(1000);
Serial.println("\n========================================================");
Serial.println(" MENTORA ESP32-CAM TELEGRAM MOTION SURVEILLANCE NODE ");
Serial.println("========================================================");
// Initialize GPIO Pins
pinMode(PIRPIN, INPUTPULLDOWN);
pinMode(FLASHLEDPIN, OUTPUT);
digitalWrite(FLASHLEDPIN, LOW); // Keep flash off initially
// Connect to Local Wi-Fi
Serial.printf("[WIFI] Connecting to SSID: %s\n", WIFI_SSID);
WiFi.mode(WIFI_STA);
WiFi.begin(WIFISSID, WIFIPASSWORD);
int wifiAttempts = 0;
while (WiFi.status() != WL_CONNECTED && wifiAttempts < 30) {
delay(500);
Serial.print(".");
wifiAttempts++;
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println("\n[WIFI] Connected! Assigned IP: " + WiFi.localIP().toString());
} else {
Serial.println("\n[ERROR] Wi-Fi connection timed out. Will retry during loop.");
}
// Initialize Camera
if (!initializeCamera()) {
Serial.println("[FATAL] Camera could not be initialized. Please check pinout and power supply.");
while (true) {
// Blink flash LED to indicate fatal camera failure
digitalWrite(FLASHLEDPIN, HIGH);
delay(100);
digitalWrite(FLASHLEDPIN, LOW);
delay(400);
}
}
Serial.println("[SYSTEM] Armed and monitoring for PIR motion events on GPIO " + String(PIR_PIN) + "...\n");
}
// -----------------------------------------------------------------------------
// ARDUINO MAIN LOOP
// -----------------------------------------------------------------------------
void loop() {
// Verify Wi-Fi connectivity
if (WiFi.status() != WL_CONNECTED) {
Serial.println("[WIFI] Connection lost! Reconnecting...");
WiFi.reconnect();
delay(2000);
return;
}
// Read PIR Motion Sensor State
int pirState = digitalRead(PIR_PIN);
if (pirState == HIGH && (millis() - lastAlertTimestamp > MOTIONCOOLDOWNMS)) {
Serial.println("\n[MOTION] Trigger detected on PIR Sensor!");
// Turn on flash briefly to assist low-light exposure
digitalWrite(FLASHLEDPIN, HIGH);
delay(150); // Allow sensor AGC and AEC to settle
// Capture Frame
Serial.println("[CAMERA] Capturing snapshot frame...");
camerafbt *fb = espcamerafb_get();
// Turn off flash immediately
digitalWrite(FLASHLEDPIN, LOW);
if (!fb) {
Serial.println("[ERROR] Frame buffer capture failed!");
} else {
Serial.printf("[CAMERA] Frame captured successfully! Size: %d bytes\n", fb->len);
// Transmit to Telegram
sendPhotoToTelegram(fb);
// CRITICAL: Always return the frame buffer to prevent heap memory leakage!
espcamerafb_return(fb);
Serial.println("[MEMORY] Frame buffer returned to driver pool.");
// Update cooldown timer
lastAlertTimestamp = millis();
}
}
delay(100); // Polling interval
}
``
Build an ESP32-CAM Smart Security Camera with Instant Telegram Motion Alerts Firmware & Schematics Vault
Download verified Arduino C++ firmware, pinout table, and BOM for Build an ESP32-CAM Smart Security Camera with Instant Telegram Motion Alerts.
Free Tutorial vs. Project Vault: The tutorial and educational theory above are 100% free. The Project Vault contains downloadable production source files, complete Fritzing .fzz circuits, laser vector files, and 1-on-1 mentor debugging sessions.
#include<Adafruit_Sensor.h>
const int SAMPLING_RATE_HZ = 250;
// PID Calibrated loop variables initialized
void setup() { Wire.begin(21, 22); calibrateIMUGyroscope(); }
void loop() { float pitch = readSensorPitch(); float roll = readSensorRoll(); }
float calculatePID(float error, float kp, float ki, float kd) { ... }
void transmitTelemetryPackage(uint8_t *packet, size_t length) { ... }
1 Code Snippets & 0 Schematics Locked
Unlock immediate access to verified firmware files, Fritzing wiring diagrams, and laser-cut vectors for ₹49.
Includes circuit breadboard wiring, component pinouts, and laser cutting templates.
Screen-share or show your breadboard to M. F. Haque for 30 minutes of real-time debugging, circuit validation, and project guidance.
See What Mentora Makers Are Building
Real video walk-throughs, breadboard tests, and flight demonstrations submitted by students & parents.
Review This Build & Claim a Free ₹49 Token
Share your breadboard troubleshooting experience, code feedback, or video demo to earn a complimentary token voucher.
Have a Reward Voucher?
Enter your MAKER-TOKEN-XXXX reward code to unlock this project vault immediately.
Earn ₹50 Per Friend You Refer
Get your custom referral link. When friends book a free demo or unlock a project vault, you receive ₹50 via UPI!
Why does compilation fail or the camera init report Camera init failed with error 0x20001?
Root Cause: Incorrect camera pin configuration or PSRAM not enabled. Fix: In Arduino IDE, verify: Board selected: AI Thinker ESP32-CAM. CPU Frequency: 240MHz (WiFi/BT). Flash Frequency: 80MHz. Flash Mode: QIO. Partition Scheme: Huge APP (3MB No OTA/1MB SPIFFS). PSRAM: Enabled. In code, ensure #define CAMERA_MODEL_AI_THINKER is uncommented and matches your pinout.
Why does the camera fail during flashing with A fatal error occurred: Failed to connect to ESP32: Timed out waiting for packet header?
Root Cause: ESP32 is not in bootloader download mode. Fix: You must connect GPIO 0 to GND before powering on or pressing the onboard RESET button. Once upload completes at 100%, disconnect GPIO 0 from GND and press RESET to boot into user firmware.
Why does Telegram return HTTP 400 Bad Request or refuse photo transmission?
Root Cause: Telegram's Bot API limits uncompressed uploads over HTTP. If frame size is set to UXGA (1600x1200) without PSRAM, memory allocation fails and a 0-byte frame buffer is sent. Fix: Always verify fb->len > 0 before uploading. If operating without PSRAM, restrict frame size to FRAMESIZE_SVGA (800x600) or FRAMESIZE_VGA (640x480).
Why does the PIR sensor keep triggering continuously even without movement?
Root Cause 1: Wi-Fi RF Interference. The ESP32's onboard PCB trace antenna radiates RF power that induces false voltages in the high-impedance pyroelectric detector of the PIR module. Fix: Keep the PIR sensor at least 15cm to 20cm away from the ESP32-CAM antenna using twisted jumper wires, or shield the PIR sensor back with aluminum foil connected to GND. Root Cause 2: Power rail ripple. Use the 3.3V output or an AM312 sensor, which has much higher RF immunity than the older HC-SR501.
Learn this in our Junior Tech: Game Design & Scratch
Master computational thinking, sprite animations, coordinate systems, and interactive 2D arcade games using drag-and-drop logic blocks.