s60sc / ESP32-CAM_MJPEG2SD

ESP32 Camera motion capture application to record JPEGs to SD card as AVI files and stream to browser as MJPEG. If a microphone is installed then a WAV file is also created. Files can be uploaded via FTP or downloaded to browser.
GNU Affero General Public License v3.0
922 stars 210 forks source link

Telegram integration possible? #293

Closed dr-garimella closed 11 months ago

dr-garimella commented 1 year ago

Your work is really excellent. Really, I don't have any words to express the gratitude.

Small doubt if possible:

Is it possible to access (open) the SD card files through telegram group.?!

Regards.

s60sc commented 1 year ago

It is something I will investigate in the future

FBMinis commented 1 year ago

Your work is really excellent. Really, I don't have any words to express the gratitude.

Small doubt if possible:

Is it possible to access (open) the SD card files through telegram group.?!

Regards.

In the meantime, I would suggest you try this application which send a photo and video to telegram when movement is detected by a PIR connected to GPIO13: https://github.com/jameszah/ESP32-CAM-Video-Telegram

dr-garimella commented 1 year ago

Your work is really excellent. Really, I don't have any words to express the gratitude. Small doubt if possible: Is it possible to access (open) the SD card files through telegram group.?! Regards.

In the meantime, I would suggest you try this application which send a photo and video to telegram when movement is detected by a PIR connected to GPIO13: https://github.com/jameszah/ESP32-CAM-Video-Telegram

Thank you for the response.

However, it doesn't work. Already tried the code. Videos are not sending properly. The code is good to send Photos alone.

FBMinis commented 1 year ago

However, it doesn't work. Already tried the code. Videos are not sending properly. The code is good to send Photos alone.

I have had 3 cameras working outside for over 12 months without a problem, they send video and photo when movement is detected.

dr-garimella commented 1 year ago

However, it doesn't work. Already tried the code. Videos are not sending properly. The code is good to send Photos alone.

I have had 3 cameras working outside for over 12 months without a problem, they send video and photo when movement is detected.

Ohh.! May be my hard luck. I tried many times and finally, left it.

FBMinis commented 1 year ago

I put this together, it sends a photo to Telegram when haveMotion() returns true, one photo per 10sec interval at most, so not to flood the connection.

#include <WiFi.h>
#include <AsyncTelegram2.h>
#include "esp_camera.h"
#include "soc/soc.h"           // Brownout error fix
#include "soc/rtc_cntl_reg.h"  // Brownout error fix

#include <WiFiClientSecure.h>
WiFiClientSecure secure_client;

const char* ssid = "***********";                                        // SSID WiFi network
const char* pass = "***********";                                        // Password  WiFi network
const char* token = "***********";  // Telegram token
int64_t userid = ***********;

// Timezone definition to get properly time from NTP server
#define MYTZ "WET0WEST,M3.5.0/1,M10.5.0"

AsyncTelegram2 myBot(secure_client);

#define PWDN_GPIO_NUM 32
#define RESET_GPIO_NUM -1
#define XCLK_GPIO_NUM 0
#define SIOD_GPIO_NUM 26
#define SIOC_GPIO_NUM 27

#define Y9_GPIO_NUM 35
#define Y8_GPIO_NUM 34
#define Y7_GPIO_NUM 39
#define Y6_GPIO_NUM 36
#define Y5_GPIO_NUM 21
#define Y4_GPIO_NUM 19
#define Y3_GPIO_NUM 18
#define Y2_GPIO_NUM 5
#define VSYNC_GPIO_NUM 25
#define HREF_GPIO_NUM 23
#define PCLK_GPIO_NUM 22

static camera_config_t camera_config = {
  .pin_pwdn = PWDN_GPIO_NUM,
  .pin_reset = RESET_GPIO_NUM,
  .pin_xclk = XCLK_GPIO_NUM,
  .pin_sscb_sda = SIOD_GPIO_NUM,
  .pin_sscb_scl = SIOC_GPIO_NUM,
  .pin_d7 = Y9_GPIO_NUM,
  .pin_d6 = Y8_GPIO_NUM,
  .pin_d5 = Y7_GPIO_NUM,
  .pin_d4 = Y6_GPIO_NUM,
  .pin_d3 = Y5_GPIO_NUM,
  .pin_d2 = Y4_GPIO_NUM,
  .pin_d1 = Y3_GPIO_NUM,
  .pin_d0 = Y2_GPIO_NUM,
  .pin_vsync = VSYNC_GPIO_NUM,
  .pin_href = HREF_GPIO_NUM,
  .pin_pclk = PCLK_GPIO_NUM,
  .xclk_freq_hz = 20000000,
  .ledc_timer = LEDC_TIMER_0,
  .ledc_channel = LEDC_CHANNEL_0,
  .pixel_format = PIXFORMAT_JPEG,  /* PIXFORMAT_RGB565, // for face detection/recognition */
  .frame_size = FRAMESIZE_VGA,
  .jpeg_quality = 12,
  .fb_count = 1,
  .fb_location = CAMERA_FB_IN_PSRAM,
  .grab_mode = CAMERA_GRAB_WHEN_EMPTY,
#if CONFIG_CAMERA_CONVERTER_ENABLED
  .conv_mode = CONV_DISABLE,  /*!< RGB<->YUV Conversion mode */
#endif
  //.sccb_i2c_port = 1          /*!< If pin_sccb_sda is -1, use the already configured I2C bus by number */
};

static esp_err_t init_camera() {

  // Best picture quality, but first frame requestes get lost sometimes (comment/uncomment to try)
  if (psramFound()) {
    Serial.println("PSRAM found");
    camera_config.fb_count = 2;
    camera_config.grab_mode = CAMERA_GRAB_LATEST;
  }

  //initialize the camera
  Serial.println("Camera init... ");
  esp_err_t err = esp_camera_init(&camera_config);

  if (err != ESP_OK) {
    delay(100);  // need a delay here or the next serial o/p gets missed
    Serial.printf("\n\nCRITICAL FAILURE: Camera sensor failed to initialise.\n\n");
    Serial.printf("A full (hard, power off/on) reboot will probably be needed to recover from this.\n");
    return err;
  } else {
    Serial.println("succeeded");

    // Get a reference to the sensor
    sensor_t* s = esp_camera_sensor_get();

    // Dump camera module, warn for unsupported modules.
    switch (s->id.PID) {
      case OV9650_PID: Serial.println("WARNING: OV9650 camera module is not properly supported, will fallback to OV2640 operation"); break;
      case OV7725_PID: Serial.println("WARNING: OV7725 camera module is not properly supported, will fallback to OV2640 operation"); break;
      case OV2640_PID: Serial.println("OV2640 camera module detected"); break;
      case OV3660_PID: Serial.println("OV3660 camera module detected"); break;
      default: Serial.println("WARNING: Camera module is unknown and not properly supported, will fallback to OV2640 operation");
    }
  }
  return ESP_OK;
}

size_t sendPicture(int64_t userid) {

  // Take picture with Camera and send to Telegram
  Serial.println("Camera capture requested");

  //  for (int j = 0; j < 4; j++) {
  //    camera_fb_t * newfb = esp_camera_fb_get();
  //    if (!newfb) {
  //      Serial.println("Camera Capture Failed");
  //    } else {
  //      //Serial.print("Pic, len="); Serial.print(newfb->len);
  //      //Serial.printf(", new fb %X\n", (long)newfb->buf);
  //      esp_camera_fb_return(newfb);
  //      delay(10);
  //    }
  //  }

  camera_fb_t* fb = esp_camera_fb_get();
  if (!fb) {
    Serial.println("Camera capture failed");
    return 0;
  }
  size_t len = fb->len;
  myBot.sendPhoto(userid, fb->buf, fb->len);

  // Clear buffer
  esp_camera_fb_return(fb);
  return len;
}

#define THIS_FRAME FRAMESIZE_QVGA // JPEG frames size to be retrieved
#define LAMP_PIN 4
bool debug = true;
uint8_t fsizePtr = THIS_FRAME; // framesize selection
uint8_t lightLevel; // Current ambient light level
uint8_t nightSwitch = 10; // white level % for night/day switching
uint8_t motionVal = 7; // motion sensitivity difference setting
bool haveMotion = false;
struct frameStruct {
  const char* frameSizeStr;
  const uint16_t frameWidth;
  const uint16_t frameHeight;
  const uint16_t defaultFPS;
  const uint8_t scaleFactor;
  const uint8_t sampleRate;
};
// sample factors, 5th arg is scaling factor (1..N), 6th arg is sample factor (0..3)
// indexed by frame size - needs to be consistent with sensor.h enum
extern const frameStruct frameData[] = {
  {"QQVGA", 160, 120, 25, 2, 1},
  {"n/a", 0, 0, 0, 0, 1},
  {"n/a", 0, 0, 0, 0, 1},
  {"HQVGA", 240, 176, 25, 3, 1},
  {"QVGA", 320, 240, 25, 3, 1},
  {"CIF", 400, 296, 25, 3, 1},
  {"VGA", 640, 480, 15, 3, 2},
  {"SVGA", 800, 600, 10, 3, 2},
  {"XGA", 1024, 768, 5, 3, 3},
  {"SXGA", 1280, 1024, 3, 3, 4},
  {"UXGA", 1600, 1200, 2, 6, 5}
};

bool checkMotion(camera_fb_t* fb, bool motionStatus);
bool isNight(uint8_t nightSwitch);

void setup_camera() {
  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_sscb_sda = SIOD_GPIO_NUM;
  config.pin_sscb_scl = SIOC_GPIO_NUM;
  config.pin_pwdn = PWDN_GPIO_NUM;
  config.pin_reset = RESET_GPIO_NUM;
  config.xclk_freq_hz = 10000000; // https://github.com/esphome/issues/issues/4191
  config.pixel_format = PIXFORMAT_JPEG;
  //init with high specs to pre-allocate larger buffers
  if (psramFound())
  {
    config.frame_size = FRAMESIZE_VGA; // FRAMESIZE_ + QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA
    config.jpeg_quality = 10;
    config.fb_count = 2;
  }
  else
  {
    config.frame_size = FRAMESIZE_VGA;
    config.jpeg_quality = 12;
    config.fb_count = 1;
  }

  // camera init
  esp_err_t err = ESP_FAIL;
  uint8_t retries = 2;
  while (retries && err != ESP_OK) {
    err = esp_camera_init(&config);
    if (err != ESP_OK) {
      Serial.printf("Camera init failed with error 0x%x", err);
      digitalWrite(PWDN_GPIO_NUM, 1);
      delay(100);
      digitalWrite(PWDN_GPIO_NUM, 0); // power cycle the camera (OV2640)
      retries--;
    }
  }
  if (err != ESP_OK) ESP.restart();
}

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

  WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);       // disable brownout detector

  // Initiate the camera module 
  // init_camera(); // alternative camera setup routine for testing purposes only
  setup_camera();

  // Start WiFi connection
  WiFi.begin(ssid, pass);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println(WiFi.localIP());

  // Sync time with NTP
  configTzTime(MYTZ, "time.google.com", "time.windows.com", "pool.ntp.org");
  secure_client.setCACert(telegram_cert);

  myBot.addSentCallback([](bool sent) {
    const char* res = sent ? "Picture delivered!" : "Error! Picture NOT delivered";
    if (!sent)
      myBot.sendTo(userid, res);
  }, 3000);

  // Set the Telegram bot properies
  myBot.setUpdateTime(1000);
  myBot.setTelegramToken(token);

  // Check if all things are ok
  Serial.print("\nTest Telegram connection... ");
  myBot.begin() ? Serial.println("OK") : Serial.println("NOK");

  //  Serial.println("\nSending Photo from CAM");
  //  if (sendPicture(userid))
  //    Serial.println("Picture sent successfull");
  //  else
  //    myBot.sendTo(userid, "Error, picture not sent.");
}

unsigned long lastPictureTime = 0;
const long interval = 10000; // wait 10sec between sending a new photo when there is movement

void loop() {
  camera_fb_t* fb = esp_camera_fb_get();

  if (fb) {
    haveMotion = checkMotion(fb, haveMotion);

    if (haveMotion) {
      haveMotion = false;

      Serial.println("movement detected");

      unsigned long currentTime = millis();

      if (currentTime - lastPictureTime >= interval) {
        lastPictureTime = currentTime;
        Serial.println("\nSending Photo from CAM");
        if (sendPicture(userid))
          Serial.println("Picture sent successfull");
        else
          myBot.sendTo(userid, "Error, picture not sent.");
      }
    }

    esp_camera_fb_return(fb);
  } else Serial.println("Failed to get frame");
  delay(100);
}
dr-garimella commented 1 year ago

I put this together, it sends a photo to Telegram when haveMotion() returns true, one photo per 10sec interval at most, so not to flood the connection.

#include <WiFi.h>
#include <AsyncTelegram2.h>
#include "esp_camera.h"
#include "soc/soc.h"           // Brownout error fix
#include "soc/rtc_cntl_reg.h"  // Brownout error fix

#include <WiFiClientSecure.h>
WiFiClientSecure secure_client;

const char* ssid = "***********";                                        // SSID WiFi network
const char* pass = "***********";                                        // Password  WiFi network
const char* token = "***********";  // Telegram token
int64_t userid = ***********;

// Timezone definition to get properly time from NTP server
#define MYTZ "WET0WEST,M3.5.0/1,M10.5.0"

AsyncTelegram2 myBot(secure_client);

#define PWDN_GPIO_NUM 32
#define RESET_GPIO_NUM -1
#define XCLK_GPIO_NUM 0
#define SIOD_GPIO_NUM 26
#define SIOC_GPIO_NUM 27

#define Y9_GPIO_NUM 35
#define Y8_GPIO_NUM 34
#define Y7_GPIO_NUM 39
#define Y6_GPIO_NUM 36
#define Y5_GPIO_NUM 21
#define Y4_GPIO_NUM 19
#define Y3_GPIO_NUM 18
#define Y2_GPIO_NUM 5
#define VSYNC_GPIO_NUM 25
#define HREF_GPIO_NUM 23
#define PCLK_GPIO_NUM 22

static camera_config_t camera_config = {
  .pin_pwdn = PWDN_GPIO_NUM,
  .pin_reset = RESET_GPIO_NUM,
  .pin_xclk = XCLK_GPIO_NUM,
  .pin_sscb_sda = SIOD_GPIO_NUM,
  .pin_sscb_scl = SIOC_GPIO_NUM,
  .pin_d7 = Y9_GPIO_NUM,
  .pin_d6 = Y8_GPIO_NUM,
  .pin_d5 = Y7_GPIO_NUM,
  .pin_d4 = Y6_GPIO_NUM,
  .pin_d3 = Y5_GPIO_NUM,
  .pin_d2 = Y4_GPIO_NUM,
  .pin_d1 = Y3_GPIO_NUM,
  .pin_d0 = Y2_GPIO_NUM,
  .pin_vsync = VSYNC_GPIO_NUM,
  .pin_href = HREF_GPIO_NUM,
  .pin_pclk = PCLK_GPIO_NUM,
  .xclk_freq_hz = 20000000,
  .ledc_timer = LEDC_TIMER_0,
  .ledc_channel = LEDC_CHANNEL_0,
  .pixel_format = PIXFORMAT_JPEG,  /* PIXFORMAT_RGB565, // for face detection/recognition */
  .frame_size = FRAMESIZE_VGA,
  .jpeg_quality = 12,
  .fb_count = 1,
  .fb_location = CAMERA_FB_IN_PSRAM,
  .grab_mode = CAMERA_GRAB_WHEN_EMPTY,
#if CONFIG_CAMERA_CONVERTER_ENABLED
  .conv_mode = CONV_DISABLE,  /*!< RGB<->YUV Conversion mode */
#endif
  //.sccb_i2c_port = 1          /*!< If pin_sccb_sda is -1, use the already configured I2C bus by number */
};

static esp_err_t init_camera() {

  // Best picture quality, but first frame requestes get lost sometimes (comment/uncomment to try)
  if (psramFound()) {
    Serial.println("PSRAM found");
    camera_config.fb_count = 2;
    camera_config.grab_mode = CAMERA_GRAB_LATEST;
  }

  //initialize the camera
  Serial.println("Camera init... ");
  esp_err_t err = esp_camera_init(&camera_config);

  if (err != ESP_OK) {
    delay(100);  // need a delay here or the next serial o/p gets missed
    Serial.printf("\n\nCRITICAL FAILURE: Camera sensor failed to initialise.\n\n");
    Serial.printf("A full (hard, power off/on) reboot will probably be needed to recover from this.\n");
    return err;
  } else {
    Serial.println("succeeded");

    // Get a reference to the sensor
    sensor_t* s = esp_camera_sensor_get();

    // Dump camera module, warn for unsupported modules.
    switch (s->id.PID) {
      case OV9650_PID: Serial.println("WARNING: OV9650 camera module is not properly supported, will fallback to OV2640 operation"); break;
      case OV7725_PID: Serial.println("WARNING: OV7725 camera module is not properly supported, will fallback to OV2640 operation"); break;
      case OV2640_PID: Serial.println("OV2640 camera module detected"); break;
      case OV3660_PID: Serial.println("OV3660 camera module detected"); break;
      default: Serial.println("WARNING: Camera module is unknown and not properly supported, will fallback to OV2640 operation");
    }
  }
  return ESP_OK;
}

size_t sendPicture(int64_t userid) {

  // Take picture with Camera and send to Telegram
  Serial.println("Camera capture requested");

  //  for (int j = 0; j < 4; j++) {
  //    camera_fb_t * newfb = esp_camera_fb_get();
  //    if (!newfb) {
  //      Serial.println("Camera Capture Failed");
  //    } else {
  //      //Serial.print("Pic, len="); Serial.print(newfb->len);
  //      //Serial.printf(", new fb %X\n", (long)newfb->buf);
  //      esp_camera_fb_return(newfb);
  //      delay(10);
  //    }
  //  }

  camera_fb_t* fb = esp_camera_fb_get();
  if (!fb) {
    Serial.println("Camera capture failed");
    return 0;
  }
  size_t len = fb->len;
  myBot.sendPhoto(userid, fb->buf, fb->len);

  // Clear buffer
  esp_camera_fb_return(fb);
  return len;
}

#define THIS_FRAME FRAMESIZE_QVGA // JPEG frames size to be retrieved
#define LAMP_PIN 4
bool debug = true;
uint8_t fsizePtr = THIS_FRAME; // framesize selection
uint8_t lightLevel; // Current ambient light level
uint8_t nightSwitch = 10; // white level % for night/day switching
uint8_t motionVal = 7; // motion sensitivity difference setting
bool haveMotion = false;
struct frameStruct {
  const char* frameSizeStr;
  const uint16_t frameWidth;
  const uint16_t frameHeight;
  const uint16_t defaultFPS;
  const uint8_t scaleFactor;
  const uint8_t sampleRate;
};
// sample factors, 5th arg is scaling factor (1..N), 6th arg is sample factor (0..3)
// indexed by frame size - needs to be consistent with sensor.h enum
extern const frameStruct frameData[] = {
  {"QQVGA", 160, 120, 25, 2, 1},
  {"n/a", 0, 0, 0, 0, 1},
  {"n/a", 0, 0, 0, 0, 1},
  {"HQVGA", 240, 176, 25, 3, 1},
  {"QVGA", 320, 240, 25, 3, 1},
  {"CIF", 400, 296, 25, 3, 1},
  {"VGA", 640, 480, 15, 3, 2},
  {"SVGA", 800, 600, 10, 3, 2},
  {"XGA", 1024, 768, 5, 3, 3},
  {"SXGA", 1280, 1024, 3, 3, 4},
  {"UXGA", 1600, 1200, 2, 6, 5}
};

bool checkMotion(camera_fb_t* fb, bool motionStatus);
bool isNight(uint8_t nightSwitch);

void setup_camera() {
  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_sscb_sda = SIOD_GPIO_NUM;
  config.pin_sscb_scl = SIOC_GPIO_NUM;
  config.pin_pwdn = PWDN_GPIO_NUM;
  config.pin_reset = RESET_GPIO_NUM;
  config.xclk_freq_hz = 10000000; // https://github.com/esphome/issues/issues/4191
  config.pixel_format = PIXFORMAT_JPEG;
  //init with high specs to pre-allocate larger buffers
  if (psramFound())
  {
    config.frame_size = FRAMESIZE_VGA; // FRAMESIZE_ + QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA
    config.jpeg_quality = 10;
    config.fb_count = 2;
  }
  else
  {
    config.frame_size = FRAMESIZE_VGA;
    config.jpeg_quality = 12;
    config.fb_count = 1;
  }

  // camera init
  esp_err_t err = ESP_FAIL;
  uint8_t retries = 2;
  while (retries && err != ESP_OK) {
    err = esp_camera_init(&config);
    if (err != ESP_OK) {
      Serial.printf("Camera init failed with error 0x%x", err);
      digitalWrite(PWDN_GPIO_NUM, 1);
      delay(100);
      digitalWrite(PWDN_GPIO_NUM, 0); // power cycle the camera (OV2640)
      retries--;
    }
  }
  if (err != ESP_OK) ESP.restart();
}

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

  WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);       // disable brownout detector

  // Initiate the camera module 
  // init_camera(); // alternative camera setup routine for testing purposes only
  setup_camera();

  // Start WiFi connection
  WiFi.begin(ssid, pass);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println(WiFi.localIP());

  // Sync time with NTP
  configTzTime(MYTZ, "time.google.com", "time.windows.com", "pool.ntp.org");
  secure_client.setCACert(telegram_cert);

  myBot.addSentCallback([](bool sent) {
    const char* res = sent ? "Picture delivered!" : "Error! Picture NOT delivered";
    if (!sent)
      myBot.sendTo(userid, res);
  }, 3000);

  // Set the Telegram bot properies
  myBot.setUpdateTime(1000);
  myBot.setTelegramToken(token);

  // Check if all things are ok
  Serial.print("\nTest Telegram connection... ");
  myBot.begin() ? Serial.println("OK") : Serial.println("NOK");

  //  Serial.println("\nSending Photo from CAM");
  //  if (sendPicture(userid))
  //    Serial.println("Picture sent successfull");
  //  else
  //    myBot.sendTo(userid, "Error, picture not sent.");
}

unsigned long lastPictureTime = 0;
const long interval = 10000; // wait 10sec between sending a new photo when there is movement

void loop() {
  camera_fb_t* fb = esp_camera_fb_get();

  if (fb) {
    haveMotion = checkMotion(fb, haveMotion);

    if (haveMotion) {
      haveMotion = false;

      Serial.println("movement detected");

      unsigned long currentTime = millis();

      if (currentTime - lastPictureTime >= interval) {
        lastPictureTime = currentTime;
        Serial.println("\nSending Photo from CAM");
        if (sendPicture(userid))
          Serial.println("Picture sent successfull");
        else
          myBot.sendTo(userid, "Error, picture not sent.");
      }
    }

    esp_camera_fb_return(fb);
  } else Serial.println("Failed to get frame");
  delay(100);
}

Great.

Can we get a 2-3 video with same logic instead of photo.?!

FBMinis commented 1 year ago

I would adapt the project by jameszah to include something like this:

static unsigned long lastFrameTime = 0;
unsigned long currentFrameTime = millis();

unsigned long lastPictureTime = 0;
const long interval = 30000; // wait 30sec between sending a new photo+video when there is movement

void loop() {

  // Capture frame every 100ms
  if (currentFrameTime - lastFrameTime >= 100) {

    camera_fb_t* fb = esp_camera_fb_get();

    if (fb) {
      haveMotion = checkMotion(fb, haveMotion);

      if (haveMotion) {
        haveMotion = false;

        Serial.println("movement detected");

        unsigned long currentTime = millis();

        if (currentTime - lastPictureTime >= interval) {
          lastPictureTime = currentTime;

          // capture and send photo+video
          bot.longPoll = 0;
          xTaskCreatePinnedToCore( the_camera_loop, "the_camera_loop", 10000, NULL, 1, &the_camera_loop_task, 1);

        }
      }

      esp_camera_fb_return(fb);
    } else Serial.println("Failed to get frame");

    lastFrameTime = currentFrameTime;
  }

}
s60sc commented 1 year ago

Noted. I've started work on a telegram feature, but will be writing my own code as there's no challenge copying someone else.

FBMinis commented 1 year ago

One thing I haven't found in other Telegram libs: save error messages in RTC (errors from camera or connections), send them as a Telegram message after the camera has power-cycled or restarted or upon we send a message to the bot.

s60sc commented 1 year ago

I'd previously thought about using RTC_NOINIT_ATTR for carrying over restart messages then forgot about it, so I'll look again. Only works for s/w reset not power cycle. The sd logs are persistent though.

s60sc commented 11 months ago

Telegram & RTC log added to v9.1