This is an old revision of the document!


ESP 32 Security system to detect movement and capture picture

  • Author: Felicia Saghin
  • Email: felicia.saghin@stud.acs.pub.ro
  • Master: SRIC

Introduction

In today’s connected world, real-time security monitoring at home or in small offices has become both practical and affordable. This project delivers a lightweight IoT door-security solution by combining an ESP32-CAM module with a Hall-effect sensor. Whenever the door opens, the sensor immediately signals the ESP32-CAM to capture a high-resolution image. That image is then uploaded to Firebase Storage, and its publicly accessible URL is written to Firebase Realtime Database. Simultaneously, Twilio’s API is invoked to send an SMS to your smartphone. Finally, a web gallery hosted on Firebase displays the latest snapshot instantly, giving you secure and remote visibility of every entry event.

Context

Diagram In many homes and small offices, it’s hard to know in real time if someone has opened a door while you’re away. Traditional locks only log locally or require you to check in person. This project closes that gap by combining a Hall-effect sensor, an ESP32-CAM, cloud storage and instant SMS alerts.

Key features:

  • Instant detection of door opening via a Hall-effect sensor mounted on the door frame
  • Automated photo capture by ESP32-CAM when the sensor toggles
  • Cloud storage of each snapshot in Firebase Storage
  • Real-time SMS notifications via Twilio with a link to the gallery
  • Live web monitoring through a Firebase-hosted photo gallery

When the door swings open, the Hall sensor’s output changes state. The ESP32-CAM immediately takes a JPEG, uploads it to Firebase Storage, and writes it into Realtime Database. A Twilio API call then sends you an SMS alert containing the gallery URL. Meanwhile, your web app—hosted on Firebase Hosting and listening to the database—updates instantly to show the new image.

Hardware

Hardware Components

  • ESP32-CAM (OV2640 camera module)
  • Hall-effect sensor (A3144)
  • Permanent magnet
  • 5 V USB power supply (or power bank)
  • ESP32-CAM-MB shield
  • Jumper wires & mounting tape/screws

Hardware Circuit

Connecting Components

Hall-effect Sensor (A3144) Mounted on the door frame. Detects the magnet fixed to the door as it swings past: output goes LOW when the magnet is within 5–10 mm (door closed), and HIGH when it moves away (door open).

  • VCC → ESP32-CAM 3V3
  • GND → ESP32-CAM GND
  • OUT → ESP32-CAM GPIO13 (`INPUT_PULLUP`)

ESP32-CAM Module Handles image capture, Firebase upload, and Twilio notifications.

  • Power → VIN pin → +5 V from your battery pack (e.g. USB power-bank or Li-Po + boost converter)
  • Ground → GND → battery pack GND
  • (If you’re using the ESP32-CAM-MB shield instead of wiring VIN/GND, just plug your battery’s USB cable into its micro-USB port.)*

USB-Serial Adapter *(only if not using the on-board USB shield)* Required to flash code to the ESP32-CAM.

  • Adapter TX → ESP32-CAM U0R0 (GPIO3)
  • Adapter RX → ESP32-CAM U0T0 (GPIO1)
  • Adapter +5 V → ESP32-CAM VIN
  • Adapter GND → ESP32-CAM GND

Permanent Magnet Mounted on the door so its north pole passes within 5–10 mm of the Hall sensor when the door is closed. No wiring required.

Software Design

I used VS Code with the PlatformIO IDE extension.

Key Project Features

- Firebase Realtime Database Instant data synchronization between the ESP32-CAM device and the web dashboard.

- Image Processing Automated JPEG capture, Base64 encoding, and seamless cloud upload.

- SMS Notifications (Twilio) Instant SMS alerts via Twilio API with direct gallery links.

- Responsive Web Dashboard Mobile-friendly interface for real-time image monitoring and history review.

- Hall Sensor Integration Magnetic door-open detection with software debouncing to ensure one capture per event.

- PSRAM Optimization Advanced PSRAM configuration on ESP32-CAM for reliable image buffering and processing.

- Modern Web Technologies Built with HTML5, CSS3, JavaScript ES6+, Firebase Hosting, and fetch API for a smooth user experience.

Code Snippets

bool uploadImageToFirebase(camera_fb_t* fb, const char* source) {
    if (!fb || !fb->buf || fb->len == 0) {
        return false;
    }
    
    // Convert to base64 encoding
    size_t required_len = ((fb->len + 2) / 3) * 4 + 1;
    char* base64_buffer = (char*)malloc(required_len);
    
    size_t olen = 0;
    int ret = mbedtls_base64_encode((unsigned char*)base64_buffer, 
                                   required_len, &olen, fb->buf, fb->len);
    
    // Create JSON payload and upload to Firebase
    FirebaseJson imageData;
    imageData.set("timestamp", millis());
    imageData.set("source", source);
    imageData.set("size", (int)fb->len);
    imageData.set("base64", String(base64_buffer));
    
    String path = String("/images/") + String(millis());
    
    if (Firebase.RTDB.setJSON(&fbdo, path.c_str(), &imageData)) {
        // Send SMS notification via Twilio
        String smsMessage = "📸 Intruder detected! Check: https://proiect-iot-feli.web.app/";
        sendTwilioSMS(smsMessage.c_str());
        return true;
    }
    
    free(base64_buffer);
    return false;
}
#define HALL_SENSOR_PIN 12
const unsigned long DEBOUNCE_DELAY = 500; // 500ms debounce

void checkHallSensor() {
    static int lastState = HIGH;
    static unsigned long lastTriggerTime = 0;
    static bool initialized = false;
    
    // Initialize sensor state on first run
    if (!initialized) {
        lastState = digitalRead(HALL_SENSOR_PIN);
        initialized = true;
        return;
    }
    
    int currentState = digitalRead(HALL_SENSOR_PIN);
    unsigned long currentTime = millis();
    
    // Check for state change with debouncing
    if (currentState != lastState && 
        (currentTime - lastTriggerTime) > DEBOUNCE_DELAY) {
        
        if (currentState == LOW) {
            Serial.println("🧲 Magnet detected - capturing photo");
        } else {
            Serial.println("🧲 Magnet removed - capturing photo");
        }
        
        capturePhotoFromSensor();
        lastTriggerTime = currentTime;
        lastState = currentState;
    }
}
const firebaseConfig = {
  apiKey: "AIzaSyB_GqKEayiItvWUcP9b0PLF8xKqtqJBjXM",
  authDomain: "proiect-iot-feli.firebaseapp.com",
  databaseURL: "https://proiect-iot-feli-default-rtdb.europe-west1.firebasedatabase.app",
  projectId: "proiect-iot-feli"
};

function initializeFirebase() {
  firebase.initializeApp(firebaseConfig);
  database = firebase.database();
  imagesRef = database.ref('images');
  
  // Set up real-time listener for new images
  setupRealtimeListener();
  loadImages();
}

function setupRealtimeListener() {
  imagesRef.on('child_added', function(snapshot) {
    const imageData = snapshot.val();
    displayImage(snapshot.key, imageData);
    updateStatus(`📸 New image detected at ${new Date().toLocaleTimeString()}`, 'new-image');
  });
}
bool sendTwilioSMS(const char* message) {
    if (!twilio) {
        Serial.println("❌ Twilio client not initialized");
        return false;
    }
    
    Serial.println("📱 Sending SMS notification...");
    String response;
    bool result = twilio->send_message(TO_PHONE_NUMBER, TWILIO_PHONE_NUMBER, message, response);
    
    if (result) {
        Serial.println("✅ SMS sent successfully");
        Serial.println("SMS Response:");
        Serial.println(response);
    } else {
        Serial.println("❌ SMS failed to send");
        Serial.printf("Error: %s\n", response.c_str());
    }
    
    return result;
}

Firebase

firebase_feli.jpeg

The entire application is deployed on Firebase Hosting and uses Firebase Realtime Database to coordinate data between the ESP32-CAM and the web dashboard. The database contains:

  • images/

A collection of timestamped entries, each holding the Base64-encoded JPEG and metadata (size, source).

  • latestImage

Stores the key of the most recent `images/{timestamp}` entry for quick access (optional).

  • notificationsEnabled

A Boolean flag to enable or disable SMS alerts on the fly.

All communication flows through the Realtime Database:

- ESP32-CAM writes a new child under `/images` on every door-open event. - Web dashboard listens for `child_added` and updates the UI in real time. - Toggles to `/notificationsEnabled` can be flipped by the user to mute alerts without redeploy.

Realtime Database Structure

Challenges

References

iothings/proiecte/2025sric/security-system-to_detect-movement-and-capture-image.1748504063.txt.gz · Last modified: 2025/05/29 10:34 by felicia.saghin
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0