From 7ae1e15fb940920113e6f833c0aaf75d7738e3a9 Mon Sep 17 00:00:00 2001 From: jameszah <36938190+jameszah@users.noreply.github.com> Date: Wed, 26 Feb 2020 15:39:11 -0700 Subject: [PATCH] Delete TimeLapseAvi59x.ino --- v59/TimeLapseAvi59x.ino | 1540 --------------------------------------- 1 file changed, 1540 deletions(-) delete mode 100644 v59/TimeLapseAvi59x.ino diff --git a/v59/TimeLapseAvi59x.ino b/v59/TimeLapseAvi59x.ino deleted file mode 100644 index 552ff64..0000000 --- a/v59/TimeLapseAvi59x.ino +++ /dev/null @@ -1,1540 +0,0 @@ - - -#include - -/* - - TimeLapseAvi - - ESP32-CAM Video Recorder - - This program records an AVI video on the SD Card of an ESP32-CAM. - - by James Zahary July 20, 2019 TimeLapseAvi23x.ino - jamzah.plc@gmail.com - - https://github.com/jameszah/ESP32-CAM-Video-Recorder - - jameszah/ESP32-CAM-Video-Recorder is licensed under the - GNU General Public License v3.0 - - The is Arduino code, with standard setup for ESP32-CAM - - Board ESP32 Wrover Module - - Partition Scheme Huge APP (3MB No OTA) - -*/ - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// edit these parameters for your needs - -static const char vernum[] = "v59"; // version 59 Feb 23, 2020 - switch to 1 bit system, and pir -static const char devname[] = "desklens"; // name of your camera for mDNS, Router, and filenames - - -#define TIMEZONE "GMT0BST,M3.5.0/01,M10.5.0/02" // your timezone - this is GMT - -// 1 for blink red led with every sd card write, at your frame rate -// 0 for blink only for skipping frames and SOS if camera or sd is broken -#define BlinkWithWrite 0 - -// EDIT ssid and password -const char ssid[] = "wifiRouter"; // your wireless network name (SSID) -const char password[] = "wifipassword"; // your Wi-Fi network password - -// startup defaults for first recording - - -// here are the recording options from the "retart web page" -// VGA 10 fps for 30 min, repeat, realtime http://192.168.0.117/start?framesize=VGA&length=1800&interval=100&quality=10&repeat=100&speed=1&gray=0 -// VGA 2 fps, for 30 minutes repeat, 30x playback http://192.168.0.117/start?framesize=VGA&length=1800&interval=500&quality=10&repeat=300&speed=30&gray=0 -// UXGA 1 sec per frame, for 30 minutes repeat, 30x playback http://192.168.0.117/start?framesize=UXGA&length=1800&interval=1000&quality=10&repeat=100&speed=30&gray=0 -// UXGA 2 fps for 30 minutes repeat, 15x playback http://192.168.0.117/start?framesize=UXGA&length=1800&interval=500&quality=10&repeat=100&speed=30&gray=0 -// CIF 20 fps second for 30 minutes repeat http://192.168.0.117/start?framesize=CIF&length=1800&interval=50&quality=10&repeat=100&speed=1&gray=0 - -// reboot startup parameters here - -int record_on_reboot = 1; // set to 1 to record, or 0 to NOT record on reboot -int framesize = 6; // vga (10 UXGA, 7 SVGA, 6 VGA, 5 CIF) -int repeat = 100; // 100 files -int xspeed = 1; // 1x playback speed (realtime is 1) -int gray = 0; // not gray -int quality = 10; // 10 on the 0..64 scale, or 10..50 subscale - 10 is good, 20 is grainy and smaller files -int capture_interval = 100; // 100 ms or 10 frames per second -int total_frames = 18000; // 18000 frames = 10 fps * 60 seconds * 30 minutes = half hour - -int PIRpin = 12; - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -int new_config = 5; // this system abandoned ! -int xlength = total_frames * capture_interval / 1000; -int recording = 0; -int PIRstatus = 0; -int PIRrecording = 0; -int ready = 0; - -//#define LOG_LOCAL_LEVEL ESP_LOG_VERBOSE -#include "esp_log.h" -#include "esp_http_server.h" -#include "esp_camera.h" - -#include - -#include "ESP32FtpServer.h" -#include - -FtpServer ftpSrv; //set #define FTP_DEBUG in ESP32FtpServer.h to see ftp verbose on serial - -// Time -#include "time.h" - -// MicroSD -#include "driver/sdmmc_host.h" -#include "driver/sdmmc_defs.h" -#include "sdmmc_cmd.h" -#include "esp_vfs_fat.h" -#include - -long current_millis; -long last_capture_millis = 0; -static esp_err_t cam_err; -static esp_err_t card_err; -char strftime_buf[64]; -int file_number = 0; -bool internet_connected = false; -struct tm timeinfo; -time_t now; - -char *filename ; -char *stream ; -int newfile = 0; -int frames_so_far = 0; -FILE *myfile; -long bp; -long ap; -long bw; -long aw; -long totalp; -long totalw; -float avgp; -float avgw; -int overtime_count = 0; - -// CAMERA_MODEL_AI_THINKER -#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 - - -// GLOBALS -#define BUFFSIZE 512 - -// global variable used by these pieces - -char str[20]; -uint16_t n; -uint8_t buf[BUFFSIZE]; - -static int i = 0; -uint8_t temp = 0, temp_last = 0; -unsigned long fileposition = 0; -uint16_t frame_cnt = 0; -uint16_t remnant = 0; -uint32_t length = 0; -uint32_t startms; -uint32_t elapsedms; -uint32_t uVideoLen = 0; -bool is_header = false; -long bigdelta = 0; -int other_cpu_active = 0; -int skipping = 0; -int skipped = 0; - -int fb_max = 12; - -camera_fb_t * fb_q[30]; -int fb_in = 0; -int fb_out = 0; - -camera_fb_t * fb = NULL; - -FILE *avifile = NULL; -FILE *idxfile = NULL; - - -#define AVIOFFSET 240 // AVI main header length - -unsigned long movi_size = 0; -unsigned long jpeg_size = 0; -unsigned long idx_offset = 0; - -uint8_t zero_buf[4] = {0x00, 0x00, 0x00, 0x00}; -uint8_t dc_buf[4] = {0x30, 0x30, 0x64, 0x63}; // "00dc" -uint8_t avi1_buf[4] = {0x41, 0x56, 0x49, 0x31}; // "AVI1" -uint8_t idx1_buf[4] = {0x69, 0x64, 0x78, 0x31}; // "idx1" - -uint8_t vga_w[2] = {0x80, 0x02}; // 640 -uint8_t vga_h[2] = {0xE0, 0x01}; // 480 -uint8_t cif_w[2] = {0x90, 0x01}; // 400 -uint8_t cif_h[2] = {0x28, 0x01}; // 296 -uint8_t svga_w[2] = {0x20, 0x03}; // 800 -uint8_t svga_h[2] = {0x58, 0x02}; // 600 -uint8_t uxga_w[2] = {0x40, 0x06}; // 1600 -uint8_t uxga_h[2] = {0xB0, 0x04}; // 1200 - - -const int avi_header[AVIOFFSET] PROGMEM = { - 0x52, 0x49, 0x46, 0x46, 0xD8, 0x01, 0x0E, 0x00, 0x41, 0x56, 0x49, 0x20, 0x4C, 0x49, 0x53, 0x54, - 0xD0, 0x00, 0x00, 0x00, 0x68, 0x64, 0x72, 0x6C, 0x61, 0x76, 0x69, 0x68, 0x38, 0x00, 0x00, 0x00, - 0xA0, 0x86, 0x01, 0x00, 0x80, 0x66, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x02, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4C, 0x49, 0x53, 0x54, 0x84, 0x00, 0x00, 0x00, - 0x73, 0x74, 0x72, 0x6C, 0x73, 0x74, 0x72, 0x68, 0x30, 0x00, 0x00, 0x00, 0x76, 0x69, 0x64, 0x73, - 0x4D, 0x4A, 0x50, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x74, 0x72, 0x66, - 0x28, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00, - 0x01, 0x00, 0x18, 0x00, 0x4D, 0x4A, 0x50, 0x47, 0x00, 0x84, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x4E, 0x46, 0x4F, - 0x10, 0x00, 0x00, 0x00, 0x6A, 0x61, 0x6D, 0x65, 0x73, 0x7A, 0x61, 0x68, 0x61, 0x72, 0x79, 0x20, - 0x76, 0x35, 0x39, 0x20, 0x4C, 0x49, 0x53, 0x54, 0x00, 0x01, 0x0E, 0x00, 0x6D, 0x6F, 0x76, 0x69, -}; - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// AviWriterTask runs on cpu 1 to write the avi file -// - -TaskHandle_t CameraTask, AviWriterTask; -SemaphoreHandle_t baton; -int counter = 0; - -void codeForAviWriterTask( void * parameter ) -{ - - for (;;) { - if (ready) { - make_avi(); - } - delay(1); - } -} - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// CameraTask runs on cpu 0 to take pictures and drop them in a queue -// - -void codeForCameraTask( void * parameter ) -{ - - for (;;) { - - if (other_cpu_active == 1 ) { - current_millis = millis(); - if (current_millis - last_capture_millis > capture_interval) { - - last_capture_millis = millis(); - - xSemaphoreTake( baton, portMAX_DELAY ); - - if ( ( (fb_in + fb_max - fb_out) % fb_max) + 1 == fb_max ) { - xSemaphoreGive( baton ); - - Serial.print(" Queue Full, Skipping ... "); // the queue is full - skipped++; - skipping = 1; - - } - - if (skipping > 0 ) { - - - if (!BlinkWithWrite) { - digitalWrite(33, LOW); - } - - if (skipping % 2 == 0) { // skip every other frame until queue is cleared - - frames_so_far = frames_so_far + 1; - frame_cnt++; - - fb_in = (fb_in + 1) % fb_max; - bp = millis(); - fb_q[fb_in] = esp_camera_fb_get(); - totalp = totalp - bp + millis(); - - } else { - Serial.print(((fb_in + fb_max - fb_out) % fb_max)); // skip an extra frame to empty the queue - skipped++; - } - skipping = skipping + 1; - if (((fb_in + fb_max - fb_out) % fb_max) == 0 ) { - skipping = 0; - Serial.println(" Queue cleared. "); - } - - xSemaphoreGive( baton ); - - } else { - - skipping = 0; - frames_so_far = frames_so_far + 1; - frame_cnt++; - - fb_in = (fb_in + 1) % fb_max; - bp = millis(); - fb_q[fb_in] = esp_camera_fb_get(); - totalp = totalp - bp + millis(); - xSemaphoreGive( baton ); - - } - } - } - delay(1); - } -} - - -// -// Writes an uint32_t in Big Endian at current file position -// -static void inline print_quartet(unsigned long i, FILE * fd) -{ - uint8_t x[1]; - - x[0] = i % 0x100; - size_t i1_err = fwrite(x , 1, 1, fd); - i = i >> 8; x[0] = i % 0x100; - size_t i2_err = fwrite(x , 1, 1, fd); - i = i >> 8; x[0] = i % 0x100; - size_t i3_err = fwrite(x , 1, 1, fd); - i = i >> 8; x[0] = i % 0x100; - size_t i4_err = fwrite(x , 1, 1, fd); -} - - -void startCameraServer(); -httpd_handle_t camera_httpd = NULL; - -char the_page[3000]; - -char localip[20]; -WiFiEventId_t eventID; - -#include "soc/soc.h" -#include "soc/rtc_cntl_reg.h" - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// setup() runs on cpu 1 -// - -void setup() { - //WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector // creates other problems - - Serial.begin(115200); - - Serial.setDebugOutput(true); - - // zzz - Serial.println(" "); - Serial.println("-------------------------------------"); - Serial.printf("ESP-CAM Video Recorder %s\n", vernum); - Serial.printf(" http://%s.local - to access the camera\n", devname); - Serial.println("-------------------------------------"); - - pinMode(33, OUTPUT); // little red led on back of chip - digitalWrite(33, LOW); // turn on the red LED on the back of chip - - if (init_wifi()) { // Connected to WiFi - internet_connected = true; - } - - if (!psramFound()) { - Serial.println("paraFound wrong - major fail"); - major_fail(); - } - - // SD camera init - card_err = init_sdcard(); - if (card_err != ESP_OK) { - Serial.printf("SD Card init failed with error 0x%x", card_err); - major_fail(); - return; - } - - startCameraServer(); - - // zzz username and password for ftp server - - ftpSrv.begin("esp", "esp"); - - Serial.printf("Total space: %lluMB\n", SD_MMC.totalBytes() / (1024 * 1024)); - Serial.printf("Used space: %lluMB\n", SD_MMC.usedBytes() / (1024 * 1024)); - - digitalWrite(33, HIGH); // red light turns off when setup is complete - - baton = xSemaphoreCreateMutex(); - - xTaskCreatePinnedToCore( - codeForCameraTask, - "CameraTask", - 10000, - NULL, - 1, - &CameraTask, - 0); - - delay(50); - - xTaskCreatePinnedToCore( - codeForAviWriterTask, - "AviWriterTask", - 10000, - NULL, - 2, - &AviWriterTask, - 1); - - delay(50); - - - recording = 0; // we are NOT recording - config_camera(); - - - pinMode(4, OUTPUT); // using 1 bit mode, shut off the Blinding Disk-Active Light - digitalWrite(4, LOW); - - pinMode(PIRpin, INPUT_PULLDOWN); // or PULLDOWN for active high - - newfile = 0; // no file is open // don't fiddle with this! - - recording = record_on_reboot; - - ready = 1; - - Serial.print("Camera Ready! Use 'http://"); - Serial.print(WiFi.localIP()); - Serial.println("' to connect"); - - -} - - -// -// if we have no camera, or sd card, then flash rear led on and off to warn the human SOS - SOS -// -void major_fail() { - - Serial.println(" "); - - for (int i = 0; i < 10; i++) { // 10 loops or about 100 seconds then reboot - digitalWrite(33, LOW); delay(150); - digitalWrite(33, HIGH); delay(150); - digitalWrite(33, LOW); delay(150); - digitalWrite(33, HIGH); delay(150); - digitalWrite(33, LOW); delay(150); - digitalWrite(33, HIGH); delay(150); - - delay(1000); - - digitalWrite(33, LOW); delay(500); - digitalWrite(33, HIGH); delay(500); - digitalWrite(33, LOW); delay(500); - digitalWrite(33, HIGH); delay(500); - digitalWrite(33, LOW); delay(500); - digitalWrite(33, HIGH); delay(500); - - delay(1000); - Serial.print("Major Fail "); Serial.print(i); Serial.print(" / "); Serial.println(10); - } - - ESP.restart(); - -} - - -bool init_wifi() -{ - int connAttempts = 0; - - WiFi.disconnect(true); - WiFi.mode(WIFI_STA); - - WiFi.setHostname(devname); - //WiFi.printDiag(Serial); - WiFi.begin(ssid, password); - delay(1000); - while (WiFi.status() != WL_CONNECTED ) { - delay(500); - Serial.print("."); - if (connAttempts == 10) { - Serial.println("Cannot connect - try again"); - WiFi.begin(ssid, password); - WiFi.printDiag(Serial); - } - if (connAttempts == 20) { - Serial.println("Cannot connect - fail"); - - WiFi.printDiag(Serial); - return false; - } - connAttempts++; - } - - Serial.println("Internet connected"); - - //WiFi.printDiag(Serial); - - if (!MDNS.begin(devname)) { - Serial.println("Error setting up MDNS responder!"); - } else { - Serial.printf("mDNS responder started '%s'\n", devname); - } - - configTime(0, 0, "pool.ntp.org"); - setenv("TZ", TIMEZONE, 1); // mountain time zone from #define at top - tzset(); - - time_t now ; - timeinfo = { 0 }; - int retry = 0; - const int retry_count = 10; - delay(1000); - time(&now); - localtime_r(&now, &timeinfo); - - while (timeinfo.tm_year < (2016 - 1900) && ++retry < retry_count) { - Serial.printf("Waiting for system time to be set... (%d/%d) -- %d\n", retry, retry_count, timeinfo.tm_year); - delay(1000); - time(&now); - localtime_r(&now, &timeinfo); - } - - Serial.println(ctime(&now)); - sprintf(localip, "%s", WiFi.localIP().toString().c_str()); - - return true; - -} - - -static esp_err_t init_sdcard() -{ - esp_err_t ret = ESP_FAIL; - sdmmc_host_t host = SDMMC_HOST_DEFAULT(); - host.flags = SDMMC_HOST_FLAG_1BIT; // using 1 bit mode - host.max_freq_khz = SDMMC_FREQ_HIGHSPEED; - sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT(); - slot_config.width = 1; // using 1 bit mode - //Serial.print("Slot config width should be 4 width: "); Serial.println(slot_config.width); - esp_vfs_fat_sdmmc_mount_config_t mount_config = { - .format_if_mount_failed = false, - .max_files = 5, - }; - - //pinMode(4, OUTPUT); // using 1 bit mode, shut off the Blinding Disk-Active Light - //digitalWrite(4, LOW); - - sdmmc_card_t *card; - - Serial.println("Mounting SD card..."); - ret = esp_vfs_fat_sdmmc_mount("/sdcard", &host, &slot_config, &mount_config, &card); - - if (ret == ESP_OK) { - Serial.println("SD card mount successfully!"); - } else { - Serial.printf("Failed to mount SD card VFAT filesystem. Error: %s", esp_err_to_name(ret)); - major_fail(); - } - sdmmc_card_print_info(stdout, card); - Serial.print("SD_MMC Begin: "); Serial.println(SD_MMC.begin()); // required by ftp system ?? -} - - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Make the avi move in 4 pieces -// -// make_avi() called in every loop, which calls below, depending on conditions -// start_avi() - open the file and write headers -// another_pic_avi() - write one more frame of movie -// end_avi() - write the final parameters and close the file - -void make_avi( ) { - - - PIRstatus = digitalRead(PIRpin); - - - if (PIRstatus == 1) { - - if (PIRrecording == 1) { - // keep recording for 15 more seconds - if ( (millis() - startms) > (total_frames * capture_interval - 5000) ) { - - total_frames = total_frames + 10000 / capture_interval ; - Serial.println("Add another 10 seconds"); - } - - } else { - - if ( recording == 0 && newfile == 0) { - - //start a pir recording with current parameters, except no repeat and 15 seconds - Serial.println("Start a PIR"); - PIRrecording = 1; - repeat = 0; - total_frames = 15000 / capture_interval; - xlength = total_frames * capture_interval / 1000; - recording = 1; - } - } - } - - - // we are recording, but no file is open - - if (newfile == 0 && recording == 1) { // open the file - - digitalWrite(33, HIGH); - newfile = 1; - start_avi(); - - } else { - - // we have a file open, but not recording - - if (newfile == 1 && recording == 0) { // got command to close file - - digitalWrite(33, LOW); - end_avi(); - - Serial.println("Done capture due to command"); - - frames_so_far = total_frames; - - newfile = 0; // file is closed - recording = 0; // DO NOT start another recording - PIRrecording = 0; - - } else { - - if (newfile == 1 && recording == 1) { // regular recording - - if (frames_so_far >= total_frames) { // we are done the recording - - Serial.println("Done capture for total frames!"); - - digitalWrite(33, LOW); // close the file - end_avi(); - - frames_so_far = 0; - newfile = 0; // file is closed - - if (repeat > 0) { - recording = 1; // start another recording - repeat = repeat - 1; - } else { - recording = 0; - PIRrecording = 0; - } - - } else if ((millis() - startms) > (total_frames * capture_interval)) { // time is up, even though we have not done all the frames - - Serial.println (" "); Serial.println("Done capture for time"); - Serial.print("Time Elapsed: "); Serial.print(millis() - startms); Serial.print(" Frames: "); Serial.println(frame_cnt); - Serial.print("Config: "); Serial.print(total_frames * capture_interval ) ; Serial.print(" ("); - Serial.print(total_frames); Serial.print(" x "); Serial.print(capture_interval); Serial.println(")"); - - digitalWrite(33, LOW); // close the file - - end_avi(); - - frames_so_far = 0; - newfile = 0; // file is closed - if (repeat > 0) { - recording = 1; // start another recording - repeat = repeat - 1; - } else { - recording = 0; - PIRrecording = 0; - } - - } else { // regular - - another_save_avi(); - - } - } - } - } -} - -static esp_err_t config_camera() { - - camera_config_t config; - - //Serial.println("config camera"); - - if (new_config == 5) { - - 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 = 20000000; - config.pixel_format = PIXFORMAT_JPEG; - - config.frame_size = FRAMESIZE_UXGA; - - fb_max = 7; // for vga and uxga - config.jpeg_quality = 8; - config.fb_count = fb_max + 1; - - // camera init - cam_err = esp_camera_init(&config); - if (cam_err != ESP_OK) { - Serial.printf("Camera init failed with error 0x%x", cam_err); - major_fail(); - } - - new_config = 2; - - } - - delay(100); - - sensor_t * ss = esp_camera_sensor_get(); - ss->set_quality(ss, quality); - ss->set_framesize(ss, (framesize_t)framesize); - if (gray == 1) { - ss->set_special_effect(ss, 2); // 0 regular, 2 grayscale - } else { - ss->set_special_effect(ss, 0); // 0 regular, 2 grayscale - } - - for (int j = 0; j < 3; j++) { - do_fb(); // start the camera ... warm it up - delay(1); - } -} - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// start_avi - open the files and write in headers -// - -static esp_err_t start_avi() { - - Serial.println("Starting an avi "); - - config_camera(); - - time(&now); - localtime_r(&now, &timeinfo); - - strftime(strftime_buf, sizeof(strftime_buf), "%F_%H.%M.%S", &timeinfo); - - char fname[100]; - - if (framesize == 6) { - sprintf(fname, "/sdcard/%s_%s_vga_Q%d_I%d_L%d_S%d.avi", devname, strftime_buf, quality, capture_interval, xlength, xspeed); - } else if (framesize == 7) { - sprintf(fname, "/sdcard/%s_%s_svga_Q%d_I%d_L%d_S%d.avi", devname, strftime_buf, quality, capture_interval, xlength, xspeed); - } else if (framesize == 10) { - sprintf(fname, "/sdcard/%s_%s_uxga_Q%d_I%d_L%d_S%d.avi", devname, strftime_buf, quality, capture_interval, xlength, xspeed); - } else if (framesize == 5) { - sprintf(fname, "/sdcard/%s_%s_cif_Q%d_I%d_L%d_S%d.avi", devname, strftime_buf, quality, capture_interval, xlength, xspeed); - } else { - Serial.println("Wrong framesize"); - sprintf(fname, "/sdcard/%s_%s_xxx_Q%d_I%d_L%d_S%d.avi", devname, strftime_buf, quality, capture_interval, xlength, xspeed); - } - - Serial.print("\nFile name will be >"); Serial.print(fname); Serial.println("<"); - - avifile = fopen(fname, "w"); - idxfile = fopen("/sdcard/idx.tmp", "w"); - - if (avifile != NULL) { - - //Serial.printf("File open: %s\n", fname); - - } else { - Serial.println("Could not open file"); - major_fail(); - } - - if (idxfile != NULL) { - - //Serial.printf("File open: %s\n", "/sdcard/idx.tmp"); - - } else { - Serial.println("Could not open file"); - major_fail(); - } - - - for ( i = 0; i < AVIOFFSET; i++) - { - char ch = pgm_read_byte(&avi_header[i]); - buf[i] = ch; - } - - size_t err = fwrite(buf, 1, AVIOFFSET, avifile); - - if (framesize == 6) { - - fseek(avifile, 0x40, SEEK_SET); - err = fwrite(vga_w, 1, 2, avifile); - fseek(avifile, 0xA8, SEEK_SET); - err = fwrite(vga_w, 1, 2, avifile); - fseek(avifile, 0x44, SEEK_SET); - err = fwrite(vga_h, 1, 2, avifile); - fseek(avifile, 0xAC, SEEK_SET); - err = fwrite(vga_h, 1, 2, avifile); - - } else if (framesize == 10) { - - fseek(avifile, 0x40, SEEK_SET); - err = fwrite(uxga_w, 1, 2, avifile); - fseek(avifile, 0xA8, SEEK_SET); - err = fwrite(uxga_w, 1, 2, avifile); - fseek(avifile, 0x44, SEEK_SET); - err = fwrite(uxga_h, 1, 2, avifile); - fseek(avifile, 0xAC, SEEK_SET); - err = fwrite(uxga_h, 1, 2, avifile); - - } else if (framesize == 7) { - - fseek(avifile, 0x40, SEEK_SET); - err = fwrite(svga_w, 1, 2, avifile); - fseek(avifile, 0xA8, SEEK_SET); - err = fwrite(svga_w, 1, 2, avifile); - fseek(avifile, 0x44, SEEK_SET); - err = fwrite(svga_h, 1, 2, avifile); - fseek(avifile, 0xAC, SEEK_SET); - err = fwrite(svga_h, 1, 2, avifile); - - } else if (framesize == 5) { - - fseek(avifile, 0x40, SEEK_SET); - err = fwrite(cif_w, 1, 2, avifile); - fseek(avifile, 0xA8, SEEK_SET); - err = fwrite(cif_w, 1, 2, avifile); - fseek(avifile, 0x44, SEEK_SET); - err = fwrite(cif_h, 1, 2, avifile); - fseek(avifile, 0xAC, SEEK_SET); - err = fwrite(cif_h, 1, 2, avifile); - } - - fseek(avifile, AVIOFFSET, SEEK_SET); - - Serial.print(F("\nRecording ")); - Serial.print(total_frames); - Serial.println(F(" video frames ...\n")); - - startms = millis(); - bigdelta = millis(); - totalp = 0; - totalw = 0; - overtime_count = 0; - jpeg_size = 0; - movi_size = 0; - uVideoLen = 0; - idx_offset = 4; - - - frame_cnt = 0; - frames_so_far = 0; - - skipping = 0; - skipped = 0; - - newfile = 1; - - other_cpu_active = 1; - -} // end of start avi - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// another_save_avi runs on cpu 1, saves another frame to the avi file -// -// the "baton" semaphore makes sure that only one cpu is using the camera subsystem at a time -// - -static esp_err_t another_save_avi() { - - xSemaphoreTake( baton, portMAX_DELAY ); - - if (fb_in == fb_out) { // nothing to do - - xSemaphoreGive( baton ); - - } else { - - fb_out = (fb_out + 1) % fb_max; - - int fblen; - fblen = fb_q[fb_out]->len; - - //xSemaphoreGive( baton ); - - if (BlinkWithWrite) { - digitalWrite(33, LOW); - } - - jpeg_size = fblen; - movi_size += jpeg_size; - uVideoLen += jpeg_size; - - bw = millis(); - size_t dc_err = fwrite(dc_buf, 1, 4, avifile); - size_t ze_err = fwrite(zero_buf, 1, 4, avifile); - - bw = millis(); - size_t err = fwrite(fb_q[fb_out]->buf, 1, fb_q[fb_out]->len, avifile); - if (err == 0 ) { - Serial.println("Error on avi write"); - major_fail(); - } - totalw = totalw + millis() - bw; - - //xSemaphoreTake( baton, portMAX_DELAY ); - esp_camera_fb_return(fb_q[fb_out]); // release that buffer back to the camera system - xSemaphoreGive( baton ); - - remnant = (4 - (jpeg_size & 0x00000003)) & 0x00000003; - - print_quartet(idx_offset, idxfile); - print_quartet(jpeg_size, idxfile); - - idx_offset = idx_offset + jpeg_size + remnant + 8; - - jpeg_size = jpeg_size + remnant; - movi_size = movi_size + remnant; - if (remnant > 0) { - size_t rem_err = fwrite(zero_buf, 1, remnant, avifile); - } - - fileposition = ftell (avifile); // Here, we are at end of chunk (after padding) - fseek(avifile, fileposition - jpeg_size - 4, SEEK_SET); // Here we are the the 4-bytes blank placeholder - - print_quartet(jpeg_size, avifile); // Overwrite placeholder with actual frame size (without padding) - - fileposition = ftell (avifile); - - fseek(avifile, fileposition + 6, SEEK_SET); // Here is the FOURCC "JFIF" (JPEG header) - // Overwrite "JFIF" (still images) with more appropriate "AVI1" - - size_t av_err = fwrite(avi1_buf, 1, 4, avifile); - - fileposition = ftell (avifile); - fseek(avifile, fileposition + jpeg_size - 10 , SEEK_SET); - //Serial.println("Write done"); - //41 totalw = totalw + millis() - bw; - - //if (((fb_in + fb_max - fb_out) % fb_max) > 0 ) { - // Serial.print(((fb_in + fb_max - fb_out) % fb_max)); Serial.print(" "); - //} - - digitalWrite(33, HIGH); - } -} // end of another_pic_avi - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// end_avi runs on cpu 1, empties the queue of frames, writes the index, and closes the files -// - -static esp_err_t end_avi() { - - unsigned long current_end = 0; - - other_cpu_active = 0 ; // shuts down the picture taking program - - //Serial.print(" Write Q: "); Serial.print((fb_in + fb_max - fb_out) % fb_max); Serial.print(" in/out "); Serial.print(fb_in); Serial.print(" / "); Serial.println(fb_out); - - for (int i = 0; i < fb_max; i++) { // clear the queue - another_save_avi(); - } - - //Serial.print(" Write Q: "); Serial.print((fb_in + fb_max - fb_out) % fb_max); Serial.print(" in/out "); Serial.print(fb_in); Serial.print(" / "); Serial.println(fb_out); - - current_end = ftell (avifile); - - Serial.println("End of avi - closing the files"); - - elapsedms = millis() - startms; - float fRealFPS = (1000.0f * (float)frame_cnt) / ((float)elapsedms) * xspeed; - float fmicroseconds_per_frame = 1000000.0f / fRealFPS; - uint8_t iAttainedFPS = round(fRealFPS); - uint32_t us_per_frame = round(fmicroseconds_per_frame); - - - //Modify the MJPEG header from the beginning of the file, overwriting various placeholders - - fseek(avifile, 4 , SEEK_SET); - print_quartet(movi_size + 240 + 16 * frame_cnt + 8 * frame_cnt, avifile); - - fseek(avifile, 0x20 , SEEK_SET); - print_quartet(us_per_frame, avifile); - - unsigned long max_bytes_per_sec = movi_size * iAttainedFPS / frame_cnt; - - fseek(avifile, 0x24 , SEEK_SET); - print_quartet(max_bytes_per_sec, avifile); - - fseek(avifile, 0x30 , SEEK_SET); - print_quartet(frame_cnt, avifile); - - fseek(avifile, 0x8c , SEEK_SET); - print_quartet(frame_cnt, avifile); - - fseek(avifile, 0x84 , SEEK_SET); - print_quartet((int)iAttainedFPS, avifile); - - fseek(avifile, 0xe8 , SEEK_SET); - print_quartet(movi_size + frame_cnt * 8 + 4, avifile); - - Serial.println(F("\n*** Video recorded and saved ***\n")); - Serial.print(F("Recorded ")); - Serial.print(elapsedms / 1000); - Serial.print(F("s in ")); - Serial.print(frame_cnt); - Serial.print(F(" frames\nFile size is ")); - Serial.print(movi_size + 12 * frame_cnt + 4); - Serial.print(F(" bytes\nActual FPS is ")); - Serial.print(fRealFPS, 2); - Serial.print(F("\nMax data rate is ")); - Serial.print(max_bytes_per_sec); - Serial.print(F(" byte/s\nFrame duration is ")); Serial.print(us_per_frame); Serial.println(F(" us")); - Serial.print(F("Average frame length is ")); Serial.print(uVideoLen / frame_cnt); Serial.println(F(" bytes")); - Serial.print("Average picture time (ms) "); Serial.println( totalp / frame_cnt ); - Serial.print("Average write time (ms) "); Serial.println( totalw / frame_cnt ); - Serial.print("Frames Skipped % "); Serial.println( 100.0 * skipped / total_frames, 1 ); - - Serial.println("Writing the index"); - - fseek(avifile, current_end, SEEK_SET); - - fclose(idxfile); - - size_t i1_err = fwrite(idx1_buf, 1, 4, avifile); - - print_quartet(frame_cnt * 16, avifile); - - idxfile = fopen("/sdcard/idx.tmp", "r"); - - if (idxfile != NULL) { - - //Serial.printf("File open: %s\n", "/sdcard/idx.tmp"); - - } else { - Serial.println("Could not open file"); - //major_fail(); - } - - char * AteBytes; - AteBytes = (char*) malloc (8); - - for (int i = 0; i < frame_cnt; i++) { - size_t res = fread ( AteBytes, 1, 8, idxfile); - size_t i1_err = fwrite(dc_buf, 1, 4, avifile); - size_t i2_err = fwrite(zero_buf, 1, 4, avifile); - size_t i3_err = fwrite(AteBytes, 1, 8, avifile); - } - - free(AteBytes); - fclose(idxfile); - fclose(avifile); - int xx = remove("/sdcard/idx.tmp"); - - Serial.println("---"); - -} - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// do_fb - just takes a picture and discards it -// - -static esp_err_t do_fb() { - xSemaphoreTake( baton, portMAX_DELAY ); - camera_fb_t * fb = esp_camera_fb_get(); - - Serial.print("Pic, len="); Serial.println(fb->len); - - esp_camera_fb_return(fb); - xSemaphoreGive( baton ); -} - -void do_time() { - - if (WiFi.status() != WL_CONNECTED) { - - Serial.println("***** WiFi reconnect *****"); - WiFi.reconnect(); - delay(5000); - - if (WiFi.status() != WL_CONNECTED) { - Serial.println("***** WiFi rerestart *****"); - init_wifi(); - } - } - -} - -//////////////////////////////////////////////////////////////////////////////////// -// -// some globals for the loop() -// - -long wakeup; -long last_wakeup = 0; - - -void loop() -{ - - wakeup = millis(); - if (wakeup - last_wakeup > (14 * 60 * 1000) ) { // 14 minutes - last_wakeup = millis(); - - //sprintf(localip, "%s", WiFi.localIP().toString().c_str()); - do_time(); - } - - ftpSrv.handleFTP(); - - //delay(1); - -} - - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// - -static esp_err_t capture_handler(httpd_req_t *req) { - - camera_fb_t * fb = NULL; - esp_err_t res = ESP_OK; - char fname[100]; - //xSemaphoreTake( baton, portMAX_DELAY ); - fb = esp_camera_fb_get(); - - if (!fb) { - Serial.println("Camera capture failed"); - httpd_resp_send_500(req); - xSemaphoreGive( baton ); - return ESP_FAIL; - } - - file_number++; - - sprintf(fname, "inline; filename=capture_%d.jpg", file_number); - - httpd_resp_set_type(req, "image/jpeg"); - httpd_resp_set_hdr(req, "Content-Disposition", fname); - - size_t out_len, out_width, out_height; - size_t fb_len = 0; - fb_len = fb->len; - res = httpd_resp_send(req, (const char *)fb->buf, fb->len); - esp_camera_fb_return(fb); - //xSemaphoreGive( baton ); - return res; -} - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// -static esp_err_t stop_handler(httpd_req_t *req) { - - esp_err_t res = ESP_OK; - - recording = 0; - Serial.println("stopping recording"); - - do_stop("Stopping previous recording"); - - httpd_resp_send(req, the_page, strlen(the_page)); - return ESP_OK; - -} - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// -static esp_err_t start_handler(httpd_req_t *req) { - - esp_err_t res = ESP_OK; - - char buf[80]; - size_t buf_len; - char new_res[20]; - - if (recording == 1) { - const char* resp = "You must Stop recording, before starting a new one. Start over ..."; - httpd_resp_send(req, resp, strlen(resp)); - - return ESP_OK; - return res; - - } else { - //recording = 1; - Serial.println("starting recording"); - - sensor_t * s = esp_camera_sensor_get(); - - int new_interval = capture_interval; - int new_length = capture_interval * total_frames; - - int new_framesize = s->status.framesize; - int new_quality = s->status.quality; - int new_repeat = 0; - int new_xspeed = 1; - int new_xlength = 3; - int new_gray = 0; - - /* - Serial.println(""); - Serial.println("Current Parameters :"); - Serial.print(" Capture Interval = "); Serial.print(capture_interval); Serial.println(" ms"); - Serial.print(" Length = "); Serial.print(capture_interval * total_frames / 1000); Serial.println(" s"); - Serial.print(" Quality = "); Serial.println(new_quality); - Serial.print(" Framesize = "); Serial.println(new_framesize); - Serial.print(" Repeat = "); Serial.println(repeat); - Serial.print(" Speed = "); Serial.println(xspeed); - */ - - buf_len = httpd_req_get_url_query_len(req) + 1; - if (buf_len > 1) { - if (httpd_req_get_url_query_str(req, buf, buf_len) == ESP_OK) { - ESP_LOGI(TAG, "Found URL query => %s", buf); - char param[32]; - /* Get value of expected key from query string */ - //Serial.println(" ... parameters"); - if (httpd_query_key_value(buf, "length", param, sizeof(param)) == ESP_OK) { - - int x = atoi(param); - if (x >= 5 && x <= 3600 * 24 ) { // 5 sec to 24 hours - new_length = x; - } - - ESP_LOGI(TAG, "Found URL query parameter => length=%s", param); - - } - if (httpd_query_key_value(buf, "repeat", param, sizeof(param)) == ESP_OK) { - int x = atoi(param); - if (x >= 0 ) { - new_repeat = x; - } - - ESP_LOGI(TAG, "Found URL query parameter => repeat=%s", param); - } - if (httpd_query_key_value(buf, "framesize", new_res, sizeof(new_res)) == ESP_OK) { - if (strcmp(new_res, "UXGA") == 0) { - new_framesize = 10; - } else if (strcmp(new_res, "SVGA") == 0) { - new_framesize = 7; - } else if (strcmp(new_res, "VGA") == 0) { - new_framesize = 6; - } else if (strcmp(new_res, "CIF") == 0) { - new_framesize = 5; - } else { - Serial.println("Only UXGA, SVGA, VGA, and CIF are valid!"); - - } - ESP_LOGI(TAG, "Found URL query parameter => framesize=%s", new_res); - } - if (httpd_query_key_value(buf, "quality", param, sizeof(param)) == ESP_OK) { - - int x = atoi(param); - if (x >= 10 && x <= 50) { // MINIMUM QUALITY 10 to save memory - new_quality = x; - } - - ESP_LOGI(TAG, "Found URL query parameter => quality=%s", param); - } - - if (httpd_query_key_value(buf, "speed", param, sizeof(param)) == ESP_OK) { - - int x = atoi(param); - if (x >= 1 && x <= 100) { - new_xspeed = x; - } - - ESP_LOGI(TAG, "Found URL query parameter => speed=%s", param); - } - - if (httpd_query_key_value(buf, "gray", param, sizeof(param)) == ESP_OK) { - - int x = atoi(param); - if (x == 1 ) { - new_gray = x; - } - - ESP_LOGI(TAG, "Found URL query parameter => gray=%s", param); - } - - if (httpd_query_key_value(buf, "interval", param, sizeof(param)) == ESP_OK) { - - int x = atoi(param); - if (x >= 1 && x <= 180000) { // 180,000 ms = 3 min - new_interval = x; - } - ESP_LOGI(TAG, "Found URL query parameter => interval=%s", param); - } - } - } - - framesize = new_framesize; - capture_interval = new_interval; - xlength = new_length; - total_frames = new_length * 1000 / capture_interval; - repeat = new_repeat; - quality = new_quality; - xspeed = new_xspeed; - gray = new_gray; - - do_start("Starting a new AVI"); - httpd_resp_send(req, the_page, strlen(the_page)); - - recording = 1; - return ESP_OK; - } -} - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// -void do_start(char *the_message) { - - Serial.print("do_start "); Serial.println(the_message); - - const char msg[] PROGMEM = R"rawliteral( - - - - -ESP32-CAM Video Recorder - - -

ESP32-CAM Video Recorder %s


-

Message is %s


- Recording = %d (1 is active)
- Capture Interval = %d ms
- Length = %d seconds
- Quality = %d (10 best to 50 worst)
- Framesize = %d (10 UXGA, 7 SVGA, 6 VGA, 5 CIF)
- Repeat = %d
- Speed = %d
- Gray = %d

- -
-
- - -)rawliteral"; - - - sprintf(the_page, msg, vernum, the_message, recording, capture_interval, capture_interval * total_frames / 1000, quality, framesize, repeat, xspeed, gray); - //Serial.println(strlen(msg)); - -} - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// -void do_stop(char *the_message) { - - Serial.print("do_stop "); Serial.println(the_message); - - const char msg[] PROGMEM = R"rawliteral( - - - - -ESP32-CAM Video Recorder - - -

ESP32-CAM Video Recorder %s


-

Message is %s


-

http://%s/

-

http://%s/start?framesize=VGA&length=1800&interval=100&quality=10&repeat=100&speed=1&gray=0

-

VGA 2 fps, for 30 minutes repeat, 30x playback

-

UXGA 1 sec per frame, for 30 minutes repeat, 30x playback

-

UXGA 2 fps for 30 minutes repeat, 15x playback

-

CIF 20 fps second for 30 minutes repeat

-
- -)rawliteral"; - - sprintf(the_page, msg, vernum, the_message, localip, localip, localip, localip, localip, localip, localip, localip); - -} - - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// -void do_status(char *the_message) { - - Serial.print("do_status "); Serial.println(the_message); - - const char msg[] PROGMEM = R"rawliteral( - - - - -ESP32-CAM Video Recorder - - -

ESP32-CAM Video Recorder %s
%s


-

Message is %s


- Total SD Space is %d MB, Used SD Space is %d MB
- Recording = %d (1 is active)
- Frame %d of %d, Skipped %d

- Capture Interval = %d ms
- Length = %d seconds
- Quality = %d (10 best to 50 worst)
- Framesize = %d (10 UXGA, 7 SVGA, 6 VGA, 5 CIF)
- Repeat = %d
- Playback Speed = %d
- Gray = %d

- Commands as follows for your ESP's ip address:
-

http://%s/

-

http://%s/stop ... and restart
You must be stopped before restart or PIR

-

ftp://%s/

- Username: esp, Password: esp ... to download the files

- Red LED on back of ESP will flash with every frame (or skipped frames), and flash SOS if camera or sd card not working.
- -
-Check camera position with the frame below
-Refresh page for more.
-
-
- -)rawliteral"; - - time(&now); - const char *strdate = ctime(&now); - - //Serial.printf("Total space: %lluMB\n", SD_MMC.totalBytes() / (1024 * 1024)); - //Serial.printf("Used space: %lluMB\n", SD_MMC.usedBytes() / (1024 * 1024)); - - int tot = SD_MMC.totalBytes() / (1024 * 1024); - int use = SD_MMC.usedBytes() / (1024 * 1024); - - //Serial.print(strlen(msg)); Serial.print(" "); - - sprintf(the_page, msg, vernum, strdate, the_message, tot, use, recording, frames_so_far, total_frames, skipped, capture_interval, capture_interval * total_frames / 1000, quality, framesize, repeat, xspeed, gray, localip, localip, localip, localip, localip, localip); - - //Serial.println(strlen(the_page)); -} - - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// -static esp_err_t index_handler(httpd_req_t *req) { - - do_status("Refresh Status"); - httpd_resp_send(req, the_page, strlen(the_page)); - return ESP_OK; -} - -void startCameraServer() { - httpd_config_t config = HTTPD_DEFAULT_CONFIG(); - - httpd_uri_t index_uri = { - .uri = "/", - .method = HTTP_GET, - .handler = index_handler, - .user_ctx = NULL - }; - httpd_uri_t capture_uri = { - .uri = "/capture", - .method = HTTP_GET, - .handler = capture_handler, - .user_ctx = NULL - }; - - httpd_uri_t file_stop = { - .uri = "/stop", - .method = HTTP_GET, - .handler = stop_handler, - .user_ctx = NULL - }; - - httpd_uri_t file_start = { - .uri = "/start", - .method = HTTP_GET, - .handler = start_handler, - .user_ctx = NULL - }; - - if (httpd_start(&camera_httpd, &config) == ESP_OK) { - httpd_register_uri_handler(camera_httpd, &index_uri); - httpd_register_uri_handler(camera_httpd, &capture_uri); - httpd_register_uri_handler(camera_httpd, &file_start); - httpd_register_uri_handler(camera_httpd, &file_stop); - } - - Serial.println("Camera http started"); -}