Translate

Rabu, 10 Juli 2024

ESP32-CAM : Simpan video ke SD Card

Support : 
Hardware :
  • ESP32-CAM
  • SD CARD 8GB
Fitur :
  • Auto Name : nama file video akan di buat otomatis sehingga tidak ada nama video yang sama dalam sdcrad.
  • format nama : video_0.mpeg
  • video dapat disimpan sesuai dengan durasi yang di inginkan
/*
    add    : Rahmat Fanshuri
    Versi  : 1.0
    Update : 04/JULI/2024
    code   : ESP32-CAM RECORD VIDEO
*/
////////////////////////////////////////////////////////////////////////////////////////
/* ---------- HEADER GLOGAL ----------------------------------------------------------*/
#include "WiFi.h"
#include "esp_camera.h"
#include "FS.h"
#include "SD_MMC.h"
#include "soc/soc.h"           // Disable brownour problems
#include "soc/rtc_cntl_reg.h"  // Disable brownour problems
#define erFlashLed 4

uint8_t cardType = SD_MMC.cardType();
unsigned long previusTimeRecord;
int timeSetRecord = 30;
/* ---------- Konfigurasi SDCARD -----------------------------------------------------*/
const char* sdPath = "/myVideo";
const char* sdNameFile = "/video";
uint32_t sdNumberFile = 0;  //0.jpg
////////////////////////////////////////////////////////////////////////////////////////
void setup() {
  /* ---------- begin ----------------------------------------------- */
  Serial.begin(115200);
  Serial.println("\n\n\n\n  INI ESP32-CAM");
  /* ---------- setting I/O ----------------------------------------- */
  pinMode(erFlashLed, OUTPUT);
  /* ---------- setting esp32-cam ----------------------------------- */
  while (true) {
    camera_config_t config;
    config.ledc_channel = LEDC_CHANNEL_0;
    config.ledc_timer = LEDC_TIMER_0;
    config.pin_d0 = 5;
    config.pin_d1 = 18;
    config.pin_d2 = 19;
    config.pin_d3 = 21;
    config.pin_d4 = 36;
    config.pin_d5 = 39;
    config.pin_d6 = 34;
    config.pin_d7 = 35;
    config.pin_xclk = 0;
    config.pin_pclk = 22;
    config.pin_vsync = 25;
    config.pin_href = 23;
    config.pin_sscb_sda = 26;
    config.pin_sscb_scl = 27;
    config.pin_pwdn = 32;
    config.pin_reset = -1;
    config.xclk_freq_hz = 20000000;
    config.pixel_format = PIXFORMAT_JPEG;
    config.frame_size = FRAMESIZE_SVGA;
    config.jpeg_quality = 12;
    config.fb_count = 1;

    esp_err_t err = esp_camera_init(&config);
    /*------------------------------------------------------------------*/
    if (err != ESP_OK) {
      Serial.printf("Camera init failed with error 0x%x", err);
      ESP.restart();
      delay(5000);
    }
    break;
  }
  /*----------------------------------------------------------------- */
  sdCard_cekKondisi(true);
  digitalWrite(erFlashLed, 1);
  delay(1000);
  digitalWrite(erFlashLed, 0);
  delay(10000);
}
////////////////////////////////////////////////////////////////////////////////////////
void loop() {
  String directory;
  // --------- cek folder ----------
  bool result;
  result = sdCard_cekFolder(sdPath);
  if (!result) {
    sdCard_createFolder(sdPath);
  }
  // --------- cek name file ------
  while (true) {
    directory = String(sdPath) + String(sdNameFile) + "_" + String(sdNumberFile) + ".mp4";
    if (sdCard_cekFolder(directory.c_str())) {
      sdNumberFile = sdNumberFile + 1;
    } else {
      sdNumberFile = sdNumberFile + 1;
      break;
    }
  }
  // --------- record video ------
  while (true) {
    if ((millis() / 1000) - previusTimeRecord >= timeSetRecord) {
      previusTimeRecord = (millis() / 1000);
      break;
    }
    // read frame-----------------
    camera_fb_t* frame = NULL;
    frame = function_takeImage();
    if (frame) {
      File file = SD_MMC.open(directory.c_str(), FILE_APPEND);
      if (!file) {
        Serial.println("SDCARD : Gagal membuka file untuk penulisan");
        return;
      }
      file.write(frame->buf, frame->len);
      file.close();
      esp_camera_fb_return(frame);
    } else {
      Serial.println("Camera : Gagal mengambil frame dari kamera");
    }
  }
  Serial.print(directory);
  Serial.println(" success !!!");
  delay(20000);
}


///////////////////////////////////////////////////////////////////////////////////////////
camera_fb_t *function_takeImage() {
  digitalWrite(erFlashLed, 1);
  camera_fb_t *fb = NULL;
  fb = esp_camera_fb_get();
  digitalWrite(erFlashLed, 0);
  return fb;
}

///////////////////////////////////////////////////////////////////////////////////////////
/*---------- check status sdcard --------------------------------------------------------*/
bool sdCard_cekKondisi(bool status) {
  bool result;
  if (SD_MMC.begin("/sdcard", status) && cardType == CARD_NONE) {
    Serial.println("SD : Modul Card Oke");
    result = 1;
  } else {
    Serial.println("SD : Modul Card Problem.....!");
    result = 0;
  }
  delay(5000);
  return result;
}
///////////////////////////////////////////////////////////////////////////////////////////
void sdCard_cekIsiFolder(const char *nameFolder) {
  Serial.printf("Membaca direktori: %s\n", nameFolder);
  File root = SD_MMC.open(nameFolder);
  if (!root) {
    Serial.println("Gagal membuka direktori.");
    return;
  }
  File file = root.openNextFile();
  while (file) {
    Serial.print("  FILE: ");
    Serial.print(file.name());
    Serial.print("  SIZE: ");
    Serial.println(file.size());
    file.close();
    file = root.openNextFile();
  }
  root.close();
}
///////////////////////////////////////////////////////////////////////////////////////////
bool sdCard_cekFolder(const char *nameFolder) {
  if (SD_MMC.exists(nameFolder)) {
    Serial.print("SD : Folder ");
    Serial.print(nameFolder);
    Serial.println(" Tersedia.");
    return true;
  } else {
    Serial.print("SD : Folder ");
    Serial.print(nameFolder);
    Serial.println(" Tidak Tersedia.");
    return false;
  }
}
///////////////////////////////////////////////////////////////////////////////////////////
bool sdCard_createFolder(const char *nameFolder) {
  if (SD_MMC.mkdir(nameFolder)) {
    Serial.print("SD : Folder ");
    Serial.print(nameFolder);
    Serial.println(" berhasil dibuat.");
    return true;
  } else {
    Serial.print("SD : Gagal membuat folder ");
    Serial.println(nameFolder);
    return false;
  }
}

Tidak ada komentar:

Posting Komentar