Closed sakana1110 closed 2 weeks ago
If it gets stuck starting the camera, you probably have your gpio<->camera pins wrong. Is there are simple test program for that board, just to show the jpegs to a web browser. Have you also checked the sd gpio pins - they would have changed as well.
Is this what you used
https://github.com/Freenove/Freenove_ESP32_S3_WROOM_Board/blob/main/ESP32S3_Pinout.png
You could turn on the DEBUG messages in Arduino to get some more messages about what is failing ...
Which Arduino board type are you using?
You could also switch to the much newer code that I am more familiar with - like version 60 -- and just delete any sections that you dont need.
Yes, this is what I used, but I refer to another example (https://github.com/Freenove/Freenove_Ultimate_Starter_Kit_for_ESP32_S3). I tried to use example 32.2 in it and it ran normally. Then I modified the pins of the SD card (not sure is the change work).Thank you for your response. With my current abilities, I'm unable to proceed further.
ESP-ROM:esp32s3-20210327
Build:Mar 27 2021
rst:0x1 (POWERON),boot:0x2b (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fce3818,len:0x508
load:0x403c9700,len:0x4
load:0x403c9704,len:0xad0
load:0x403cc700,len:0x29e4
entry 0x403c9880
[ 113][I][esp32-hal-psram.c:90] psramInit(): PSRAM enabled
=========== Before Setup Start ===========
Chip Info:
------------------------------------------
Model : ESP32-S3
Package : 0
Revision : 2
Cores : 2
CPU Frequency : 240 MHz
XTAL Frequency : 40 MHz
Embedded Flash : No
Embedded PSRAM : No
2.4GHz WiFi : Yes
Classic BT : No
BT Low Energy : Yes
IEEE 802.15.4 : No
------------------------------------------
INTERNAL Memory Info:
------------------------------------------
Total Size : 393444 B ( 384.2 KB)
Free Bytes : 365384 B ( 356.8 KB)
Allocated Bytes : 23156 B ( 22.6 KB)
Minimum Free Bytes: 360336 B ( 351.9 KB)
Largest Free Block: 327668 B ( 320.0 KB)
------------------------------------------
SPIRAM Memory Info:
------------------------------------------
Total Size : 8388608 B (8192.0 KB)
Free Bytes : 8385672 B (8189.1 KB)
Allocated Bytes : 576 B ( 0.6 KB)
Minimum Free Bytes: 8385672 B (8189.1 KB)
Largest Free Block: 8257524 B (8064.0 KB)
Bus Mode : OPI
-----------------------------------------
Flash Info:
------------------------------------------
Chip Size : 8388608 B (8 MB)
Block Size : 65536 B ( 64.0 KB)
Sector Size : 4096 B ( 4.0 KB)
Page Size : 256 B ( 0.2 KB)
Bus Speed : 80 MHz
Bus Mode : QIO
------------------------------------------
Partitions Info:
------------------------------------------
nvs : addr: 0x00009000, size: 20.0 KB, type: DATA, subtype: NVS
otadata : addr: 0x0000E000, size: 8.0 KB, type: DATA, subtype: OTA
app0 : addr: 0x00010000, size: 1280.0 KB, type: APP, subtype: OTA_0
app1 : addr: 0x00150000, size: 1280.0 KB, type: APP, subtype: OTA_1
spiffs : addr: 0x00290000, size: 1408.0 KB, type: DATA, subtype: SPIFFS
coredump : addr: 0x003F0000, size: 64.0 KB, type: DATA, subtype: COREDUMP
------------------------------------------
Software Info:
------------------------------------------
Compile Date/Time : Nov 3 2024 11:51:07
Compile Host OS : windows
ESP-IDF Version : v5.1.4-358-gbd2b9390ef-dirty
Arduino Version : 3.0.2
------------------------------------------
Board Info:
------------------------------------------
Arduino Board : ESP32S3_DEV
Arduino Variant : esp32s3
Arduino FQBN : esp32:esp32:esp32s3:UploadSpeed=921600,USBMode=hwcdc,CDCOnBoot=default,MSCOnBoot=default,DFUOnBoot=default,UploadMode=default,CPUFreq=240,FlashMode=qio,FlashSize=4M,PartitionScheme=default,DebugLevel=debug,PSRAM=opi,LoopCore=1,EventsCore=1,EraseFlash=none,JTAGAdapter=default,ZigbeeMode=default
============ Before Setup End ============
---
-------------------------------------
ESP32-CAM-Video-Recorder-junior v02
-------------------------------------
setup, core 1, priority = 1
Internal Total heap 393444, internal Free Heap 363584
SPIRam Total heap 8388608, SPIRam Free Heap 8385412
Setting up the camera ...
//Change from https://github.com/jameszah/ESP32-CAM-Video-Recorder-junior/blob/master/old/ESP32-CAM-Video-Recorder-junior-02x.ino
static const char vernum[] = "v02";
static const char devname[] = "desklens"; // name of your camera for mDNS, Router, and filenames
int framesize = 7; // 10 UXGA, 9 SXGA, 7 SVGA, 6 VGA, 5 CIF
int quality = 20; // quality on the 1..63 scale - lower is better quality and bigger files - must be higher than the jpeg_quality in camera_config
int avi_length = 10; // how long a movie in seconds
int MagicNumber = 11; // change this number to reset the epron in your esp32
//#define LOG_LOCAL_LEVEL ESP_LOG_VERBOSE
#include "esp_log.h"
#include "esp_http_server.h"
#include "esp_camera.h"
#define PWDN_GPIO_NUM -1
#define RESET_GPIO_NUM -1
#define XCLK_GPIO_NUM 15
#define SIOD_GPIO_NUM 4
#define SIOC_GPIO_NUM 5
#define Y2_GPIO_NUM 11
#define Y3_GPIO_NUM 9
#define Y4_GPIO_NUM 8
#define Y5_GPIO_NUM 10
#define Y6_GPIO_NUM 12
#define Y7_GPIO_NUM 18
#define Y8_GPIO_NUM 17
#define Y9_GPIO_NUM 16
#define VSYNC_GPIO_NUM 6
#define HREF_GPIO_NUM 7
#define PCLK_GPIO_NUM 13
camera_fb_t * fb_curr = NULL;
camera_fb_t * fb_next = NULL;
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "nvs_flash.h"
#include "nvs.h"
#include "soc/soc.h"
#include "esp_cpu.h"
#include "soc/rtc_cntl_reg.h"
static esp_err_t cam_err;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Avi Writer Stuff here
// MicroSD
#include "driver/sdmmc_host.h"
#include "driver/sdmmc_defs.h"
#include "sdmmc_cmd.h"
#include "esp_vfs_fat.h"
#include <SD_MMC.h>
FILE *avifile = NULL;
FILE *idxfile = NULL;
long bp;
long ap;
long bw;
long aw;
int diskspeed = 0;
char fname[100];
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;
int bad_jpg = 0;
int extend_jpg = 0;
int normal_jpg = 0;
int file_number = 0;
int file_group = 0;
long boot_time = 0;
long totalp;
long totalw;
float avgp;
float avgw;
#define BUFFSIZE 512
uint8_t buf[BUFFSIZE];
#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 dc_and_zero_buf[8] = {0x30, 0x30, 0x64, 0x63, 0x00, 0x00, 0x00, 0x00};
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 sxga_w[2] = {0x00, 0x05}; // 1280
uint8_t sxga_h[2] = {0x00, 0x04}; // 1024
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, 0x30, 0x32, 0x20, 0x4C, 0x49, 0x53, 0x54, 0x00, 0x01, 0x0E, 0x00, 0x6D, 0x6F, 0x76, 0x69,
};
//
// Writes an uint32_t in Big Endian at current file position
//
static void inline print_quartet(unsigned long i, FILE * fd)
{
uint8_t y[4];
y[0] = i % 0x100;
y[1] = (i >> 8) % 0x100;
y[2] = (i >> 16) % 0x100;
y[3] = (i >> 24) % 0x100;
size_t i1_err = fwrite(y , 1, 4, fd);
}
//
// Writes 2 uint32_t in Big Endian at current file position
//
static void inline print_2quartet(unsigned long i, unsigned long j, FILE * fd)
{
uint8_t y[8];
y[0] = i % 0x100;
y[1] = (i >> 8) % 0x100;
y[2] = (i >> 16) % 0x100;
y[3] = (i >> 24) % 0x100;
y[4] = j % 0x100;
y[5] = (j >> 8) % 0x100;
y[6] = (j >> 16) % 0x100;
y[7] = (j >> 24) % 0x100;
size_t i1_err = fwrite(y , 1, 8, fd);
}
static esp_err_t config_camera() {
camera_config_t config;
//Serial.println("config camera");
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.fb_location = CAMERA_FB_IN_PSRAM;
//config.grab_mode = CAMERA_GRAB_WHEN_EMPTY;
config.xclk_freq_hz = 20000000; // 10000000 or 20000000 -- 10 is faster !!
config.pixel_format = PIXFORMAT_JPEG;
config.frame_size = FRAMESIZE_HD; // edit in framesizes below -- this must be better than the framesize specified at the top
/*
FRAMESIZE_96X96, // 96x96
FRAMESIZE_QQVGA, // 160x120
FRAMESIZE_QCIF, // 176x144
FRAMESIZE_HQVGA, // 240x176
FRAMESIZE_240X240, // 240x240
FRAMESIZE_QVGA, // 320x240
FRAMESIZE_CIF, // 400x296
FRAMESIZE_HVGA, // 480x320
FRAMESIZE_VGA, // 640x480
FRAMESIZE_SVGA, // 800x600
FRAMESIZE_XGA, // 1024x768
FRAMESIZE_HD, // 1280x720
FRAMESIZE_SXGA, // 1280x1024
FRAMESIZE_UXGA, // 1600x1200
*/
config.jpeg_quality = 6; // 1 to 63 - smaller number is higher quality and more data - must be lower rhat the quality parameter at the top
config.fb_count = 7;
// camera init
cam_err = esp_camera_init(&config);
if (cam_err != ESP_OK) {
Serial.printf("Camera init failed with error 0x%x", cam_err);
}
sensor_t * ss = esp_camera_sensor_get();
ss->set_quality(ss, quality);
ss->set_framesize(ss, (framesize_t)framesize);
ss->set_brightness(ss, 1); //up the blightness just a bit
ss->set_saturation(ss, -2); //lower the saturation
delay(500);
for (int j = 0; j < 5; j++) {
camera_fb_t * fb = esp_camera_fb_get();
//Serial.print("Pic, len="); Serial.println(fb->len);
esp_camera_fb_return(fb);
delay(50);
}
}
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;
diskspeed = host.max_freq_khz;
sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT();
slot_config.width = 1; // using 1 bit mode
slot_config.clk = GPIO_NUM_39; // CLK 引脚
slot_config.cmd = GPIO_NUM_38; // CMD 引脚
slot_config.d0 = GPIO_NUM_40; // Data 0 引脚
esp_vfs_fat_sdmmc_mount_config_t mount_config = {
.format_if_mount_failed = false,
.max_files = 8,
};
sdmmc_card_t *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));
}
sdmmc_card_print_info(stdout, card);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// get_good_jpeg() - take a picture and make sure it has a good jpeg
//
camera_fb_t * get_good_jpeg() {
camera_fb_t * fb;
do {
bp = millis();
fb = esp_camera_fb_get();
totalp = totalp + millis() - bp;
int x = fb->len;
int foundffd9 = 0;
for (int j = 1; j <= 1025; j++) {
if (fb->buf[x - j] != 0xD9) {
// no d9, try next for
} else {
//Serial.println("Found a D9");
if (fb->buf[x - j - 1] == 0xFF ) {
//Serial.print("Found the FFD9, junk is "); Serial.println(j);
if (j == 1) {
normal_jpg++;
} else {
extend_jpg++;
}
if (j > 1000) { // never happens. but > 1 does, usually 400-500
Serial.print("Frame "); Serial.print(frame_cnt);
Serial.print(", Len = "); Serial.print(x);
Serial.print(", Corrent Len = "); Serial.print(x - j + 1);
Serial.print(", Extra Bytes = "); Serial.println( j - 1);
}
foundffd9 = 1;
break;
}
}
}
if (!foundffd9) {
bad_jpg++;
Serial.print("Bad jpeg, Len = "); Serial.println(x);
esp_camera_fb_return(fb);
} else {
break;
// count up the useless bytes
}
} while (1);
return fb;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// eprom functions - increment the file_group, so files are always unique
//
#include <EEPROM.h>
struct eprom_data {
int eprom_good;
int file_group;
};
void do_eprom_read() {
eprom_data ed;
EEPROM.begin(200);
EEPROM.get(0, ed);
if (ed.eprom_good == MagicNumber) {
Serial.println("Good settings in the EPROM ");
file_group = ed.file_group;
file_group++;
Serial.print("New File Group "); Serial.println(file_group );
} else {
Serial.println("No settings in EPROM - Starting with File Group 1 ");
file_group = 1;
}
do_eprom_write();
file_number = 1;
}
void do_eprom_write() {
eprom_data ed;
ed.eprom_good = MagicNumber;
ed.file_group = file_group;
Serial.println("Writing to EPROM ...");
EEPROM.begin(200);
EEPROM.put(0, ed);
EEPROM.commit();
EEPROM.end();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Make the avi functions
//
// 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
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// start_avi - open the files and write in headers
//
static esp_err_t start_avi() {
Serial.println("Starting an avi ");
sprintf(fname, "/sdcard/%s %d.%d + %ds.avi", devname, file_group, file_number, (millis() - boot_time) / 1000);
file_number++;
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");
}
if (idxfile != NULL) {
Serial.printf("File open: %s\n", "/sdcard/idx.tmp");
} else {
Serial.println("Could not open file");
}
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 == 9) {
fseek(avifile, 0x40, SEEK_SET);
err = fwrite(sxga_w, 1, 2, avifile);
fseek(avifile, 0xA8, SEEK_SET);
err = fwrite(sxga_w, 1, 2, avifile);
fseek(avifile, 0x44, SEEK_SET);
err = fwrite(sxga_h, 1, 2, avifile);
fseek(avifile, 0xAC, SEEK_SET);
err = fwrite(sxga_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(avi_length);
Serial.println(" seconds.");
startms = millis();
totalp = 0;
totalw = 0;
jpeg_size = 0;
movi_size = 0;
uVideoLen = 0;
idx_offset = 4;
frame_cnt = 0;
bad_jpg = 0;
extend_jpg = 0;
normal_jpg = 0;
} // end of start avi
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// another_save_avi saves another frame to the avi file, uodates index
// -- pass in a fb pointer to the frame to add
//
//
static esp_err_t another_save_avi(camera_fb_t * fb ) {
int fblen;
fblen = fb->len;
jpeg_size = fblen;
movi_size += jpeg_size;
uVideoLen += jpeg_size;
bw = millis();
size_t dc_err = fwrite(dc_and_zero_buf, 1, 8, avifile);
size_t err = fwrite(fb->buf, 1, fb->len, avifile);
if (err != fb->len) {
Serial.print("Error on avi write: err = "); Serial.print(err);
Serial.print(" len = "); Serial.println(fb->len);
}
remnant = (4 - (jpeg_size & 0x00000003)) & 0x00000003;
print_2quartet(idx_offset, 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 + jpeg_size , SEEK_SET);
totalw = totalw + millis() - bw;
} // end of another_pic_avi
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// end_avi writes the index, and closes the files
//
static esp_err_t end_avi() {
unsigned long current_end = 0;
current_end = ftell (avifile);
Serial.println("End of avi - closing the files");
elapsedms = millis() - startms;
float fRealFPS = (1000.0f * (float)frame_cnt) / ((float)elapsedms);
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( 1.0 * totalp / frame_cnt);
Serial.print("Average write time (ms) "); Serial.println( totalw / frame_cnt );
Serial.print("Normal jpg % "); Serial.println( 100.0 * normal_jpg / frame_cnt, 1 );
Serial.print("Extend jpg % "); Serial.println( 100.0 * extend_jpg / frame_cnt, 1 );
Serial.print("Bad jpg % "); Serial.println( 100.0 * bad_jpg / frame_cnt, 1 );
Serial.printf("Writng the index, %d frames\n", frame_cnt);
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 index file");
}
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("---");
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void setup() {
Serial.begin(115200);
Serial.println("\n\n---");
//Serial.setDebugOutput(true);
// zzz
Serial.println(" ");
Serial.println("-------------------------------------");
Serial.printf("ESP32-CAM-Video-Recorder-junior %s\n", vernum);
Serial.println("-------------------------------------");
Serial.print("setup, core "); Serial.print(xPortGetCoreID());
Serial.print(", priority = "); Serial.println(uxTaskPriorityGet(NULL));
// put your setup code here, to run once:
Serial.printf("Internal Total heap %d, internal Free Heap %d\n", ESP.getHeapSize(), ESP.getFreeHeap());
Serial.printf("SPIRam Total heap %d, SPIRam Free Heap %d\n", ESP.getPsramSize(), ESP.getFreePsram());
Serial.println("Setting up the camera ...");
config_camera();
Serial.println("camera after config");
Serial.printf("Internal Total heap %d, internal Free Heap %d\n", ESP.getHeapSize(), ESP.getFreeHeap());
Serial.printf("SPIRam Total heap %d, SPIRam Free Heap %d\n", ESP.getPsramSize(), ESP.getFreePsram());
// SD camera init
esp_err_t card_err = init_sdcard();
if (card_err != ESP_OK) {
Serial.printf("SD Card init failed with error 0x%x", card_err);
return;
}
Serial.printf("Internal Total heap %d, internal Free Heap %d\n", ESP.getHeapSize(), ESP.getFreeHeap());
Serial.printf("SPIRam Total heap %d, SPIRam Free Heap %d\n", ESP.getPsramSize(), ESP.getFreePsram());
Serial.println("Warming up the camera ... here are some frames sizes ...");
for (int i = 0; i < 10; i++) {
camera_fb_t * fb = esp_camera_fb_get();
Serial.printf("frame %d, len %d\n", i, fb->len);
esp_camera_fb_return(fb);
delay(100);
}
do_eprom_read();
Serial.println(" End of setup()\n\n");
boot_time = millis();
}
int first = 1;
int frames = 0;
long frame_start = 0;
long frame_end = 0;
long frame_total = 0;
long frame_average = 0;
long loop_average = 0;
long loop_total = 0;
long total_frame_data = 0;
long last_frame_length = 0;
int done = 0;
long avi_start_time = 0;
long avi_end_time = 0;
int stop = 1;
int we_are_already_stopped = 0;
void loop() {
if (first) {
Serial.print("the loop, core "); Serial.print(xPortGetCoreID());
Serial.print(", priority = "); Serial.println(uxTaskPriorityGet(NULL));
first = 0;
}
frames++;
frame_cnt = frames;
if (frames == 1 ) { // start the avi
if (stop == 0) {
if (we_are_already_stopped == 0) Serial.println("\n\nCannot start video, as Pin 12 is connected to GND\n\n");
frames--;
we_are_already_stopped = 1;
delay(1000);
} else {
we_are_already_stopped = 0;
avi_start_time = millis();
Serial.printf("Start the avi ... at %d\n", avi_start_time);
fb_curr = get_good_jpeg(); // should take zero time
start_avi();
fb_next = get_good_jpeg(); // should take nearly zero time due to time spent writing header
another_save_avi( fb_curr); // put first frame in avi
esp_camera_fb_return(fb_curr); // get rid of first frame
}
} else if ( stop == 0 || millis() > (avi_start_time + avi_length * 1000)) { // end the avi
fb_curr = fb_next;
another_save_avi(fb_curr); // save final frame of avi
esp_camera_fb_return(fb_curr);
end_avi(); // end the movie
avi_end_time = millis();
float fps = frames / ((avi_end_time - avi_start_time) / 1000) ;
Serial.printf("End the avi at %d. It was %d frames, %d ms at %.1f fps...\n", millis(), frames, avi_end_time, avi_end_time - avi_start_time, fps);
frames = 0; // start recording again on the next loop
} else { // another frame of the avi
fb_curr = fb_next; // we will write a frame, and get the camera preparing a new one
fb_next = get_good_jpeg(); // should take near zero, unless the sd is faster than the camera, when we will have to wait for the camera
another_save_avi(fb_curr);
esp_camera_fb_return(fb_curr);
if (frames % 100 == 0 ) { // print some status every 100 frames
float fps = 1.0 * frames / ((millis() - avi_start_time) / 1000) ;
Serial.printf("So far: %d frames, %d ms at %.2f fps...\n", frames, millis() - avi_start_time, fps);
}
}
}
Try lowering fb count to 3 (maybe 4), and quality up to 12, and do a print statement after the camera_init line to see if that is where it is stuck.
Change like this? It seems that there is a problem with the following parts:
You could change from size from UXGA to HD, just above the fb_count change, and include that serial print after the fb_get line ... that will tell you if the camera is working. Otherwise you will have to pin down which of those 3-4 lines is causing the problem.
After that you will need to look at the init_sdcard code to see how much of it is running before it stops. I see you are setting the gpios there. Are you using a freenove-cam-s3 board definitiions? I think they would be set there, but dont see any board definitions on my arduino ide.
I assume there is no more serial output after the "after camera init" line? No garbage or anything printed? The serial output might be disturbed.
Thanks for your response. Yes,there is no more serial output after the "after camera init" line. And I have found something new,it is stuck here. And after I comment out.It show this.
/*
for (int j = 0; j < 5; j++) {
camera_fb_t * fb = esp_camera_fb_get();
Serial.print("Pic, len="); Serial.println(fb->len);
esp_camera_fb_return(fb);
delay(50);
}
*/
-------------------------------------
ESP32-CAM-Video-Recorder-junior v02
-------------------------------------
setup, core 1, priority = 1
Internal Total heap 393444, internal Free Heap 363584
SPIRam Total heap 8388608, SPIRam Free Heap 8385412
Setting up the camera ...
after camera initGuru Meditation Error: Core 1 panic'ed (IllegalInstruction). Exception was unhandled.
Memory dump at 0x420029b8: 8565f4a1 00000002 31004136
Core 1 register dump:
PC : 0x420029bd PS : 0x00060030 A0 : 0x82006ea6 A1 : 0x3fcebf20
A2 : 0x3fcec9c0 A3 : 0x420164a8 A4 : 0x00800000 A5 : 0x00000001
A6 : 0xffffffff A7 : 0x3fc93398 A8 : 0x820029bd A9 : 0x3fcebf00
A10 : 0x000001f4 A11 : 0x3c04c081 A12 : 0x0000000f A13 : 0x3c04c081
A14 : 0x00000000 A15 : 0x00000026 SAR : 0x0000001a EXCCAUSE: 0x00000000
EXCVADDR: 0x00000000 LBEG : 0x40056f5c LEND : 0x40056f72 LCOUNT : 0xffffffff
Backtrace: 0x420029ba:0x3fcebf20 0x42006ea3:0x3fcebfc0 0x4037df2e:0x3fcebfe0
I add more print to know where is the problem.
static esp_err_t config_camera() {
camera_config_t config;
//Serial.println("config camera");
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.fb_location = CAMERA_FB_IN_PSRAM;
config.grab_mode = CAMERA_GRAB_LATEST;
config.xclk_freq_hz = 20000000; // 10000000 or 20000000 -- 10 is faster !!
config.pixel_format = PIXFORMAT_JPEG;
config.frame_size = FRAMESIZE_HD; // edit in framesizes below -- this must be better than the framesize specified at the top
/*
FRAMESIZE_96X96, // 96x96
FRAMESIZE_QQVGA, // 160x120
FRAMESIZE_QCIF, // 176x144
FRAMESIZE_HQVGA, // 240x176
FRAMESIZE_240X240, // 240x240
FRAMESIZE_QVGA, // 320x240
FRAMESIZE_CIF, // 400x296
FRAMESIZE_HVGA, // 480x320
FRAMESIZE_VGA, // 640x480
FRAMESIZE_SVGA, // 800x600
FRAMESIZE_XGA, // 1024x768
FRAMESIZE_HD, // 1280x720
FRAMESIZE_SXGA, // 1280x1024
FRAMESIZE_UXGA, // 1600x1200
*/
config.jpeg_quality = 12; // 1 to 63 - smaller number is higher quality and more data - must be lower rhat the quality parameter at the top
config.fb_count = 2;
// camera init
cam_err = esp_camera_init(&config);
if (cam_err != ESP_OK) {
Serial.printf("Camera init failed with error 0x%x", cam_err);
}
Serial.printf("after camera init");
sensor_t * ss = esp_camera_sensor_get();
ss->set_quality(ss, quality);
ss->set_framesize(ss, (framesize_t)framesize);
ss->set_brightness(ss, 1); //up the blightness just a bit
ss->set_saturation(ss, 0); //lower the saturation
delay(500);
for (int z = 0; z < 5; z++) {
camera_fb_t * fb = esp_camera_fb_get();
Serial.print("Pic, len="); Serial.println(fb->len);
esp_camera_fb_return(fb);
delay(50);
}
Serial.print("after return test finish");
}
void setup() {
Serial.begin(115200);
Serial.println("\n\n---");
//Serial.setDebugOutput(true);
// zzz
Serial.println(" ");
Serial.println("-------------------------------------");
Serial.printf("ESP32-CAM-Video-Recorder-junior %s\n", vernum);
Serial.println("-------------------------------------");
Serial.print("setup, core "); Serial.print(xPortGetCoreID());
Serial.print(", priority = "); Serial.println(uxTaskPriorityGet(NULL));
// put your setup code here, to run once:
Serial.printf("Internal Total heap %d, internal Free Heap %d\n", ESP.getHeapSize(), ESP.getFreeHeap());
Serial.printf("SPIRam Total heap %d, SPIRam Free Heap %d\n", ESP.getPsramSize(), ESP.getFreePsram());
Serial.println("Setting up the camera ...");
config_camera();
Serial.println("after camera config");
Serial.printf("Internal Total heap %d, internal Free Heap %d\n", ESP.getHeapSize(), ESP.getFreeHeap());
Serial.printf("SPIRam Total heap %d, SPIRam Free Heap %d\n", ESP.getPsramSize(), ESP.getFreePsram());
// SD camera init
esp_err_t card_err = init_sdcard();
if (card_err != ESP_OK) {
Serial.printf("SD Card init failed with error 0x%x", card_err);
return;
}
Serial.printf("Internal Total heap %d, internal Free Heap %d\n", ESP.getHeapSize(), ESP.getFreeHeap());
Serial.printf("SPIRam Total heap %d, SPIRam Free Heap %d\n", ESP.getPsramSize(), ESP.getFreePsram());
Serial.println("Warming up the camera ... here are some frames sizes ...");
for (int i = 0; i < 10; i++) {
camera_fb_t * fb = esp_camera_fb_get();
Serial.printf("frame %d, len %d\n", i, fb->len);
esp_camera_fb_return(fb);
delay(100);
}
do_eprom_read();
Serial.println(" End of setup()\n\n");
boot_time = millis();
}
-------------------------------------
ESP32-CAM-Video-Recorder-junior v02
-------------------------------------
setup, core 1, priority = 1
Internal Total heap 393444, internal Free Heap 363584
SPIRam Total heap 8388608, SPIRam Free Heap 8385412
Setting up the camera ...
after camera initPic, len=5076
Pic, len=5076
Pic, len=5076
Pic, len=5074
Pic, len=5074
after return test finishGuru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled.
Core 1 register dump:
PC : 0x420029fa PS : 0x00060030 A0 : 0x82006ee2 A1 : 0x3fcebf20
A2 : 0x3fc97450 A3 : 0x00000000 A4 : 0x3c060d48 A5 : 0x00000001
A6 : 0xffffffff A7 : 0x3fc93398 A8 : 0x820029fa A9 : 0x3fcebf00
A10 : 0x00000018 A11 : 0x3c0402c4 A12 : 0x0000000a A13 : 0x3c04c0a1
A14 : 0x00000000 A15 : 0x00000026 SAR : 0x0000001a EXCCAUSE: 0x0000001c
EXCVADDR: 0x82006ee0 LBEG : 0x400556d5 LEND : 0x400556e5 LCOUNT : 0xfffffff9
Backtrace: 0x420029f7:0x3fcebf20 0x42006edf:0x3fcebfc0 0x4037df2e:0x3fcebfe0
If that for loop does not work, that means the memory is scrambled up - something is dumping random information in ram.
You could use exception decoder to see what it is doing when your get the illegal instruction or load prohibited.
https://github.com/me-no-dev/EspExceptionDecoder
And the frames are too small and all the same size ... so camera is not working and memory is scrambled.
You might try taking your working example, and adding in some code to mount the sd card, and then add some code to write the avi, ... all on top of the working example, that does not have the scrambled memory.
Thank you for your patience and answer. I want to try using V60. After I modified the camera and SD card pins and deleted the redundant pin settings, I got an error in "new_simple.print(config_txt);": "Compilation error : 'config_txt' was not declared in this scope"
You have to frag all the files into the arduino ide, like this:
My bad, I missed one. After that I get an error when I run it and I can't find the cause of the problem: Edit:Never mind.After I increasing the depth of the stack it fix!! I think my last question is where should I add the sensor's judgment conditions and continuously read the sensor to control the recording? My idea is to continuously detect the sensor value. If it is greater than the condition, record for 10 seconds and then judge again. If the condition is met, continue recording. If not, end the recording and storage. , repeat the above actions.
Here are some changes,it work?:
void the_camera_loop (void* pvParameter) {
Serial.print("the camera loop, core "); Serial.print(xPortGetCoreID());
Serial.print(", priority = "); Serial.println(uxTaskPriorityGet(NULL));
frame_cnt = 0;
start_record = 0;
time_for_stop= 0;
delay(1000);
while (1) {
// if (frame_cnt == 0 && start_record == 0) // do nothing
// if (frame_cnt == 0 && start_record == 1) // start a movie
// if (frame_cnt > 0 && start_record == 0) // stop the movie
// if (frame_cnt > 0 && start_record != 0) // another frame
/////////////////// NOTHING TO DO //////////////////
if (frame_cnt == 0 && start_record == 0) {
Serial.println("Do nothing");
if (we_are_already_stopped == 0) Serial.println("\n\nDisconnect Pin 12 from GND to start recording.\n\n");
we_are_already_stopped = 1;
delay(100);
/////////////////// START A MOVIE //////////////////
} else if (frame_cnt == 0 && start_record == 1) {
//Serial.println("Ready to start");
we_are_already_stopped = 0;
//delete_old_stuff(); // move to loop
avi_start_time = millis();
Serial.printf("\nStart the avi ... at %d\n", avi_start_time);
Serial.printf("Framesize %d, quality %d, length %d seconds\n\n", framesize, quality, avi_length);
logfile.printf("\nStart the avi ... at %d\n", avi_start_time);
logfile.printf("Framesize %d, quality %d, length %d seconds\n\n", framesize, quality, avi_length);
logfile.flush();
frame_cnt++;
long wait_for_cam_start = millis();
fb_curr = get_good_jpeg(); // should take zero time
wait_for_cam += millis() - wait_for_cam_start;
Serial.printf("Remaining stack: %d\n", uxTaskGetStackHighWaterMark(NULL));
start_avi();
wait_for_cam_start = millis();
fb_next = get_good_jpeg(); // should take nearly zero time due to time spent writing header
//if (framebuffer_time < (millis() - 10)){
xSemaphoreTake( baton, portMAX_DELAY );
framebuffer_len = fb_next->len; // v59.5
memcpy(framebuffer, fb_next->buf, fb_next->len); // v59.5
framebuffer_time = millis(); // v59.5
xSemaphoreGive( baton );
//}
wait_for_cam += millis() - wait_for_cam_start;
xSemaphoreGive( sd_go ); // trigger sd write to write first frame
/////////////////// END THE MOVIE //////////////////
} else if ( restart_now || reboot_now || (frame_cnt > 0 && start_record == 0) || time_for_stop==1 ) { // end the avi
Serial.println("End the Avi");
restart_now = false;
xSemaphoreTake( wait_for_sd, portMAX_DELAY );
esp_camera_fb_return(fb_curr);
frame_cnt++;
fb_curr = fb_next;
fb_next = NULL;
xSemaphoreGive( sd_go ); // save final frame of movie
xSemaphoreTake( wait_for_sd, portMAX_DELAY ); // wait for final frame of movie to be written
esp_camera_fb_return(fb_curr);
fb_curr = NULL;
end_avi(); // end the movie
delete_old_stuff_flag = 1;
delay(50);
avi_end_time = millis();
float fps = 1.0 * frame_cnt / ((avi_end_time - avi_start_time) / 1000) ;
Serial.printf("End the avi at %d. It was %d frames, %d ms at %.2f fps...\n", millis(), frame_cnt, avi_end_time, avi_end_time - avi_start_time, fps);
logfile.printf("End the avi at %d. It was %d frames, %d ms at %.2f fps...\n", millis(), frame_cnt, avi_end_time, avi_end_time - avi_start_time, fps);
if (!reboot_now) frame_cnt = 0; // start recording again on the next loop
start_record=0;
int extime=0;
void loop() {
long run_time = millis() - boot_time;
GetAcceleration();
float ax=rax/16384;
float ay=ray/16384;
float az=raz/16384;
float vector = sqrt(ax*ax + ay*ay + az*az);
if (delete_old_stuff_flag == 1) {
delete_old_stuff_flag = 0;
delete_old_stuff();
}
if (abs(vector-last_vector)>=deltalimit_acceleration ) {
start_record = 1;
}
if (millis()>(avi_start_time + avi_length * 1000)+extime){
if (abs(vector-last_vector)<deltalimit_acceleration){
time_for_stop=1;
}else{
time_for_stop=0;
extime+=1000;
}
}
last_vector=vector;
By the way, I really appreciate your help, so I bought you a cup of coffee, please enjoy
I got one of those modules.
The changes are the camera gpio, the sd gpio, the stack business needs some more bytes, enable the psram, and disable the brownout changes.
You seem to have solved it, so I wont post for now.
Regarding the record on event things. You can check your readings every run through the loop, and set the start_record flag. Or if your device has a interrupt you can control the start_record flag from the interrupt handler.
There is some code here:
The loop is simpler and plenty fast, as the next photo is 80 ms at HD, so the very loop will run plenty of times every 80ms.
All functions are working normally. Thank you again for your help. However, I want to increase the frame rate of recording, so I am interested in enabling the psram. Can you elaborate on it? Currently, my picture quality is set to HD, and I added "config.grab_mode = CAMERA_GRAB_LATEST;" "config.fb_location = CAMERA_FB_IN_PSRAM;" (but it seems there is no change). The number of frames recorded is about 10fps. I want to know if it can be increased to about 25.
Psram does not make it faster ... it is slower than regular ram, but not really relevant as the bottleneck is the camera or the sd card, or sometimes the esp32 processor speed.
To eanble the psram, set the setting below.
The camera can operate at 12.5 fps is HD, or 25 fps SVGA (800X600) or below, and 50 fps CIF (400x296) or below. You could get an ov5640 that works with the esp32, which will give you better resolution and about twice the speed ... 24 fps HD, but you will run into the sd card bottleneck at some point, which may or may not improve with faster sd cards.
The sd card can usually keep up with the ov2640 rates, but some sd csrds are slower, or if the sd is fragmented, or other processing on the esp32 (like streaming or downloading videos) can slow things down.
I fixed that little program you were using originally - I can post that if you like. It still has some old code, so I was thinking of rewriting it to make it very simple.
Got it, thank you for your answer, I really appreciate your help, I will close this issues since there are no more questions.
I am a beginner and try to modify the version you have released. I can successfully upload,but not working and the serial monitor shows I modified "avi_length=10", camera pin,deleted major_fail(), deleted the part controlled by pin12 and set "stop=1" (this should automatically stop recording after 10 seconds), add " config.fb_location = CAMERA_FB_IN_PSRAM; config.grab_mode = CAMERA_GRAB_WHEN_EMPTY;".attached the modified file , thank you in advance for your answer.