Differences

This shows you the differences between two versions of the page.

Link to this comparison view

iothings:proiecte:2025sric:security-system-to_detect-movement-and-capture-image [2025/05/29 09:11]
felicia.saghin [Context]
iothings:proiecte:2025sric:security-system-to_detect-movement-and-capture-image [2025/05/29 11:19] (current)
felicia.saghin [Introduction]
Line 7: Line 7:
  
 ====== Introduction ====== ====== 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.+In today’s connected world, real-time security monitoring at home or in small offices ​is 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 ​JPEG, which is then Base64-encoded ​and stored directly in Firebase Realtime Database. Simultaneously,​ Twilio’s API sends an SMS alert with a link to your live web gallery. A responsive dashboard ​hosted on Firebase ​Hosting listens for new entries in the database and displays each snapshot instantly, giving you secureremote visibility of every entry event.
 ====== Context ====== ====== Context ======
 __**Diagram**__ __**Diagram**__
-{{ :​iothings:​proiecte:​2025sric:​diagrama_feli.png |}}+{{ :​iothings:​proiecte:​2025sric:​diagrama_feli.png?550 |}}
 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. 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.
  
Line 60: Line 60:
 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.  ​ 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 ======+====== 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 === === Code Snippets ===
 +<​code>​
 +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;
 +}
 +</​code>​
 +
 +<​code>​
 +#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;​
 +    }
 +}
 +</​code>​
 +
 +<​code>​
 +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'​);​
 +  });
 +}
 +</​code>​
 +
 +<​code>​
 +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;
 +}
 +</​code>​
 +
 +==== Firebase ====
 +
 +{{ :​iothings:​proiecte:​2025sric:​firebase_feli.jpeg?​600 }}
 +
 +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.
 +
 +{{ :​iothings:​proiecte:​2025sric:​firebase2_feli.jpg?​600 }}
 +
  
 ====== Challenges ====== ====== Challenges ======
 +
 +One of the first hurdles I encountered was the ESP32-CAM’s limited onboard RAM. Capturing high-resolution JPEGs and then encoding them into Base64 demanded more memory than the 520 KB of SRAM could comfortably provide. To overcome this, I enabled the module’s external PSRAM and carefully managed my buffer allocations so that large image data would reside in PSRAM rather than exhausting the internal memory.
 +
 +Another issue came up when trying to upload these large images all at once: memory would sometimes fragment, or the HTTP requests would time out, leading to failed uploads. I solved this by breaking the Base64 encoding into smaller, manageable chunks, freeing each buffer immediately after use, and adding a simple retry mechanism for any failed network calls. This approach dramatically reduced memory spikes and improved upload reliability.
 +
 +Finally, my Hall-effect sensor occasionally produced multiple false “door open” triggers due to electrical noise or rapid swings near the magnet. Instead of acting on every glitch, I implemented a 500 ms software debounce in my sensor-reading routine. That way, once the sensor changes state, I wait half a second to ensure it’s stable before capturing a photo—guaranteeing exactly one image per genuine door-open event.  ​
  
 ====== References ====== ====== References ======
 +
 +https://​docs.espressif.com/​projects/​esp-idf/​en/​latest/​esp32/​hw-reference/​esp32/​get-started-wrover-kit.html
 +
 +https://​github.com/​mobizt/​Firebase-ESP-Client
 +
 +https://​github.com/​ademuri/​twilio-esp32-client
 +
 +https://​firebase.google.com/​docs/​database
 +
 +https://​docs.platformio.org/​en/​latest/​
 +
 +https://​github.com/​espressif/​esp32-camera
 +
 +https://​www.twilio.com/​docs/​sms/​api
 +
 +https://​firebase.google.com/​docs/​web/​setup
 +
 +https://​docs.espressif.com/​projects/​esp-idf/​en/​latest/​esp32/​api-guides/​external-ram.html
 +
 +https://​randomnerdtutorials.com/​esp32-cam-pinout-gpios/​
  
  
iothings/proiecte/2025sric/security-system-to_detect-movement-and-capture-image.1748499112.txt.gz · Last modified: 2025/05/29 09:11 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