admin管理员组

文章数量:1334826

I have an Ai-Thinker ESP32-CAM board with an OV2640 camera. I'm trying to build a project (details are not relevant) in which I need to take pictures (jpeg) at a certain frame rate (30fps+) and process them.

The code here is simple. I'm taking pictures with a certain delay - then free the buffer. The problem is when I point my camera at something bright or change the scene and monitor my stack with Serial.printf("Free Stack: %u bytes\n", uxTaskGetStackHighWaterMark(NULL)); I see that there is a memory leak. If the scene changes too often the stack is overflowed in a matter of minutes. My question is what I'm doing wrong that there is a memory leak? Am I missing something?

#include "esp_camera.h"

#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

camera_fb_t *frameBuffer = NULL;

void setup() {

  Serial.begin(115200);
  Serial.printf("\r\n");
  Serial.printf("Before camera init:\r\n");
  Serial.printf("Free DRAM: %u bytes\r\n", heap_caps_get_free_size(MALLOC_CAP_8BIT));
  Serial.printf("Free PSRAM: %u bytes\r\n", heap_caps_get_free_size(MALLOC_CAP_SPIRAM));

  initialize_camera();

  Serial.printf("\r\n");
  Serial.printf("After camera init:\r\n");
  Serial.printf("Free DRAM: %u bytes\r\n", heap_caps_get_free_size(MALLOC_CAP_8BIT));
  Serial.printf("Free PSRAM: %u bytes\r\n", heap_caps_get_free_size(MALLOC_CAP_SPIRAM));

  delay(5000);
}

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

  if (!frameBuffer) {
    Serial.println("Failed to capture frame");
    delay(100);
    return;
  }

  vTaskDelay(pdMS_TO_TICKS(10));

  if (frameBuffer) {
    esp_camera_fb_return(frameBuffer);
    frameBuffer = NULL;
  }

  vTaskDelay(pdMS_TO_TICKS(20));

  if (!heap_caps_check_integrity(MALLOC_CAP_8BIT, true)) {
    Serial.println("Heap integrity check failed \r\n");
  }

  Serial.printf("Free Stack: %u bytes\n", uxTaskGetStackHighWaterMark(NULL));
  Serial.printf("\r\n");
}



void initialize_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 = 20000000;
  config.frame_size = FRAMESIZE_QQVGA;
  config.pixel_format = PIXFORMAT_JPEG;

  if (psramFound()) {
    Serial.print("Using psram \n\r");

    config.jpeg_quality = 5;
    config.fb_count = 2;
    config.grab_mode = CAMERA_GRAB_LATEST;
    config.fb_location = CAMERA_FB_IN_PSRAM;
  } else {
    Serial.print("Using dram. Exiting \n\r");

    return;
  }

  esp_err_t err = esp_camera_init(&config);
  if (err != ESP_OK) {
    Serial.printf("Сamera error: 0x%x", err);
    return;
  }

  Serial.print("Camera initialized \n\r");
}

I have an Ai-Thinker ESP32-CAM board with an OV2640 camera. I'm trying to build a project (details are not relevant) in which I need to take pictures (jpeg) at a certain frame rate (30fps+) and process them.

The code here is simple. I'm taking pictures with a certain delay - then free the buffer. The problem is when I point my camera at something bright or change the scene and monitor my stack with Serial.printf("Free Stack: %u bytes\n", uxTaskGetStackHighWaterMark(NULL)); I see that there is a memory leak. If the scene changes too often the stack is overflowed in a matter of minutes. My question is what I'm doing wrong that there is a memory leak? Am I missing something?

#include "esp_camera.h"

#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

camera_fb_t *frameBuffer = NULL;

void setup() {

  Serial.begin(115200);
  Serial.printf("\r\n");
  Serial.printf("Before camera init:\r\n");
  Serial.printf("Free DRAM: %u bytes\r\n", heap_caps_get_free_size(MALLOC_CAP_8BIT));
  Serial.printf("Free PSRAM: %u bytes\r\n", heap_caps_get_free_size(MALLOC_CAP_SPIRAM));

  initialize_camera();

  Serial.printf("\r\n");
  Serial.printf("After camera init:\r\n");
  Serial.printf("Free DRAM: %u bytes\r\n", heap_caps_get_free_size(MALLOC_CAP_8BIT));
  Serial.printf("Free PSRAM: %u bytes\r\n", heap_caps_get_free_size(MALLOC_CAP_SPIRAM));

  delay(5000);
}

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

  if (!frameBuffer) {
    Serial.println("Failed to capture frame");
    delay(100);
    return;
  }

  vTaskDelay(pdMS_TO_TICKS(10));

  if (frameBuffer) {
    esp_camera_fb_return(frameBuffer);
    frameBuffer = NULL;
  }

  vTaskDelay(pdMS_TO_TICKS(20));

  if (!heap_caps_check_integrity(MALLOC_CAP_8BIT, true)) {
    Serial.println("Heap integrity check failed \r\n");
  }

  Serial.printf("Free Stack: %u bytes\n", uxTaskGetStackHighWaterMark(NULL));
  Serial.printf("\r\n");
}



void initialize_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 = 20000000;
  config.frame_size = FRAMESIZE_QQVGA;
  config.pixel_format = PIXFORMAT_JPEG;

  if (psramFound()) {
    Serial.print("Using psram \n\r");

    config.jpeg_quality = 5;
    config.fb_count = 2;
    config.grab_mode = CAMERA_GRAB_LATEST;
    config.fb_location = CAMERA_FB_IN_PSRAM;
  } else {
    Serial.print("Using dram. Exiting \n\r");

    return;
  }

  esp_err_t err = esp_camera_init(&config);
  if (err != ESP_OK) {
    Serial.printf("Сamera error: 0x%x", err);
    return;
  }

  Serial.print("Camera initialized \n\r");
}
Share Improve this question asked Nov 20, 2024 at 19:41 Vitaliy OliynykVitaliy Oliynyk 511 silver badge2 bronze badges 3
  • 2 Please edit the question to include the output of the program that indicates there’s a memory leak. – romkey Commented Nov 21, 2024 at 0:44
  • Are you sure there is a memory leak? Different jpeg frames require different amount of memory to be stored. The library may allocate not enough buffer space initially and expand buffer at runtime, when required. – dimich Commented Nov 21, 2024 at 5:30
  • Also task delay between esp_camera_fb_get() and esp_camera_fb_return() looks suspicious. – dimich Commented Nov 21, 2024 at 6:04
Add a comment  | 

1 Answer 1

Reset to default 0

There is several tips that help you to solve your porblem

  1. Set camera clock to 10Mhz
config.xclk_freq_hz = 10000000;

I tested for fix my WDT problem

  1. Reduce Frame JPEG quality from 5 to 10 or even 20
config.jpeg_quality = 10;
  1. Increase fb_count to make sure you have enough buffer
config.fb_count = 30;
  1. Reduce your delays in loop function to under 1ms

  2. Make sure you configure your board correct in Arduino and use stable firmware, enable PSRAM

  3. If all above steps didn't fix your problem test CameraWebServer example with your test condition to make sure it's your code problem not project configuration or board or something else

本文标签: cESP32CAM Memory leaks when calling espcamerafbget()Stack Overflow