Page 1 of 1

[SOLVED] ESP32 Cam - corrupted big images

Posted: Tue Mar 23, 2021 1:22 am
by solisqq
Hi,
Im up to get an image from camera to ESP32-CAM and send it via TCP to my PC. This works fine as long as picture is not too big. If I go any higher than SVGA and quality=6 I get corrupted JPEG.
Ive tested a lot of solutions from this site (and not only) without success.
I suspect the problem is with PSRAM or with communication between cam and esp.
Few things to note:
- WebServer example works fine
- Max quality I can get is with specs below:

Code: Select all

config.xclk_freq_hz = 15000000;
config.pixel_format = PIXFORMAT_JPEG;
config.frame_size = FRAMESIZE_SVGA; //TEST
config.jpeg_quality = 6;
config.fb_count = 1;
- There is no difference if I use this settings with PSRAM disabled or enabled - it works fine
- If I want to get better quality or bigger frame_size problems occur: If PSRAM is enabled JPEG is corrupted. If PSRAM is disabled camera fails to take a picture (or init fails)
- Ive noticed that if I change quality (jpeg_quality=5 for example) and I take picture of basic scene (wall/a lot of dark) this image might be smaller size than lower quality but with advanced scene with a lot of changes. Still this lesser size image with better quality is corrupted and the other one is fine...


Specs:
- ESP32 Cam
- OV2640
- Arduino IDE

Capturing:

Code: Select all

auto fb = esp_camera_fb_get();
if (!fb) Serial.println("Camera capture failed");
else pictureDone.emit(fb);
esp_camera_fb_return(fb);

Code: Select all

uint8_t Camera::init()
{
    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 = 15000000;
    config.pixel_format = PIXFORMAT_JPEG;
    config.frame_size = FRAMESIZE_SVGA; //TEST
    config.jpeg_quality = 6;
    config.fb_count = 1;
    
    esp_err_t err = esp_camera_init(&config);
    while (err != ESP_OK) {
        esp_err_t err = esp_camera_init(&config);
        return 1;
    }

    sensor_t* s = esp_camera_sensor_get();
    if (psramFound()) goutput.info("MEM: " + String(ESP.getPsramSize()));
    else goutput.warning("!PSRAMOFF");
    
    s->set_exposure_ctrl(s, 0); // 0 = disable , 1 = enable
    s->set_aec2(s, 0); // 0 = disable , 1 = enable
    s->set_aec_value(s, 100);
    s->set_framesize(s, FRAMESIZE_SVGA);
    s->set_quality(s,6);
    s->set_pixformat(s, PIXFORMAT_JPEG);
    
    return 0;
}

Re: ESP32 Cam - corrupted big images

Posted: Fri Mar 26, 2021 10:06 am
by solisqq
Ok now I can at least see where the problem is, Ive made short test:

Code: Select all

unsigned int count = img->len;
for (int i = count - 4; i < count; i++) {
	Serial.print(img->buf[i], HEX);
	Serial.print(" ");
}
client.write(img->buf, img->len);
client.flush();
Serial.println("");

for (int i = count - 4; i < count; i++) {
	Serial.print(img->buf[i], HEX);
	Serial.print(" ");
}
Serial.println("");
This example shows last 4 bytes of buffor before and after sending.It seems that when I do client.write() on buffor, buffor changes meanwhile or client.write() changes it.
Its a bit weird, because Im freeing the memory only after Ive had received response from server OR got timeout and im using client.flush() which will make sure that all data was sent before going to next instruction (AFAIK).
What is more weird it happens only with better quality images, but not necessary larger size...

Is is possible that something is messing around with buffor on another core while im sending it?
And why does it happens only to higher quality images even if they are not larger in size?

//EDIT
Ive tested this issue more and im positive that something is messing around with psram on another core. Printing buffor twice after delay(100) gives different results (for the same buffor).
auto pic = esp_camera_fb_get();
print(pic); //0xFF 0xD9 0xFF 0xFA
delay(100);
print(pic); //0x00 0x00 0x00 0x00
Ive tried to put it first in SPIFFS before sending it but without success. SPIFFS either fails to save image correctly.

Re: ESP32 Cam - corrupted big images

Posted: Fri Mar 26, 2021 5:29 pm
by solisqq
I was using GPIO16 which is being used by PSRAM aswell. It was pretty hard to find this bug as most of the program worked...
Please close...

[SOLVED] Re: ESP32 Cam - corrupted big images

Posted: Fri Mar 26, 2021 6:38 pm
by ESP_Minatel
Hi,

Thank you for your feedback. Changing the subject to SOLVED.