ESP32CAM, OV2640 and get sensor values problem

After taking say 5-10 pictures I want to try and get the values in
camera_status_t;
save them, go to lightsleep, wakeup on a trigger, recall the values
and hopefully take one frame buffer capture without a green tint.

Using the source code at:

I think that I need to call:
ov2640_detect(int slv_addr, sensor_id_t *id)
and then:
ov2640_init(sensor_t *sensor)

However, I am not able to work out what to put in the call to ov2640_detect()
I have read that the slv_addr is 0x3C, but don't have a clue what to put in as
the 2nd parameter. I read somewhere that sensor_id_t *id might be used if you
have multiple sensors ... I only have one OV2640. Likewise, in ov2640_init()
what is sensor_t *sensor?

I hope that after I am able to detect the sensor that I will then be able to
get all the camera_status_t values.

If this approach is flawed please tell me.
Thank you.

I built a lot of ESP32 cameras, but I have no idea what you want to do. The green tint issue is simply some adjustments to the settings, but I have no clue regarding the status values. Have you looked at the code behind that function?

I have found that taking about 3 pictures removes colour and exposure issues. However, 3 pictures take about 600ms. For vehicles travelling at 30-50KMH getting a good snapshot is difficult, especially when they could be going in either direction.

My "bright" idea was to take 5-10 pictures, save the sensor values and even update them every say 10 minutes, again hoping that taking periodic snapshots would keep those sensor values fairly close to what the current lighting conditions require.

I have read other suggestions for getting rid of green tint, however exposure has also been an issue that "3 pictures" seems to sort.

I have looked at the code in those functions, however things with pointers in them is my weakness.

The AI functionality at esp32.com was very helpful.

// Get the sensor control structure
sensor_t *s = esp_camera_sensor_get();

// Example: Read a sensor register (replace reg_addr and mask as needed)
// int reg_value = s->get_reg(s, reg_addr, mask);

// Get sensor information
camera_sensor_info_t *info = esp_camera_sensor_get_info(&s->id);

// my attempt at printing
printf("Model: %u\n", info->model);
printf("Name: %s\n", info->name);
printf("SCCB address: %x\n", info->sccb_addr);
printf("PID: %x\n", info->pid);
printf("Max Size: %u\n", info->max_size);
printf("Support JPEG?: %u\n", info->support_jpeg);

Model: 1
Name: OV2640
SCCB address: 30 (probably 0x30)
PID: 26 (probably 0x26)
Max Size: 15
Support JPEG?: 1

Not sure about the values. Now the challenge is to print out the contents of the other structs.

Why do you use low-level functions that are NOT intended to be called by user code?

Functions you need starts with “esp_camera_” :

esp_camera_init(...)
esp_camera_sensor_get(...)  ←— get a sensor object with this, call corresponding getter (e.g. sensor→get_awb_gain())

My unfamiliarity with the source code resulted in me diving-down to the low-level. Thanks for the prompt as even looking in esp_camera.h it would have not been obvious how I would get individual sensor values.

sensor_t * esp_camera_sensor_get(void);

/**
 * @brief Save camera settings to non-volatile-storage (NVS)
 *
 * @param key   A unique nvs key name for the camera settings
 */

Appreciate you putting me on the right track.

Where do I find get_awb_gain()?

As in any digital camera, there are settings to adjust hue, saturation, etc. I don't know off the top of my head, but just transfer the raw image and use your post-processing software (Adobe Lightroom) to adjust. If you just transfer the raw, you can always make any adjustments later; if you do it in camera, it's pretty much one and done. I have not taken a JPEG in decades, not even on my iPhone.

It’s part of sensor_t..

sensor_t * s = esp_camera_sensor_get();
 if (s){   
    s->set_awb_gain(s,10);
   }

good luck.. ~q

They all look like ways of setting various parameters, can you query those parameters somehow?

You've already tried a different approach in ESP32CAM and esp_camera_save_to_nvs(), but I'm posting this just in case.

All configuration values ​​are written to the camera's registers via the SCCB (Serial Camera Control Bus) and may be read with get_reg().

There is OV2640 register definition file, but you'll need to look into the datasheet for details.

I haven't actually tried it so I don't know any more details than that.

How do you know that?

Unless it's been overridden individually, the OV2640 standard defines it as follows:

I noticed get_reg() but have not looked into that. I am forming the opinion that it is more likely as my efforts trying other methods are not working.

The comment re slv_addr is 0x3C I think I found using AI.

AI suggested this code:

// Get sensor information
camera_sensor_info_t *info = esp_camera_sensor_get_info(&s->id);

// Print some fields (replace with actual fields from the struct)
printf("Model: %u\n", info->model);
printf("Name: %s\n", info->name);
printf("SCCB address: %x\n", info->sccb_addr);
printf("PID: %x\n", info->pid);
printf("Max Size: %u\n", info->max_size);
printf("Support JPEG?: %u\n", info->support_jpeg);

with the following results:
Model: 1
Name: OV2640
SCCB address: 30 (probably 0x30)
PID: 26 (probably 0x26)
Max Size: 15
Support JPEG?: 1

I will focus on get_reg.

Thanks again for your prompts.

If I do:

sensor_t* s = esp_camera_sensor_get();

int reg_value = s->get_reg(s, 1, 0);
Serial.print("Register value = ");
Serial.print(reg_value);

I get:

Guru Meditation Error: Core  1 panic'ed (LoadProhibited). Exception was unhandled.

Maybe, I haven't worked out how to call get_reg properly.

Looking at the datasheet I think this is a task beyond my skills.

BTW, I found a project on seeedstudio.com which says it uses:

esp_err_t esp_camera_save_to_nvs(const char *key);
esp_err_t esp_camera_load_from_nvs(const char *key);

but I can't find them.

Me too :sweat_smile:

Do you mean these functions?

The values you’re after are already in the sensor_t structure..

sensor_t * s = esp_camera_sensor_get();
 if (s){   
   byte b = s->status.awb_gain;
   Serial.println(b);
   }

they are all under s->status

in order to set most of them use the functions exposed by sensor_t..

here's an example of setting the values..

it’s more than likely one of the auto’s that’s giving you trouble..

aec = Auto Exposure Control

the vals that start with an “a” is usually an auto var of some kind..

you would have to turn off the auto and set it to a good working value..

or take some pics and throw them away, should be pretty quick..

good luck.. ~q

Sorry to be clear ... I couldn't find them in the SeeedStudio tutorial.

Thanks for the tip. However, I get:

Guru Meditation Error: Core  1 panic'ed (LoadProhibited). Exception was unhandled.

I am gaining the impression that I have another problem!

That usually means you are trying to access some resource which has not been properly allocated..

that’s actually why I use the if (s) , if the esp_camera_sensor_get() fails then s will be garbage and accessing it will cause the same error your seeing now..

~q

Getting closer.

Even though I have:

sensor_t * s = esp_camera_sensor_get();

at the top of the file the if (s) statement doesn't even run.

I had tried getting the status values before, but was always getting 0.