A timelapse program for esp32 cam with ov2640 sensor. The exposure is done manually based on the light level, and the image quality is far better than the default settings.
Apache License 2.0
38
stars
5
forks
source link
Picture with only the flash light / Zero environment light #9
// Don’t forget to switch to the register Bank 1 by writing 0x01 to 0xFF register.
s->set_reg(s,0xff,0xff,0x01);//banksel
s->set_reg(s,0x11,0xff,48);//frame rate (1 means longer exposure) - was 48
s->set_reg(s,0x13,0xff,0);//manual everything
s->set_reg(s,0x0c,0x6,0x8);//manual banding
s->set_reg(s,0x45,0x3f,0x3f);
Serial.print("Value for line 139 - (s,0x11,0xff) = ");
Serial.println(s->get_reg(s,0x11,0xff));
Serial.println("Getting first frame at");
Serial.println(millis());
// Take Picture with Camera
digitalWrite(4, LOW);
fb = esp_camera_fb_get();
Serial.println("Got first frame at");
Serial.println(millis());
Hello @raduprv,
hope this message finds you well.
My question is not a issue. Your code is perfect .
It is just a challenge that I am facing and maybe you can point me in the right direction.
I am playing with ESP CAM AI Thinker OV2640 for some time but facing massive problems to set the right register and be able to take a complete photo.
Please be advised that the photo is taken with no environment light , only the light provided by the flash light (GPIO 4).
To increase exposure, I have changed the registers 0x45, 0x10, 0x04 but I can[t find the most adequate values.
Would you be able to look at the two pictures attached, the code and serial report below and let me know what I am doing wrong ?
I appreciate any help, tip or experience you are willing to share.
Many Thanks for your help.
Best Regards,
Miguel
Serial monitor below :
16:15:14.105 -> rst:0x5 (DEEPSLEEP_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT) 16:15:14.105 -> configsip: 0, SPIWP:0xee 16:15:14.105 -> clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00 16:15:14.105 -> mode:DIO, clock div:1 16:15:14.105 -> load:0x3fff0030,len:1344 16:15:14.105 -> load:0x40078000,len:13864 16:15:14.105 -> load:0x40080400,len:3608 16:15:14.105 -> entry 0x400805f0 16:15:14.879 -> Setup ESP32 to sleep for every 10 Seconds 16:15:14.910 -> Value for line 139 - (s,0x11,0xff) = 48 16:15:14.910 -> Getting first frame at 16:15:14.910 -> 763 16:15:18.770 -> Got first frame at 16:15:18.770 -> 4629 16:15:18.770 -> Size of image:43311 16:15:18.770 -> Shape->width:1600 height:1200 16:15:18.770 -> Picture file name: /picture155.jpg 16:15:18.995 -> Saved file to path: /picture155.jpg 16:15:21.054 -> Going to sleep now
code below :
include "esp_camera.h"
include "Arduino.h"
include "FS.h" // SD Card ESP32
include "SD_MMC.h" // SD Card ESP32
include "soc/soc.h" // Disable brownour problems
include "soc/rtc_cntl_reg.h" // Disable brownour problems
include "driver/rtc_io.h"
include // read and write from flash memory
define uS_TO_S_FACTOR 1000000 / Conversion factor for micro seconds to seconds /
define TIME_TO_SLEEP 10 / Time ESP32 will go to sleep (in seconds) /
// define the number of bytes you want to access
define EEPROM_SIZE 1
// Pin definition for CAMERA_MODEL_AI_THINKER
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
int pictureNumber = 0;
void setup() { pinMode(4, OUTPUT); WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector
Serial.begin(115200);
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 = 20000000; config.pixel_format = PIXFORMAT_JPEG;
if(psramFound()){ config.frame_size = FRAMESIZEUXGA; // FRAMESIZE + QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA config.jpeg_quality = 10; // valor inicial = 10 config.fb_count = 1; } else { config.frame_size = FRAMESIZE_SVGA; config.jpeg_quality = 12; // valor inicial = 12 config.fb_count = 1; }
// Init Camera esp_err_t err = esp_camera_init(&config); if (err != ESP_OK) { Serial.printf("Camera init failed with error 0x%x", err); return; }
//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; }
esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR); Serial.println("Setup ESP32 to sleep for every " + String(TIME_TO_SLEEP) + " Seconds");
}
void loop() {
camera_fb_t * fb = NULL;
sensor_t * s = esp_camera_sensor_get();
int light=0;
s->set_whitebal(s, 1); // 0 = disable , 1 = enable s->set_awb_gain(s, 1); // 0 = disable , 1 = enable s->set_wb_mode(s, 2); // 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, 2); // -2 to 2 //s->set_aec_value(s, 1200); // 0 to 1200 s->set_gain_ctrl(s, 0); // 0 = disable , 1 = enable s->set_agc_gain(s, 0); // 0 to 30 s->set_gainceiling(s, (gainceiling_t)6); // 0 to 6 s->set_bpc(s, 1); // 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, 0); // 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, 0); // 0 = disable , 1 = enable s->set_colorbar(s, 0); // 0 = disable , 1 = enable
// Don’t forget to switch to the register Bank 1 by writing 0x01 to 0xFF register. s->set_reg(s,0xff,0xff,0x01);//banksel
s->set_reg(s,0x11,0xff,48);//frame rate (1 means longer exposure) - was 48 s->set_reg(s,0x13,0xff,0);//manual everything s->set_reg(s,0x0c,0x6,0x8);//manual banding
s->set_reg(s,0x45,0x3f,0x3f);
Serial.print("Value for line 139 - (s,0x11,0xff) = ");
Serial.println(s->get_reg(s,0x11,0xff));
Serial.println("Getting first frame at"); Serial.println(millis());
// Take Picture with Camera digitalWrite(4, LOW); fb = esp_camera_fb_get();
Serial.println("Got first frame at"); Serial.println(millis());
if(!fb) { Serial.println("Camera capture failed"); return; }
Serial.print("Size of image:"); Serial.println(fb->len); Serial.print("Shape->width:"); Serial.print(fb->width); Serial.print(" height:"); Serial.println(fb->height);
// initialize EEPROM with predefined size EEPROM.begin(EEPROM_SIZE); pictureNumber = EEPROM.read(0) + 1;
// Path where new picture will be saved in SD Card String path = "/picture" + String(pictureNumber) +".jpg";
fs::FS &fs = SD_MMC; Serial.printf("Picture file name: %s\n", path.c_str());
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()); EEPROM.write(0, pictureNumber); EEPROM.commit(); } file.close(); esp_camera_fb_return(fb);
// Turns off the ESP32-CAM white on-board LED (flash) connected to GPIO 4
digitalWrite(4, LOW); //rtc_gpio_hold_en(GPIO_NUM_4);
delay(2000); Serial.println("Going to sleep now"); delay(2000); esp_deep_sleep_start(); Serial.println("This will never be printed");
}