I’m experiencing an issue with my ESP32‑CAM (AiThinker) module equipped with the OV2640 sensor. My current goal is to capture images in JPEG mode at UXGA resolution (1600×1200) with maximum quality (jpeg_quality = 0). However, when I set jpeg_quality to 0, I frequently encounter errors in JPEG compression - the sensor fails to form a complete JPEG image. The serial logs show repeated “NO-EOI” warnings (indicating that the End-Of-Image marker isn’t present) and eventually a failure to capture the frame.
In contrast, when I use RAW mode (e.g., RGB565) or set JPEG quality to 5 or more, the capture works as expected.
Additional details:
- In RAW mode (e.g., using PIXFORMAT_RGB565), the module captures images correctly – for UXGA (1600×1200), the frame buffer size is approximately 3,840,000 bytes (calculated as 1600 × 1200 × 2).
- In JPEG mode with lower quality settings (e.g., jpeg_quality = 5), the module works stably.
- However, when using maximum quality (jpeg_quality = 0), the OV2640 fails to complete JPEG compression – it does not produce the proper end marker (NO-EOI error), and the frame capture fails.
- I have already adjusted buffer allocation to ensure around 3.95 MB is available, so memory allocation does not seem to be the limiting factor.
- My future goal is to transmit these high-quality JPEG images via an HTTP server so that they can be viewed directly in a browser, and then process these images using Google Vision to extract text that will be forwarded to ChatGPT for further analysis. However, currently - even before HTTP integration - capturing a full JPEG image at maximum quality proves problematic.
- Has anyone experienced issues with the OV2640 failing to complete JPEG compression (NO-EOI errors) at maximum quality (jpeg_quality = 0) in UXGA mode?
- Is this likely an inherent limitation of the OV2640’s built-in JPEG encoder when operating at such high resolution and minimal compression?
- Are there any recommended adjustments (for example, tweaking the XCLK frequency or other timing parameters) that might allow stable JPEG capture at maximum quality?
- If these issues persist due to sensor limitations, would upgrading to a more powerful sensor (e.g., one with a better hardware JPEG encoder, like the OV5640) resolve the problem and support future HTTP transmission reliably?
My current project structure: (it is just very easy project)
- managed_components Folder:
This folder contains the entire official repository code for the esp32-camera component from Espressif.
(I can provide more details if needed, though I believe it is the standard content from the official repository.)
- main Folder:
This folder contains my application code including:
- take_picture.c
- idf_component.yml
- CMakeLists.txt
Code: Select all
/**
* This example takes a picture every 5 seconds and prints its size on the serial monitor.
*/
#include "sdkconfig.h"
#define CONFIG_ESP_WIFI_STATIC_RX_BUFFER_NUM 10
#include <esp_log.h>
#include <esp_system.h>
#include <nvs_flash.h>
#include <sys/param.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_camera.h"
#define portTICK_RATE_MS portTICK_PERIOD_MS
#define CAM_PIN_PWDN 32
#define CAM_PIN_RESET -1
#define CAM_PIN_XCLK 0
#define CAM_PIN_SIOD 26
#define CAM_PIN_SIOC 27
#define CAM_PIN_D7 35
#define CAM_PIN_D6 34
#define CAM_PIN_D5 39
#define CAM_PIN_D4 36
#define CAM_PIN_D3 21
#define CAM_PIN_D2 19
#define CAM_PIN_D1 18
#define CAM_PIN_D0 5
#define CAM_PIN_VSYNC 25
#define CAM_PIN_HREF 23
#define CAM_PIN_PCLK 22
static const char *TAG = "example:take_picture";
#if ESP_CAMERA_SUPPORTED
static camera_config_t camera_config = {
.pin_pwdn = CAM_PIN_PWDN,
.pin_reset = CAM_PIN_RESET,
.pin_xclk = CAM_PIN_XCLK,
.pin_sccb_sda = CAM_PIN_SIOD,
.pin_sccb_scl = CAM_PIN_SIOC,
.pin_d7 = CAM_PIN_D7,
.pin_d6 = CAM_PIN_D6,
.pin_d5 = CAM_PIN_D5,
.pin_d4 = CAM_PIN_D4,
.pin_d3 = CAM_PIN_D3,
.pin_d2 = CAM_PIN_D2,
.pin_d1 = CAM_PIN_D1,
.pin_d0 = CAM_PIN_D0,
.pin_vsync = CAM_PIN_VSYNC,
.pin_href = CAM_PIN_HREF,
.pin_pclk = CAM_PIN_PCLK,
.xclk_freq_hz = 10000000, // also tried to use 20000000
.ledc_timer = LEDC_TIMER_0,
.ledc_channel = LEDC_CHANNEL_0,
.pixel_format = PIXFORMAT_JPEG, //in PIXFORMAT_RGB565 works properly
.frame_size = FRAMESIZE_UXGA,
.jpeg_quality = 0, // in this state it is not working(NO-EOI), but when it is 5 it works properly
// when it is 4 it sometimes has problems, but still working
.fb_count = 1,
.fb_location = CAMERA_FB_IN_PSRAM,
.grab_mode = CAMERA_GRAB_WHEN_EMPTY,
};
static esp_err_t init_camera(void)
{
esp_err_t err = esp_camera_init(&camera_config);
if(err != ESP_OK) {
ESP_LOGE(TAG, "Camera Init Failed with error 0x%x", err);
return err;
}
return ESP_OK;
}
#endif
void app_main(void)
{
#if ESP_CAMERA_SUPPORTED
if(ESP_OK != init_camera()){
return;
}
while(1) {
ESP_LOGI(TAG, "Taking picture...");
camera_fb_t *pic = esp_camera_fb_get();
if(pic) {
ESP_LOGI(TAG, "Picture taken! Its size was: %zu bytes", pic->len);
esp_camera_fb_return(pic);
} else {
ESP_LOGE(TAG, "Camera capture failed");
}
vTaskDelay(5000 / portTICK_RATE_MS);
}
#else
ESP_LOGE(TAG, "Camera support is not available for this chip");
return;
#endif
}
Code: Select all
dependencies:
espressif/esp32-camera:
version: '*'
Code: Select all
idf_component_register(SRCS take_picture.c
PRIV_INCLUDE_DIRS .
PRIV_REQUIRES nvs_flash esp_psram esp_http_server esp_wifi esp_timer)