ESP32-S3 N16R8 + OV2640 – SCCB works perfectly manually, but esp_camera_init() fails on random register writes

Hello,

I am trying to get an OV2640 camera working with an ESP32-S3-WROOM N16R8 board (16 MB Flash / 8 MB PSRAM).

I have been troubleshooting this extensively and I have reached a strange situation: the OV2640 works perfectly when I communicate with it manually over SCCB/I2C, but esp_camera_init() fails during SCCB register writes.

I would appreciate any advice on what could cause this.

Hardware / pin configuration

According to the documentation/pinout supplied for the board, I am using:

OV2640 / Camera    ESP32-S3 GPIO

--------------------------------

SIOD / SDA GPIO 4

SIOC / SCL GPIO 5

VSYNC GPIO 6

HREF GPIO 7

XCLK GPIO 15

PCLK GPIO 13

Y2 / D0 GPIO 11

Y3 / D1 GPIO 9

Y4 / D2 GPIO 8

Y5 / D3 GPIO 10

Y6 / D4 GPIO 12

Y7 / D5 GPIO 18

Y8 / D6 GPIO 17

Y9 / D7 GPIO 16

PWDN -1

RESET -1

The camera is connected through the board’s FPC camera connector.

Test 1 – SCCB scan without XCLK

Initially I performed an SCCB/I2C scan using:

SDA = GPIO4

SCL = GPIO5

SCCB = 100 kHz

Without XCLK, no device was detected:

Scanning...

NO DEVICES FOUND

Test 2 – SCCB scan with XCLK

I then generated a 20 MHz XCLK on GPIO15 before starting SCCB.

The camera was immediately detected:

XCLK started at 20 MHz

Scanning SCCB bus…

Device found at 0x30

So the OV2640 responds at the expected 7-bit SCCB address 0x30 when XCLK is present.

Test 3 – OV2640 identification

I selected the sensor register bank:

register 0xFF = 0x01

and read the OV2640 identification registers.

I successfully obtained:

PID = 0x26

The sensor can therefore be identified and communicated with.

Test 4 – SCCB read stability

I then performed 100 consecutive PID/VER reads over SCCB at 100 kHz.

Result:

GOOD READS : 100

BAD READS : 0

No SCCB read errors occurred.

Test 5 – SCCB write/read-back stability

I tested repeated register writes using register 0x11, followed by reading the value back.

Result:

GOOD WRITE/READ : 140

BAD WRITE/READ : 0

So normal SCCB writes and reads appear completely stable.

Test 6 – Direct OV2640 initialization sequence

I then manually sent the initial OV2640 register initialization sequence using Wire at 100 kHz, including software reset and the required delay.

Result:

GOOD WRITES : 35

BAD WRITES : 0

PID = 0x26

Every register write succeeded.

This sequence also included registers around the same area where esp_camera had previously failed.

Test 7 – ESP-IDF new I2C master driver

To determine whether Arduino Wire was hiding the problem, I tested the OV2640 directly using the newer ESP-IDF I2C master API:

i2c_new_master_bus()

i2c_master_bus_add_device()

i2c_master_probe()

i2c_master_transmit()

i2c_master_transmit_receive()

Configuration:

Address = 0x30

SCCB/I2C clock = 100 kHz

XCLK = 20 MHz

Result:

Probe 0x30: ESP_OK

PID = 0x26

GOOD READS : 100

BAD READS : 0

GOOD WRITE/READ : 100

BAD WRITE/READ : 0

Therefore the newer ESP-IDF I2C driver can also communicate reliably with this camera.

The problem – esp_camera_init()

When I use the normal ESP32 camera driver:

esp_camera_init(&config);

initialization fails during SCCB writes.

The interesting part is that the failed register changes between attempts.

I have seen:

SCCB_Write Failed addr:0x30, reg:0x23, data:0x00

another time:

SCCB_Write Failed addr:0x30, reg:0x22, data:0x1a

another:

SCCB_Write Failed addr:0x30, reg:0x37, data:0xc3

and with Arduino-ESP32 2.0.17:

SCCB_Write Failed addr:0x30, reg:0x26, data:0x82, ret:-1

camera: Camera probe failed with error 0xffffffff (ESP_FAIL)

Another test failed at:

SCCB_Write Failed addr:0x30, reg:0x61, data:0x70, ret:-1

camera: Camera probe failed with error 0xffffffff (ESP_FAIL)

followed by:

gdma: gdma_disconnect(299): no peripheral is connected to the channel

So it does not consistently fail on one particular OV2640 register.

Arduino versions tested

I originally tested with:

Arduino-ESP32 3.3.11

On that version sccb-ng produced failures such as:

sccb-ng: SCCB_Write Failed ... ret:259

I then downgraded to:

Arduino-ESP32 2.0.17

The problem remains, although the legacy SCCB driver now reports ret:-1.

ESP32-S3 configuration

I am currently using:

Board: ESP32S3 Dev Module

CPU Frequency: 240 MHz

Flash Size: 16 MB

PSRAM: OPI PSRAM

PSRAM is detected successfully:

PSRAM: FOUND

What I have established so far

As far as I can determine:

OV2640 sensor            OK

SCCB address 0x30 OK

GPIO4 SDA OK

GPIO5 SCL OK

GPIO15 XCLK OK

SCCB reads 100/100 OK

SCCB write/read 140/140 OK

Manual init writes 35/35 OK

New IDF I2C driver 100/100 reads + 100/100 writes OK

PID 0x26

PSRAM FOUND

esp_camera_init() FAILS

The most confusing part is that manually writing the OV2640 registers works reliably, but the SCCB implementation used inside esp_camera_init() fails at apparently random points in the initialization sequence.

Questions

Does anyone know what could cause esp_camera_init() / the ESP32 camera SCCB driver to fail like this when direct SCCB communication is completely stable?

In particular:

  1. Is there a known SCCB timing issue with OV2640 + ESP32-S3?
  2. Does the camera driver send the OV2640 register writes too quickly compared with manual Wire transactions?
  3. Should a delay be added between SCCB register writes?
  4. Is there a known issue with the SCCB implementation in Arduino-ESP32 2.0.17 or 3.3.x?
  5. Is there a clean way to make esp_camera use my already-tested SCCB implementation while still using the ESP32-S3 camera DMA/framebuffer driver?
  6. Could XCLK/SCCB timing during camera_probe() explain why manual communication works but esp_camera_init() does not?
  7. Is there anything board-specific regarding RESET/PWDN or camera power sequencing that could produce this exact behavior?

My immediate goal is simply to get one valid JPEG frame from the OV2640. I am not trying to run a web server yet.

Any suggestions for additional tests or a patch to the SCCB/camera driver would be greatly appreciated.

Thank you.


Hi, I have 3 working perfectly and integrated into a frigate. You can see the configuration I made, activating all the RAM and PSRAM, in this link: ESP32S3-CAMERA-N16R8