This guide shows how to change the ESP32-CAM OV2640 camera settings such as contrast, brightness, resolution, quality, saturation and more using Arduino IDE.
The instructions in this tutorial work for any ESP32 camera development board as long as it comes with the OV2640 camera.
You may like reading: Best ESP32 Camera Development Board
Installing the ESP32 add-on
We’ll program the ESP32 board using Arduino IDE. So, you need the Arduino IDE installed as well as the ESP32 add-on:
OV2640 Camera Settings
In the ESP32 Camera Web Server project, the web server provided a lot of options to change the image settings. Take a look at the following screenshot – there are sliders that you can move to change the image settings.
In this tutorial we’ll show you how to implement those changes on your code regardless of the project you’re building: taking photos or streaming video.
We recommend that you follow the Camera Web Server project first and play with the image settings to see what each setting does:
Depending on where your camera is located, you may want to change some settings to get a better picture. Playing with that web server gives you an idea of what you need to change and what values you need to set to get a better picture. Once you know the best settings for your camera, you may want to apply them in your other projects.
Changing ESP32-CAM Camera Settings Arduino Sketch
To change the image settings, after initializing the camera, use the following lines:
sensor_t * s = esp_camera_sensor_get()
s->set_brightness(s, 0); // -2 to 2
s->set_contrast(s, 0); // -2 to 2
s->set_saturation(s, 0); // -2 to 2
s->set_special_effect(s, 0); // 0 to 6 (0 - No Effect, 1 - Negative, 2 - Grayscale, 3 - Red Tint, 4 - Green Tint, 5 - Blue Tint, 6 - Sepia)
s->set_whitebal(s, 1); // 0 = disable , 1 = enable
s->set_awb_gain(s, 1); // 0 = disable , 1 = enable
s->set_wb_mode(s, 0); // 0 to 4 - if awb_gain enabled (0 - Auto, 1 - Sunny, 2 - Cloudy, 3 - Office, 4 - Home)
s->set_exposure_ctrl(s, 1); // 0 = disable , 1 = enable
s->set_aec2(s, 0); // 0 = disable , 1 = enable
s->set_ae_level(s, 0); // -2 to 2
s->set_aec_value(s, 300); // 0 to 1200
s->set_gain_ctrl(s, 1); // 0 = disable , 1 = enable
s->set_agc_gain(s, 0); // 0 to 30
s->set_gainceiling(s, (gainceiling_t)0); // 0 to 6
s->set_bpc(s, 0); // 0 = disable , 1 = enable
s->set_wpc(s, 1); // 0 = disable , 1 = enable
s->set_raw_gma(s, 1); // 0 = disable , 1 = enable
s->set_lenc(s, 1); // 0 = disable , 1 = enable
s->set_hmirror(s, 0); // 0 = disable , 1 = enable
s->set_vflip(s, 0); // 0 = disable , 1 = enable
s->set_dcw(s, 1); // 0 = disable , 1 = enable
s->set_colorbar(s, 0); // 0 = disable , 1 = enable
The following table shows each function and the values accepted:
Function | Meaning | Values |
set_brightness() | Set brightness | -2 to 2 |
set_contrast() | Set contrast | -2 to 2 |
set_saturation() | Set saturation | -2 to 2 |
set_special_effect() | Set a special effect | 0 – No Effect 1 – Negative 2 – Grayscale 3 – Red Tint 4 – Green Tint 5 – Blue Tint 6 – Sepia |
set_whitebal() | Set white balance | 0 – disable 1 – enable |
set_awb_gain() | Set white balance gain | 0 – disable 1 – enable |
set_wb_mode() | Set white balance mode | 0 – Auto 1 – Sunny 2 – Cloudy 3 – Office 4 – Home |
set_exposure_ctrl() | Set exposure control | 0 – disable 1 – enable |
set_aec2() | 0 – disable 1 – enable | |
set_ae_level() | -2 to 2 | |
set_aec_value() | 0 to 1200 | |
set_gain_ctrl() | 0 – disable 1 – enable | |
set_agc_gain() | 0 to 30 | |
set_gainceiling() | 0 to 6 | |
set_bpc() | 0 – disable 1 – enable | |
set_wpc() | 0 – disable 1 – enable | |
set_raw_gma() | 0 – disable 1 – enable | |
set_lenc() | Set lens correction | 0 – disable 1 – enable |
set_hmirror() | Horizontal mirror | 0 – disable 1 – enable |
set_vflip() | Vertical flip | 0 – disable 1 – enable |
set_dcw() | 0 – disable 1 – enable | |
set_colorbar() | Set a colorbar | 0 – disable 1 – enable |
As you can see, changing the camera settings is pretty straightforward. You just need to use those lines of code after initializing the camera. After that, you can use the usual functions and code to control the camera. To better understand how to use them, you can follow the next example.
The functions in the table appear in the same order as in the Camera Web Server example so that it is easier to identify which functions and values you should use to get a better image in your scenario.
Changing ESP32-CAM Camera Settings Example
To show you how to apply the image settings in your code, we’ve built a simple example. The following code takes a photo every 10 seconds and saves it in the microSD card. There’s a section in the code that allows you to change the camera settings.
/*********
Rui Santos
Complete project details at https://RandomNerdTutorials.com/esp32-cam-ov2640-camera-settings/
*********/
#include "esp_camera.h"
#include "FS.h" // SD Card ESP32
#include "SD_MMC.h" // SD Card ESP32
#include "soc/soc.h" // Disable brownout problems
#include "soc/rtc_cntl_reg.h" // Disable brownout problems
#include "driver/rtc_io.h"
// Pin definition for CAMERA_MODEL_AI_THINKER
// Change pin definition if you're using another ESP32 with camera module
#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
// Keep track of number of pictures
unsigned int pictureNumber = 0;
//Stores the camera configuration parameters
camera_config_t config;
void setup() {
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector
Serial.begin(115200);
//Initialize the camera
Serial.print("Initializing the camera module...");
configInitCamera();
Serial.println("Ok!");
//Initialize MicroSD
Serial.print("Initializing the MicroSD card module... ");
initMicroSDCard();
}
void loop() {
//Path where new picture will be saved in SD Card
String path = "/picture" + String(pictureNumber) +".jpg";
Serial.printf("Picture file name: %s\n", path.c_str());
//Take and Save Photo
takeSavePhoto(path);
pictureNumber++;
delay(10000);
}
void configInitCamera(){
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_sccb_sda = SIOD_GPIO_NUM;
config.pin_sccb_scl = SIOC_GPIO_NUM;
config.pin_pwdn = PWDN_GPIO_NUM;
config.pin_reset = RESET_GPIO_NUM;
config.xclk_freq_hz = 20000000;
config.pixel_format = PIXFORMAT_JPEG; //YUV422,GRAYSCALE,RGB565,JPEG
// Select lower framesize if the camera doesn't support PSRAM
if(psramFound()){
config.frame_size = FRAMESIZE_UXGA; // FRAMESIZE_ + QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA
config.jpeg_quality = 10; //10-63 lower number means higher quality
config.fb_count = 2;
} else {
config.frame_size = FRAMESIZE_SVGA;
config.jpeg_quality = 12;
config.fb_count = 1;
}
// Initialize the Camera
esp_err_t err = esp_camera_init(&config);
if (err != ESP_OK) {
Serial.printf("Camera init failed with error 0x%x", err);
return;
}
sensor_t * s = esp_camera_sensor_get();
s->set_brightness(s, 0); // -2 to 2
s->set_contrast(s, 0); // -2 to 2
s->set_saturation(s, 0); // -2 to 2
s->set_special_effect(s, 0); // 0 to 6 (0 - No Effect, 1 - Negative, 2 - Grayscale, 3 - Red Tint, 4 - Green Tint, 5 - Blue Tint, 6 - Sepia)
s->set_whitebal(s, 1); // 0 = disable , 1 = enable
s->set_awb_gain(s, 1); // 0 = disable , 1 = enable
s->set_wb_mode(s, 0); // 0 to 4 - if awb_gain enabled (0 - Auto, 1 - Sunny, 2 - Cloudy, 3 - Office, 4 - Home)
s->set_exposure_ctrl(s, 1); // 0 = disable , 1 = enable
s->set_aec2(s, 0); // 0 = disable , 1 = enable
s->set_ae_level(s, 0); // -2 to 2
s->set_aec_value(s, 300); // 0 to 1200
s->set_gain_ctrl(s, 1); // 0 = disable , 1 = enable
s->set_agc_gain(s, 0); // 0 to 30
s->set_gainceiling(s, (gainceiling_t)0); // 0 to 6
s->set_bpc(s, 0); // 0 = disable , 1 = enable
s->set_wpc(s, 1); // 0 = disable , 1 = enable
s->set_raw_gma(s, 1); // 0 = disable , 1 = enable
s->set_lenc(s, 1); // 0 = disable , 1 = enable
s->set_hmirror(s, 0); // 0 = disable , 1 = enable
s->set_vflip(s, 0); // 0 = disable , 1 = enable
s->set_dcw(s, 1); // 0 = disable , 1 = enable
s->set_colorbar(s, 0); // 0 = disable , 1 = enable
}
void initMicroSDCard(){
// Start Micro SD card
Serial.println("Starting SD Card");
if(!SD_MMC.begin()){
Serial.println("SD Card Mount Failed");
return;
}
uint8_t cardType = SD_MMC.cardType();
if(cardType == CARD_NONE){
Serial.println("No SD Card attached");
return;
}
}
void takeSavePhoto(String path){
// Take Picture with Camera
camera_fb_t * fb = esp_camera_fb_get();
if(!fb) {
Serial.println("Camera capture failed");
return;
}
// Save picture to microSD card
fs::FS &fs = SD_MMC;
File file = fs.open(path.c_str(), FILE_WRITE);
if(!file){
Serial.println("Failed to open file in writing mode");
}
else {
file.write(fb->buf, fb->len); // payload (image), payload length
Serial.printf("Saved file to path: %s\n", path.c_str());
}
file.close();
//return the frame buffer back to the driver for reuse
esp_camera_fb_return(fb);
}
To makes things simpler, we’ve created a function called configInitCamera() that contains all the commands to initialize the camera.
Assigning OV2640 GPIOs
First, it starts by assigning the GPIOs.
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;
The camera frequency:
config.xclk_freq_hz = 20000000;
OV2640 image format, quality, and frame size
The image format:
config.pixel_format = PIXFORMAT_JPEG; //YUV422,GRAYSCALE,RGB565,JPEG
The image format can be one of the following options:
- PIXFORMAT_YUV422
- PIXFORMAT_GRAYSCALE
- PIXFORMAT_RGB565
- PIXFORMAT_JPEG
Then, set the frame size, jpeg quality and framebuffer count. We select different settings depending if you’re using a camera with PSRAM or without PSRAM.
// Select lower framesize if the camera doesn't support PSRAM
if(psramFound()){
config.frame_size = FRAMESIZE_UXGA; // FRAMESIZE_ + QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA
config.jpeg_quality = 10; //10-63 lower number means higher quality
config.fb_count = 2;
} else {
config.frame_size = FRAMESIZE_SVGA;
config.jpeg_quality = 12;
config.fb_count = 1;
}
The frame size can be set to one of these options:
- FRAMESIZE_UXGA (1600 x 1200)
- FRAMESIZE_QVGA (320 x 240)
- FRAMESIZE_CIF (352 x 288)
- FRAMESIZE_VGA (640 x 480)
- FRAMESIZE_SVGA (800 x 600)
- FRAMESIZE_XGA (1024 x 768)
- FRAMESIZE_SXGA (1280 x 1024)
The image quality (jpeg_quality) can be a number between 0 and 63. A lower number means a higher quality. However, very low numbers for image quality, specially at higher resolution can make the ESP32-CAM to crash or it may not be able to take the photos properly.
So, if you notice that the images taken with the ESP32-CAM are cut in half, or with strange colors, that’s probably a sign that you need to lower the quality (select a higher number).
Initialize OV2640 camera
The following lines initialize the camera:
// Initialize the Camera
esp_err_t err = esp_camera_init(&config);
if (err != ESP_OK) {
Serial.printf("Camera init failed with error 0x%x", err);
return;
}
After this, you can add the lines of code we’ve shown you previously to change the image settings.
OV2640 settings: brightness, contrast, saturation, white balance, exposure, and more
The values set on the following lines are the default values, you can change them to change the image settings.
sensor_t * s = esp_camera_sensor_get();
s->set_brightness(s, 0); // -2 to 2
s->set_contrast(s, 0); // -2 to 2
s->set_saturation(s, 0); // -2 to 2
s->set_special_effect(s, 0); // 0 to 6 (0 - No Effect, 1 - Negative, 2 - Grayscale, 3 - Red Tint, 4 - Green Tint, 5 - Blue Tint, 6 - Sepia)
s->set_whitebal(s, 1); // 0 = disable , 1 = enable
s->set_awb_gain(s, 1); // 0 = disable , 1 = enable
s->set_wb_mode(s, 0); // 0 to 4 - if awb_gain enabled (0 - Auto, 1 - Sunny, 2 - Cloudy, 3 - Office, 4 - Home)
s->set_exposure_ctrl(s, 1); // 0 = disable , 1 = enable
s->set_aec2(s, 0); // 0 = disable , 1 = enable
s->set_ae_level(s, 0); // -2 to 2
s->set_aec_value(s, 300); // 0 to 1200
s->set_gain_ctrl(s, 1); // 0 = disable , 1 = enable
s->set_agc_gain(s, 0); // 0 to 30
s->set_gainceiling(s, (gainceiling_t)0); // 0 to 6
s->set_bpc(s, 0); // 0 = disable , 1 = enable
s->set_wpc(s, 1); // 0 = disable , 1 = enable
s->set_raw_gma(s, 1); // 0 = disable , 1 = enable
s->set_lenc(s, 1); // 0 = disable , 1 = enable
s->set_hmirror(s, 0); // 0 = disable , 1 = enable
s->set_vflip(s, 0); // 0 = disable , 1 = enable
s->set_dcw(s, 1); // 0 = disable , 1 = enable
s->set_colorbar(s, 0); // 0 = disable , 1 = enable
Demonstration
Change the camera settings in the code to adjust the image. Then, upload the code to your ESP32-CAM.
Press the ESP32-CAM RST button, and it will start taking photos. Then, grab the microSD card to see the photos.
Below you can see several images taken with different settings.
In my opinion, in these conditions, the best settings for a better picture are: contrast set to 2 and saturation set to -2.
Wrapping Up
In this tutorial, you’ve learned how to change the camera settings to adjust the image you get with the OV2640 camera.
This can be useful because depending on where you place your camera you may need to change the settings to get a better image.
You can use the functions we’ve shown you here in any of your projects with the ESP32-CAM to adjust the settings. We have several projects with the ESP32-CAM that you may like:
- Video Streaming, Face Detection and Face Recognition
- ESP32 IP CAM – Video Streaming (Home Assistant and Node-RED)
- Take Photo and Save to MicroSD Card
- PIR Motion Detector with Photo Capture
- Take Photo, Save to SPIFFS and Display in Web Server
- Build ESP32-CAM Projects (eBook)
- Read all our ESP32-CAM Projects, Tutorials and Guides
Thanks for reading.
FRAMESIZE_UXGA (1600 x 1200)
FRAMESIZE_UXGA (1920 x 1200)
There is a typo, this cannot have 2 values 😉
Hi.
I’m sorry for the typo.
The right one is
FRAMESIZE_UXGA (1600 x 1200)
Thanks for letting us know.
It is fixed now.
Regards,
Sara
Hi
How can I fix this error?
(esp_camera.h) not found
Thanks a lot
Hi.
Make sure you’re selecting an ESP32 board in Tools > Board before compiling.
Regards,
Sara
Nice post.
In case of building an asynchronous webserver to receive the new parameters, which approach is best?
When I tested the project here, I started some drafts thinking in how I could accomplish this…
So far I didnt build a good one. Maybe another time.
Suggestions are welcome!
Hi Random Nerd,
Thanks for posting, however adjusting the parameters has no effect on the camera.
It takes a picture and saves to SDcard ok , however the set commands do not appear to work.
i.e. if I change the>>>> s->set_special_effect(s, 1); // 0 to 6 (0 – No Effect, 1 – Negative, 2 – Grayscale, 3 – Red Tint, 4 – Green Tint, 5 – Blue Tint, 6 – Sepia)
the picture does not give negative effect.
Any ideas …. chiprobot
I have dug deeper…
You have to be very careful what combination of parameters you use and in what order you use them.
I had more success by commenting out the parameters not needed.
Extra care has to be taken when any of the Auto controls are used, as subsequent parameters are ignored.
….chiprobot..
That’s right.
I starteded playing the ESP32Cam several months ago. I managed to get it working by using the Random Nerd Tutorials. I am now trying to change settings and fine tune things. I am especially interested in windowing (ROI). I found the set_window function in the ov2640.c file, but i cannot access it. Do you have and example of setting a ROI on the camera?
Thank you in advance for you help and for the great tutorials.
Hi.
Unfortunately, we don’t have any tutorials about that subject.
Thanks for your interest in our projects.
Regards,
Sara
Hello I use the ESP32-CAM as an access point on an Android smartphone or tablet. Is it possible to increase the definition of the camera above UXGA (1600X1200)? The goal is to make an acceptable quality zoom, the camera is about 5 meters from what I want to film. Thank you
I have a question. Does the ESP32-CAM detects IR light?
What I want to do is use some IR LEDs to make it possible to take pictures in the dark.
Is it possible?
You can scrape out the IR filter from the module. In addition, it might now be possible to buy the OV2640 module without an IR filter
hello nice video, only some items to ask::
a)how to cam always on , with hit enable,
b) hot to record a video using e.g. NEtcam studio or other software, itry to entry the ip adress but cannot connect it.
sorry for my Q, if anyone can help will be great,
Hi Sara, right now I have just followed your tutorials on how to program the ESP 32 cam, I have the AI thinker one, however when I press on start stream(which works) and toggle the Face detecion feature, nothing happens, it streams the video normally but no green box appears on the video feed.
Hi.
Make sure you have good light so that the ESP32 is able to detect the face.
Additionally, you need to have the camera steady.
If the video streaming is very slow, it might have a hard time finding the face.
Regards,
Sara
HI,
is it possible to save a photo in a Format other than JPG?
What is the file extension for a PIXFORMAT_GRAYSCALE?
Hi!
I’m looking for re-config code.
I config camera first to GRAYSCALE/QVGA and take a picture. Calculate pixel average to see if it is day or night.
If it is day I want to take “real” picture JPG/SVGA for sending.
Day/night detection works but if I do camera configuration again after it it results error:
[E][camera.c:1249] esp_camera_init(): Camera probe failed with error 0x103
Camera init failed with error 0x103Guru Meditation Error: Core 1 panic’ed (LoadProhibited). Exception was unhandled.
Core 1 register dump:
…etc…
How can I change image resolution and pixel format to other after used first QVGA/GRAYSCALE ?
OK!
Found this from esp_camera.h :
Currently this function can only be called once and there is
no way to de-initialize this module.
esp_err_t esp_camera_init(const camera_config_t* config);
There is deinit routine, but useless then…
esp_err_t esp_camera_deinit();
I have to make workaround using RTC_DATA_ATTR variable to remember day or night and do a small deep sleep after day/night detect and in wake up to see the variable state (0= needs day/night detect 1=is night 2=is day) and do camera init again based to that information.
Works! [SOLVED]
Hi
My ESP32-CAM picture quality is ugly, what can I do ? I think its a problem with the Lens (i have removed the ‘protection’ film 🙂 )
Hi Sara,
I recently purchased two ESP32-CAM boards and one programmed fine but the other one keeps giving me the same error when I try to run the webserver example program. The device runs fine with the blink example but there seems to be a problem with the camera. The error message I get in the serial monitor after the code is loaded is:
camera_init(): Failed to set frame size
esp_camera_init(): Camera init failed with error 0x20002
So I tried swapping out the camera with the good board camera and I still got the same message.
I made sure that when I run the program it has a rock solid +5V power supply connected. Any help is appreciated.
Hi.
Take a look at the troubleshooting guide and see if it helps: https://randomnerdtutorials.com/esp32-cam-troubleshooting-guide/
Regars,
Sara
Hi Sara,
I got the problem fixed by purchasing a new camera!
But now I have a new problem. When I run camera Web Server example it is very slow and it cuts off the bottom half of the picture. I tried other resolutions and nothing seems to work right. Any thoughts on this issue?
Robert
Hi.
That is usually related with a weak wi-fi signal.
Does your board have an external antenna?
Regards,
sara
Hi,
I added an antenna and wow! This was definitely my problem.
Thank you!
Robert
Hello again,
Sorry to be a pest… I have a new Problem running a camera Blynk app. I keep getting a “Failed to get the frame on time” message. Is it the ESP32 CAM or the blynk app? When I first start the app everything works fine. But after about 4 pictures I get the error message and it will not go away.
Robert
Hello Sara,
Is it possible to turn the view 90 dgr.
Thanks for the info on setting the parameters in code. Once I’ve done that, I don’t need the webserver to show the settings…at least not necessary at startup. Is there a way to start with the settings hidden without having to click on the hamburger button to hide them? Or is there a way to only display the video stream?
Hi Collin.
To only display video stream, you can check this example: https://randomnerdtutorials.com/esp32-cam-video-streaming-web-server-camera-home-assistant/ (ignore the Home Assistant section).
Regards,
Sara
Hi Sara
I went through the tutorial you mentioned.
It worked brillant – as long as I don’t add an SD-Card function to the code.
Just by adding SD_MMC.begin() it comes to a very strange thing:
The framerate goes down from approx. 30fps to 1fps.
No typo – it really is one fps 🙂
Like Collin I just want to have the stream automatically started and no user interface shown.
The standard CameraWebServer does a great job – even with the SD-Card code.
So there must be something that interferes with this extended code here.
Thanks for any idea 🙂
Matt
Will s->set_vflip(s, 1); flip the livestream video?
I tried to use this piece of code, but my livestream is still shown up-side-down
Any idea what I’m doing wrong?
Hi,
I have baught four ESP32-CAM and using to do my experiment to collect data. during data collection I faced with some problems, Some cut off pictures, some high brightness pictures and some black pictures during the night time even I used the lights and the main problem is three camera stoped working after taking 4 to 5 picture but with same code my two camera still capturing photos I couldn’t find the problem can you please tell me what should I do?
An excellent tutorial, as always!
I cannot seem to make the frame size work.
I used
if(psramFound())
{
config.frame_size = FRAMESIZE_XGA; // 1024x768
config.jpeg_quality = 10;
config.fb_count = 2;
}
else
{
config.frame_size = FRAMESIZE_XGA;
config.jpeg_quality = 10;
config.fb_count = 1;
}
so, I should get XGA no matter if PSRam is available or not, but, my settings always start with UXGA enabled. Does this setting only work for stills? (I am streaming video)
Again, excellent source of information, Keep up the good work!!
Same question! I need an answer please.
You have to type at the line with the content:
// drop down frame size for higher initial frame rate
s->set_framesize(s, FRAMESIZE_VGA);
It never takes the value that you enter. Took me a long time to figure it out. and it make still no sense.
When you enter XGA, it will use UXGA.
When you enter VGA, it will use XGA and so on.
Hey. I solved this by some kind of hook. Instead of constant I convert int value to
framesize_t
. Works for me 🙂// 10 –> UXGA(1600×1200)
// 9 –> SXGA(1280×1024)
// 8 –> XGA(1024×768)
// 7 –> SVGA(800×600)
// 6 –> VGA(640×480)
// 5 — CIF(400×296)
// 4 –> QVGA(320×240)
// 3 –> HQVGA(240×176)
// 0 –> QQVGA(160×120)
int int_framesize = 9;
s->set_framesize(s, (framesize_t)int_framesize);
wondering if its possible to add a button to start and stop the stream in addition to the web button.
Not sure where the stream web button is in the code and woudl like to add an IO pin in that section of code
great tutorials, really enjoy them.
Thanks, Bob
Hello, Could you please advise viewer for the specific grayscale image format of ESP32CAM. I tried some popular viewers, they do not recognize these images.
Thank you.
config.pixel_format = PIXFORMAT_GRAYSCALE;
config.frame_size = FRAMESIZE_SXGA;
config.jpeg_quality = 10;
config.fb_count = 1;
Hello, If I change the settings is it possible to see them in Home Assistant. Because I want to change the horizon 180 degrees but it don’t show up in HA. What I am doing wrong ?
Hi,
I used
if (psramFound())
{
config.frame_size = FRAMESIZE_SVGA; //+ QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA
config.jpeg_quality = 10; //0-63 lower number means higher quality
config.fb_count = 2;
}
else
{
config.frame_size = FRAMESIZE_CIF;
config.jpeg_quality = 10; //0-63 lower number means higher quality
config.fb_count = 2;
}
but my esp32cam can not find psram, so it only run else(CIF picture),what should i do.
please give me some help,thanks.
Again, excellent source of information, Keep up the good work!!
Hi.
What’s the board that you havE?
Regards,
Sara
first,thanks for your reply.
My board is AI Thinker ESP32-CAM.
But I was used VS Code + PIO to program the ESP32, and now,The problem has been solved.
I configured in the platformio.ini ,input code to open PSRAM.
build_flags = -DCORE_DEBUG_LEVEL=5
-DBOARD_HAS_PSRAM
-mfix-esp32-psram-cache-issue
Thereby,I can get the UXGA picture(1600×1200).
Thank you again for your website and tutorial, which gave me a lot of help.
Hi there, I followed your previous web server tutorial but cannot find or open any settings in the web browser. It just shows the stream. Do you know how to access the web settings? Thanks in advance!
To change the settings on the web browser, you need to follow this example: https://randomnerdtutorials.com/esp32-cam-video-streaming-face-recognition-arduino-ide/
About green tint/ gren color which you do not want if you did not choose it in settings. You need to do more than just one photo in a row. For example when i did few photos in a row: first one bad photo, second too, finally 3rd photo was clear.
I found out that color calibration improve a lot the quality of images. Have you tried it? Here a tutorial youtu.be/PYKp4RN4Was
Toggle OV2640 Settings, I found this settings gives best video and photo quality.
// Camera sensor initial values
sensor_t * s = esp_camera_sensor_get();
s->set_brightness(s, 1); // -2 to 2 // *** User settings = 1 (Brightness)
s->set_aec2(s, 1); // 0 = disable , 1 = enable // *** User settings = 1 (AEC DSP)
s->set_bpc(s, 1); // 0 = disable , 1 = enable // *** User settings = 1 (BPC)
*** Correction… Toggle OV2640 Settings, I found this settings gives best video and photo quality.
// Camera sensor initial values
sensor_t * s = esp_camera_sensor_get();
s->set_brightness(s, -2); // -2 to 2 // *** User settings = 1 (Brightness)
s->set_aec2(s, 1); // 0 = disable , 1 = enable // *** User settings = 1 (AEC DSP)
s->set_bpc(s, 1); // 0 = disable , 1 = enable // *** User settings = 1 (BPC)
Rodney
But best in low light conditions settings… just leave brightness to 0 value. The AEC DSP and BPC seems to auto correct the overall image to be viewable naturally.
Toggle OV2640 Settings, I found this settings gives best video and photo quality.
// Camera sensor initial values
sensor_t * s = esp_camera_sensor_get();
s->set_aec2(s, 1); // 0 = disable , 1 = enable // *** User settings = 1 (AEC DSP)
s->set_bpc(s, 1); // 0 = disable , 1 = enable // *** User settings = 1 (BPC)
You can also add brightness with this setting:
s->set_gainceiling(s, (gainceiling_t)6); // 0 to 6
Onboard led does not turn on when picture is taken. I can add code to turn it on/off. but how does one enable (or disable) it to come on automatically when a picture is taken ?
Thanks,
Curt
I found a way to do it easily.
In the “camera_pin.h” file, you adjust the LED pin number in the “#elif defined(CAMERA_MODEL_AI_THINKER)” section:
“#define LED_GPIO_NUM 4” (for my board).
I tested the pin in the “loop()” function before, to verify the right pin number.
P.S.
I also do two things:
1. adjust the brightness from the cameraWebSite.
2. modify the code to ensure a given brightness on the camera board bootup.
Discrepancy between picture and code:
The screen picture shows “AEC Sensor” and “AEC DSP” right after “WB Mode”. Instead, the code following the picture shows “set_exposure_ctrl” and “set_aec2” after “WB Mode”
So… is AEC Sensor the same as set_exposure_ctrl ? and AEC DSP the same as set_aec2 ??
Thanks,
Curt
Nice post, thanks?
In a garage door control project, I plan to implement a ESP32-CAM to have a door survey.
In my first try, i use “curl /capture –output image.jpg” to have a eye on my door.
I found a way to have the flash LED blinking when I take the picture.
Is it possible to have a http request to adjust the LED intensity?
Best regards
the “” was suppressed before the “/capture”
I have an app that needs to capture an image every second, and the ESP32-CAM is running on battery so lowering power consumption is good. I can’t sleep the ESP between images as other functions are running between image captures.
When this line executes the current draw jumps way up, from ~40ma to ~180ma:
esp_err_t err = esp_camera_init(&config); // Initialize the Camera
After the image is taken the current stays at ~180ma.
Is there a way to “un init” the camera so it stops eating power between images?
I think there is a way but you need to manually control the camera pin, have a look at the datasheet
The OV250 data sheet doesn’t have a reference to a “Camera pin”:
https://www.uctronics.com/download/cam_module/OV2640DS.pdf
There is a CAM_RST signal on the ESP32-CAM schematic:
https://randomnerdtutorials.com/esp32-cam-ai-thinker-pinout/
That signal has an R-C from 3V3 (4.7K and 0.1uf) which acts as a POR signal to the camera module. The ESP32 module has no GPIO connection to that signal.
The camera pin definitions in sketches list “#define RESET_GPIO_NUM -1” but there isn’t a pin “negative 1” anywhere I can find. I suspect “-1” in the definition means there is no such signal for this board or camera module implementation.
The schematic does show GPIO32 is CAM_PWR, which controls the 1.2V and 2.8V regulators for the camera module. When I assert LOW to GPIO32 the camera does indeed stop working. If I later assert HIGH to GPIO32 the camera doesn’t come back, probably because the CAM_RST signal needs to be cycled after the camera module power supplies are restored, but that only happens when 3.3V is cycled.
One could connect a GPIO pin to the CAM-RST signal for further digging of this hole, but there are precious few available GPIO pins available on the AI-Thinker ESP32-CAM board when the camera and SD are in use. Like approximately ZERO pins available.
I have already hijacked GPIO33, which normally controls the red LED, for use as an analog input for watching battery voltage. GPIO33 is the ONLY pin that the camera, SD and PSRAM activities don’t hammer on.
The camera module does utilize the I2C interface for operation, and there could be a magic I2C incantation that could control the camera power consumption, but finding information on that has been unproductive. Digging thru the cryptic structured code maze that hides behind “esp_camera.h” has been equally frustrating.
So, to avoid further digging of this hole, I’m hoping for a programmy (sketchy?) method of quiescing the camera and restoring it later in the sketch. Something the average everyday hacker can just type in.
Again, this is all to avoid battery drain in between images taken every second. A tiny battery. Before someone suggests I should just plug it in to a power supply, I don’t have an extension cord long enough and light enough to work well with a model rocket.
Thanks, Jim
What you want is this:
“Executing a software power-down through the SCCB interface suspends internal circuit activity but does not halt the device clock. The current requirements drop to less than 1 mA in this mode. All register content is
maintained in standby mode”
Have a look at the registry COM2 (0x09)
Another way is to shutdown the camera with the PWDN pin, but this require to re-initialize the camera to take pictures again.
Cheers,
Leonardo
Some progress last night…
I found a reference to “esp_camera_deinit()” while scanning thru esp_camera.h files, then googled that and found several discussions, including one in randomnerdtutorials.com.
The consensus seems to be that “esp_camera_deinit()” doesn’t work as desired, but…
esp_camera_deinit() does indeed kill the camera and the current consumption drops back to an ambient level.
I moved the “esp_camera_init(&config)” stuff from the setup at the beginning of the sketch to my take-a-picture loop, and put “esp_camera_deinit()” after the “fb = esp_camera_fb_get( ) image capture.
It now takes pictures in a loop, with the resulting increase in power consumption, and drops the consumption back down in between. Solved-ish!
Three undesired things also happen:
The message: “E (5711) gpio: gpio_install_isr_service(449): GPIO isr service already installed”, which is understandable. “esp_camera_init” probably doesn’t expect to be executed multiple times in a sketch, but that GPIO warning/error message can be masked. Not ideal.
The second error is that after several images are successfully captured and stored to SD, the ESP32 reboots. No kernel panic message, just the reset dialog on the ISP serial monitor:
“ets Jul 29 2019 12:21:46”
“rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)” etc, etc, etc.
That’s understandable, “esp_camera_deinit()” probably doesn’t clean up properly. I am using
“esp_camera_fb_return(fb);” to clear free the frame buffer after storing it to SD.
And the third problem is that, as usual, after boot (or camera init) the first image or three from the camera is always dark and greenish, probably because color balance and the like haven’t been established. A long delay after camera init and before frame capture doesn’t help. I will try snapping several images before storing one to address that.
But first a nap…
Pertinant code, sprinkled with verbose prints to serial monitor:
Serial.println(“>>> Re-init the camera…”);
esp_err_t err = esp_camera_init(&config); // Initialize camera
if (err != ESP_OK) {
Serial.printf(“!!! Camera init failed with error 0x%x”, err);
Serial.println(“\n>>> Going to sleep now…”);
esp_deep_sleep_start();
}
else {
Serial.println(“>>> Camera init OK”);
}
Serial.println(">>> Take a picture");
camera_fb_t * fb = NULL; // Clear image frame buffer
fb = esp_camera_fb_get(); // Take Picture with Camera
if(!fb) {
Serial.print("!!! Failed esp_camera_fb_get!!!");
return;
}
Serial.println(">>> De-init camera here"); // De-init camera to save power
esp_camera_deinit();
Hi,
I have some questions:
a) setting contrast: ist this only afterwards possible by s->set_contrast(s, 2) or also with a config.xxxx parameter during configuration?
b) horizontal and vertical mirror/flip are possible (set_hmirror(), set_vflip()). Is a rotation for 90° also possible?
c) Is this explainable? I use only sigle picture retrieval fb = esp_camera_fb_get();
I used with PSRAM
config.frame_size = FRAMESIZE_UXGA;
config.fb_count = 1; //2 – 1
config.grab_mode = CAMERA_GRAB_LATEST;
and so OTA (over the air update) is possible, but often not the latest picture is delivered.
if I change to
config.frame_size = FRAMESIZE_UXGA;
config.fb_count = 2; //2 – 1
config.grab_mode = CAMERA_GRAB_LATEST;
the correct latest picture is delivered, but in starting the OTA upload, the ESP32 board is rebooting.
Thanks for any help!
Hello,
Is there a correct way to implement the camera settings in this project:
https://randomnerdtutorials.com/esp32-cam-video-streaming-web-server-camera-home-assistant/
I need to know how to control the Flash LED or which command turns the LED On and OFF. I may have to increase the flash On time.
Hi,
i use the example Skatch from “OV2640 CAM Settings” and noticed a strange behavier:
The Sketch works only at low light conditions, if the light is good, now pictures are taken.
I’m playing several days now with the CAM settings, but allways get the same result, – if it is sunny weather (better say: if the light is above a certain level) i get no pics.
I’m sure that it is not a hardware problem because, i tested with 2 boards and 3 Cams, and, with all combinations, i get a stream or pic if i use the CameraWebserver example. Also i get pictures if i hold my hand (or something else) in front of the leans…
For any hints where to look at or what i’m missing i would be happy, because i’m out ideas where to look at.
Thank you
Herbert
for those who are want to manipulate exposure value.
set 1 == auto exposure
set 0 == manual exposure with set_aec_value
※ If you want to adjust exposure manually then must set_exposure_ctrl set value 0.
I use this for get a low and high exposure image to get HDR image by opencv.