ESP32 & IoT24 October 202615 mins

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.

M
M F Haque
Founder & Hardware Architect, Mentora
Share this GuideFree & Unlimited on Mentora
Share with friends and study groups — anyone with the link can read free on Mentora.
Key Strategic Takeaways
  • 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

| |

+-------------------------+ |

textcode snippet
|                         |                 |
textcode snippet
|      +------------------+                 |

| | 1000uF 16V |

| | Capacitor |

textcode snippet
|      +---[ +  - ]-------+                 |
textcode snippet
|                         |                 |

| +---------------------+-----------------+----+

textcode snippet
|   |                     |                 |    |

+-->| [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 |

textcode snippet
|  PIR SENSOR |                  |      FTDI PROGRAMMER  |
textcode snippet
|   (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

}

``

Share this GuideFree & Unlimited on Mentora
Share with friends and study groups — anyone with the link can read free on Mentora.
Microcontroller Hub: ESP32-CAM (AI-Thinker Board with OV2640 Sensor)Actuators & Sensors: HC-SR501 / AM312 PIR Motion Sensor, Built-in High-Power Flash LED (GPIO 4)Cloud & Messaging: Telegram Bot API via Secure HTTPS (WiFiClientSecure)Target Search Intent: "ESP32 CAM telegram motion alert photo", "ESP32 CAM brownout detector was triggered fix", "ESP32 CAM camera init failed 0x20001" Token-Gated Asset

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.

Access Fee
₹49₹199

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.

ESP32_CAM_Telegram_Motion_Alert.ino(Locked Asset)
Token-Gated
#include<Wire.h>
#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.

Fritzing & CAD Schematics Pack.FZZ & .PDF

Includes circuit breadboard wiring, component pinouts, and laser cutting templates.

Stuck on Hardware or Code? Book a 1-on-1 Video SessionLive Mentor

Screen-share or show your breadboard to M. F. Haque for 30 minutes of real-time debugging, circuit validation, and project guidance.

Peer Review & Rewards

Review This Build & Claim a Free ₹49 Token

Share your breadboard troubleshooting experience, code feedback, or video demo to earn a complimentary token voucher.

5/5 - Outstanding Build

Have a Reward Voucher?

Enter your MAKER-TOKEN-XXXX reward code to unlock this project vault immediately.

Ambassador Program

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!

Frequently Asked Questions

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.

Live Evening Cohort • Interactive Micro-Cohort (Max 6–8 Kids)

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.

Tuesday & Thursday • 5:30 PM – 6:30 PM IST • Monthly After-School Pass: ₹800/mo ₹1,500
Topics:#ESP32#ESP32 & IoT#Circuit Wiring#Arduino Code#DIY Electronics#ESP32-CAM Telegram alert#ESP32 camera motion detection#ESP32-CAM PIR sensor wiring#ESP32-CAM brownout fix#IoT smart security camera