Skip to content

Programming

Pseudocode:

Algorithm:
1. Initialize system and set up Wi-Fi connection.
2. Continuously monitor ultrasonic sensor for motion detection.
3. When motion detected:
   - Trigger notification alert.
   - Capture image using XIAO_ESP32 camera module.
   - Transmit captured image to mobile app.
4. Provide option for user to view captured images and receive alerts and also sound playback for visitors.

Initialize Wi-Fi Connection with Cam WebServer

  • To Set up cam webserver, go to Arduino example as shown in the image and give your wifi crendentials and select right camera model.

alt text

#include "esp_camera.h"
#include <WiFi.h>
#define CAMERA_MODEL_XIAO_ESP32S3 
#include "camera_pins.h"
// ===========================
// Enter your WiFi credentials
// ===========================
const char* ssid = "Fablab";
const char* password = "JnwSf!2023";

void startCameraServer();
void setupLedFlash(int pin);

void setup() {
  Serial.begin(115200);
  Serial.setDebugOutput(true);
  Serial.println();

  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.frame_size = FRAMESIZE_UXGA;
  config.pixel_format = PIXFORMAT_JPEG; // for streaming
  //config.pixel_format = PIXFORMAT_RGB565; // for face detection/recognition
  config.grab_mode = CAMERA_GRAB_WHEN_EMPTY;
  config.fb_location = CAMERA_FB_IN_PSRAM;
  config.jpeg_quality = 12;
  config.fb_count = 1;

  // if PSRAM IC present, init with UXGA resolution and higher JPEG quality
  //                      for larger pre-allocated frame buffer.
  if(config.pixel_format == PIXFORMAT_JPEG){
    if(psramFound()){
      config.jpeg_quality = 10;
      config.fb_count = 2;
      config.grab_mode = CAMERA_GRAB_LATEST;
    } else {
      // Limit the frame size when PSRAM is not available
      config.frame_size = FRAMESIZE_SVGA;
      config.fb_location = CAMERA_FB_IN_DRAM;
    }
  } else {
    // Best option for face detection/recognition
    config.frame_size = FRAMESIZE_240X240;
#if CONFIG_IDF_TARGET_ESP32S3
    config.fb_count = 2;
#endif
  }

#if defined(CAMERA_MODEL_ESP_EYE)
  pinMode(13, INPUT_PULLUP);
  pinMode(14, INPUT_PULLUP);
#endif

  // camera init
  esp_err_t err = esp_camera_init(&config);
  if (err != ESP_OK) {
    Serial.printf("Camera init failed with error 0x%x", err);
    return;
  }

  sensor_t * s = esp_camera_sensor_get();
  // initial sensors are flipped vertically and colors are a bit saturated
  if (s->id.PID == OV3660_PID) {
    s->set_vflip(s, 1); // flip it back
    s->set_brightness(s, 1); // up the brightness just a bit
    s->set_saturation(s, -2); // lower the saturation
  }
  // drop down frame size for higher initial frame rate
  if(config.pixel_format == PIXFORMAT_JPEG){
    s->set_framesize(s, FRAMESIZE_QVGA);
  }

#if defined(CAMERA_MODEL_M5STACK_WIDE) || defined(CAMERA_MODEL_M5STACK_ESP32CAM)
  s->set_vflip(s, 1);
  s->set_hmirror(s, 1);
#endif

#if defined(CAMERA_MODEL_ESP32S3_EYE)
  s->set_vflip(s, 1);
#endif

// Setup LED FLash if LED pin is defined in camera_pins.h
#if defined(LED_GPIO_NUM)
  setupLedFlash(LED_GPIO_NUM);
#endif

  WiFi.begin(ssid, password);
  WiFi.setSleep(false);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");

  startCameraServer();

  Serial.print("Camera Ready! Use 'http://");
  Serial.print(WiFi.localIP());
  Serial.println("' to connect");
}

void loop() {
  // Do nothing. Everything is done in another task by the web server
  delay(10000);
}

Continuously monitor ultrasonic sensor for motion detection With all other functionality

When motion detected: - Trigger notification alert. - Capture image using XIAO_ESP32 camera module. - Transmit captured image to mobile app. - Provide option for user to view captured images and receive

#include "esp_camera.h"
#include <WiFi.h>
#define CAMERA_MODEL_XIAO_ESP32S3 // Has PSRAM
#include "camera_pins.h"
#define BLYNK_PRINT Serial
/* Fill in information from Blynk Device Info here */
#define BLYNK_TEMPLATE_ID "TMPL3GrjQ3f1a"
#define BLYNK_TEMPLATE_NAME "SangayFA24"
#define BLYNK_AUTH_TOKEN "Sz2zq8TPagtaKguH3LhxaWlMGhrWVZR_"
#include<DFRobotDFPlayerMini.h>
#include<SoftwareSerial.h>

SoftwareSerial mySerial(3,4);
DFRobotDFPlayerMini myDFPlayer;

#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>
// #include <BlynkSimpleEsp8266.h>

#define LED 1
#define BUTTON 2
#define trigPin 8    // TRIG pin
#define echoPin 7    // ECHO pin
#define BUTTON_Play 9

#define BUTTON_Play2 6

#define BUTTON_Play3 5

int buttonPushCounter = 0;  // counter for the number of button presses
int buttonState = 0;        // current state of the button
int lastButtonState = 0;    // previous state of the button

int buttonPushCounter_2 = 0;  // counter for the number of button presses
int buttonState_2 = 0;        // current state of the button
int lastButtonState_2 = 0;    // previous state of the button

int buttonPushCounter_3 = 0;  // counter for the number of button presses
int buttonState_3 = 0;        // current state of the button
int lastButtonState_3 = 0;    // previous state of the button

String my_Local_IP;

const char* ssid = "Fablab";
const char* password = "JnwSf!2023";
int count = 0;
void startCameraServer();
void setupLedFlash(int pin);

BlynkTimer timer;

boolean flag = true;
float duration_us, distance_cm;

unsigned long previousMillis = 0;  //will store last time LED was blinked
const long period = 10000;         // period at which to blink in ms

void notifyOnButtonPress()
{
  unsigned long currentMillis = millis(); // store the current time
  if (currentMillis - previousMillis >= period || flag == true) { // check if 1 minute passed
    previousMillis = currentMillis;   // save the last time you blinked the LED
    Serial.println("Alert! : Some at the Door");
    Blynk.logEvent("Intruder_Alert","Intruder Alert in Home");
    flag = false;
  }
}

void capture(){

  digitalWrite(LED,HIGH);
  uint32_t number = random(40000000);
  // Blynk.notify("Someone is at the door..");
  Serial.println("http://"+my_Local_IP+"/capture?_cb="+ (String)number);
  Blynk.setProperty(V1, "urls", "http://"+my_Local_IP+"/capture?_cb="+(String)number);
  delay(1000);
  digitalWrite(LED,LOW);

}

bool flag_play = true;
bool flag_play_2 = true;
bool flag_play_3 = true;

void playAudio(int x){
  Serial.println("Play: ");

  myDFPlayer.volume(30);  // Set volume value (0~30).
  if(x == 1 && flag_play_2 == true){
    Serial.println("Play 1 ");
    myDFPlayer.play(1);     // Play the first mp3 file on the SD card.
    flag_play_2 = false;
  }
   if(x == 2 && flag_play == true){
    Serial.println("Play 2 ");
    myDFPlayer.play(2);     // Play the first mp3 file on the SD card.
    flag_play = false;
  }
  if(x == 3 && flag_play_3 == true){
    Serial.println("Play 3 ");
    myDFPlayer.play(3);     // Play the first mp3 file on the SD card.
    flag_play = false;
  }

}

void setup() {
  Serial.begin(115200);
  pinMode(LED,OUTPUT);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);

  pinMode(BUTTON_Play2, INPUT);

  mySerial.begin(9600);
  // playAudio();
  if (!myDFPlayer.begin(mySerial)) {  // Use software serial to communicate with mp3.
    Serial.println(F("Unable to begin:"));
    Serial.println(F("1. Please recheck the connection!"));
    Serial.println(F("2. Please insert the SD card!"));
    while (true);
  }

  Blynk.begin(BLYNK_AUTH_TOKEN, ssid, password);

  Serial.setDebugOutput(true);
  Serial.println();

  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.frame_size = FRAMESIZE_UXGA;
  config.pixel_format = PIXFORMAT_JPEG; // for streaming
  //config.pixel_format = PIXFORMAT_RGB565; // for face detection/recognition
  config.grab_mode = CAMERA_GRAB_WHEN_EMPTY;
  config.fb_location = CAMERA_FB_IN_PSRAM;
  config.jpeg_quality = 12;
  config.fb_count = 1;

  // if PSRAM IC present, init with UXGA resolution and higher JPEG quality
  //                      for larger pre-allocated frame buffer.
  if(config.pixel_format == PIXFORMAT_JPEG){
    if(psramFound()){
      config.jpeg_quality = 10;
      config.fb_count = 2;
      config.grab_mode = CAMERA_GRAB_LATEST;
    } else {
      // Limit the frame size when PSRAM is not available
      config.frame_size = FRAMESIZE_SVGA;
      config.fb_location = CAMERA_FB_IN_DRAM;
    }
  } else {
    // Best option for face detection/recognition
    config.frame_size = FRAMESIZE_240X240;
#if CONFIG_IDF_TARGET_ESP32S3
    config.fb_count = 2;
#endif
  }

#if defined(CAMERA_MODEL_ESP_EYE)
  pinMode(13, INPUT_PULLUP);
  pinMode(14, INPUT_PULLUP);
#endif

  // camera init
  esp_err_t err = esp_camera_init(&config);
  if (err != ESP_OK) {
    Serial.printf("Camera init failed with error 0x%x", err);
    return;
  }

  sensor_t * s = esp_camera_sensor_get();
  // initial sensors are flipped vertically and colors are a bit saturated
  if (s->id.PID == OV3660_PID) {
    s->set_vflip(s, 1); // flip it back
    s->set_brightness(s, 1); // up the brightness just a bit
    s->set_saturation(s, -2); // lower the saturation
  }
  // drop down frame size for higher initial frame rate
  if(config.pixel_format == PIXFORMAT_JPEG){
    s->set_framesize(s, FRAMESIZE_QVGA);
  }

#if defined(CAMERA_MODEL_M5STACK_WIDE) || defined(CAMERA_MODEL_M5STACK_ESP32CAM)
  s->set_vflip(s, 1);
  s->set_hmirror(s, 1);
#endif

#if defined(CAMERA_MODEL_ESP32S3_EYE)
  s->set_vflip(s, 1);
#endif

// Setup LED FLash if LED pin is defined in camera_pins.h
#if defined(LED_GPIO_NUM)
  setupLedFlash(LED_GPIO_NUM);
#endif

  WiFi.begin(ssid, password);
  WiFi.setSleep(false);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");

  startCameraServer();

  Serial.print("Camera Ready! Use 'http://");
  Serial.print(WiFi.localIP());
  my_Local_IP = WiFi.localIP().toString();
  Serial.println("' to connect");

  timer.setInterval(5000L,notifyOnButtonPress); 

}

void pauseAudio(){
  myDFPlayer.disableLoopAll(); //stop loop all mp3 files.
  delay(1000);
}


void loop() {
  Blynk.run();
  timer.run();

  buttonState = digitalRead(BUTTON_Play);
  buttonState_2 = digitalRead(BUTTON_Play2);

  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  duration_us = pulseIn(echoPin, HIGH);

  distance_cm = 0.017 * duration_us;

  Serial.print("distance: ");
  Serial.print(distance_cm);
  Serial.println(" cm");

  if(digitalRead(BUTTON) == HIGH){
    capture();
  }

  // compare the buttonState to its previous state
  if (buttonState != lastButtonState) {
    // if the state has changed, increment the counter
    if (buttonState == HIGH) {
      // if the current state is HIGH then the button went from off to on:
      playAudio(2);
    } else {
      // if the current state is LOW then the button went from on to off:
      Serial.println("off");
      pauseAudio();
      flag_play = true;
    }
    // Delay a little bit to avoid bouncing
    delay(50);
  }

  lastButtonState = buttonState;

  // compare the buttonState to its previous state
  if (buttonState_2 != lastButtonState_2) {
    // if the state has changed, increment the counter

    if (buttonState_2 == HIGH) {
      // if the current state is HIGH then the button went from off to on:
      playAudio(1);
    } else {
      // if the current state is LOW then the button went from on to off:
      Serial.println("off");
      pauseAudio();
      flag_play_2 = true;
    }
    // Delay a little bit to avoid bouncing
    delay(50);
  }

  lastButtonState_3 = buttonState_3;

  if (buttonState_3 != lastButtonState_3) {
    // if the state has changed, increment the counter

    if (buttonState_3 == HIGH) {
      // if the current state is HIGH then the button went from off to on:
      playAudio(3);
    } else {
      // if the current state is LOW then the button went from on to off:
      Serial.println("off");
      pauseAudio();
      flag_play_3 = true;
    }
    // Delay a little bit to avoid bouncing
    delay(50);
  }

  lastButtonState_3 = buttonState_3;


  if(distance_cm <= 100){
    notifyOnButtonPress();
  }

  delay(1000);

}