Change ESP32-CAM OV2640 Camera Settings: Brightness, Resolution, Quality, Contrast, and More

This guide shows how to change the ESP32-CAM OV2640 camera settings such as contrast, brightness, resolution, quality, saturation and more using Arduino IDE.

How to Change ESP32-CAM Camera Settings contrast brightness resolution quality saturation exposure

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.

OV2640 Camera Settings ESP32-CAM AI Thinker

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:

FunctionMeaningValues
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 effect0 – No Effect
1 – Negative
2 – Grayscale
3 – Red Tint
4 – Green Tint
5 – Blue Tint
6 – Sepia
set_whitebal()Set white balance0 – disable
1 – enable
set_awb_gain()Set white balance gain0 – disable
1 – enable
set_wb_mode()Set white balance mode0 – Auto
1 – Sunny
2 – Cloudy
3 – Office
4 – Home
set_exposure_ctrl()Set exposure control0 – 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 correction0 – disable
1 – enable
set_hmirror()Horizontal mirror0 – disable
1 – enable
set_vflip()Vertical flip0 – disable
1 – enable
set_dcw()0 – disable
1 – enable
set_colorbar()Set a colorbar0 – 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_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 = 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); 
}

View raw code

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.

Learn how to program and build 17 projects with the ESP32-CAM using Arduino IDE DOWNLOAD »

Learn how to program and build 17 projects with the ESP32-CAM using Arduino IDE DOWNLOAD »

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:

Thanks for reading.



Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »
Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »

Enjoyed this project? Stay updated by subscribing our newsletter!

65 thoughts on “Change ESP32-CAM OV2640 Camera Settings: Brightness, Resolution, Quality, Contrast, and More”

  1. 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!

    Reply
  2. 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

    Reply
    • 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..

      Reply
        • 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.

          Reply
          • Hi.
            Unfortunately, we don’t have any tutorials about that subject.
            Thanks for your interest in our projects.
            Regards,
            Sara

  3. 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

    Reply
    • 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

      Reply
  4. 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,

    Reply
  5. 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.

    Reply
    • 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

      Reply
  6. 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 ?

    Reply
    • 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]

      Reply
  7. 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 🙂 )

    Reply
  8. 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.

    Reply
      • 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

        Reply
          • 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

  9. 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?

    Reply
      • 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

        Reply
  10. 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?

    Reply
  11. 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?

    Reply
  12. 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!!

    Reply
    • 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.

      Reply
      • 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);

        Reply
  13. 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

    Reply
  14. 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;

    Reply
  15. 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 ?

    Reply
  16. 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!!

    Reply
      • 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.

        Reply
  17. 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!

    Reply
  18. 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.

    Reply
  19. I found out that color calibration improve a lot the quality of images. Have you tried it? Here a tutorial youtu.be/PYKp4RN4Was

    Reply
  20. 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)

    Reply
    • *** 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

      Reply
      • 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)

        Reply
  21. 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

    Reply
    • 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.

      Reply
      • 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.

        Reply
  22. 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

    Reply
  23. 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

    Reply
  24. 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?

    Reply
      • 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

        Reply
        • 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

          Reply
  25. 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();

    Reply
  26. 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!

    Reply
  27. 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

    Reply

Leave a Comment

Download Our Free eBooks and Resources

Get instant access to our FREE eBooks, Resources, and Exclusive Electronics Projects by entering your email address below.