Closed rbruneau-altyor closed 1 year ago
what happens if you use .grab_mode = CAMERA_GRAB_LATEST
?
@me-no-dev same behavior. It seems like 2 pictures are taken at the same time when I do the first loop
Though, If I initialize and deinitialize the camera every time I loop, it works fine...
that is really strange... I gave the suggestion for grab_mode
, though it should not have happened anyway, because when fb_count
is set to 1
, then whenever you call esp_camera_fb_get();
, only then the driver goes and waits for new frame from the sensor and grabs it, therefore you should always get a current frame with .fb_count = 1
What is even stranger is it that all pictures are taken fine, but returned shifted everytime, so the camera is able to take the picture but does not return it at the right time...
do you have any other sensors to test with? like OV2640?
Yes, I will try to adjust my configuration with OV2640 and I will let you know the result asap. Thank you for your help
@me-no-dev Same result with OV2640... the picture is duplicated
Can anyone try the code I gave with either OV2640 or BF3005 and tell me if you observe the same problem?
OK, I can confirm the issue. Will look into it
Hi @me-no-dev, any news on the subject? I tried the same code with different boards (esp-camera, esp-eye and custom esp32s3 + camera board) and different cameras on each hardware (BF3005 and OV2640), and the issue always shows up, so it seems like hardware is fine
it will not be very easy to fix this and we are currently a bit overloaded with other tasks. I have started the "research" on how to best approach this and will fix it. Till then you can get around this by grabbing and returning the frame immediately, then grabbing another one (which will be the latest one). The code will fill the frame as soon as you return it, so that is why you are getting an old frame currently.
Hi, @rbruneau-altyor , I suggest you try using the following configuration to test this sensor:
XCLK=10M,
format = RGB565,
resolution = VGA.
My testing here is completely normal.
Hi @WangYuxin-esp, what I2C speed do you use beside of these parameters?
Hi @WangYuxin-esp, what I2C speed do you use beside of these parameters?
100K. And here are some simple examples.
I re-wrote my code with your parameters, the first picture is still duplicated...
I re-wrote my code with your parameters, the first picture is still duplicated...
In most cases, we should always ignore the first few images by esp_camera_fb_return(esp_camera_fb_get())
.
Because most sensors have an automatic adjustment process after they are first configured.
There is another way to get rid of the problem with both OV2640 and BF3005, set .fb_count = 2
and .grab_mode = CAMERA_GRAB_LATEST
, with either PIXFORMAT_RGB565
or PIXFORMAT_YUV422
. It worked fine for me, but I'm still a bit confused why I could not use use fb_count set to 1...
Anyway, thank you @WangYuxin-esp and @me-no-dev for your advices
When .fb_count
is set to 1, it only affects the frame rate. It does not affect obtaining images. If you want to obtain new images, just call fb_retrun()
is sufficient, so that the buffer can be reused to receive data from the sensor.
Well, I can't explain why but switching fb_count to 2 made it worked by itself for me. Do you think there is a hardware problem?
Well, I can't explain why but switching fb_count to 2 made it worked by itself for me. Do you think there is a hardware problem?
This is unlikely to be a hardware issue. Because the value of parameter fb_count
only affects the operation of ESP32. I do not recommend configuring XCLK to 16M, as the standard clock for this sensor should be 10M.
XCLK set to 10MHz gives OVF errors
so I have to stick to 16MHz, which is indicated as experimental for ESP32-S3 but it is the only way I found to make it work
XCLK set to 10MHz gives OVF errors so I have to stick to 16MHz, which is indicated as experimental for ESP32-S3 but it is the only way I found to make it work
Start the camera with XCLK different than 16MHz and then switch it to 16MHz after init. This should get you out of the experimental mode (which is direct write to PSRAM from DMA).
Ok i'll try that. Do you think the problem is linked to experimental mode?
In experimental mode everything is handled in hardware and only VSYNC is captured in the ISR. Which OVF error are you getting?
I get cam_hal: FB-OVF
error with 10MHz
Just in case, I have BLE and other tasks running in the back ground, is it possible that CPU time given to each tasks has an impact on camera usage?
I get
cam_hal: FB-OVF
error with 10MHzJust in case, I have BLE and other tasks running in the back ground, is it possible that CPU time given to each tasks has an impact on camera usage?
Could you provide more detailed configurations, including resolution and data format? Different sensors have very different characteristics. For this sensor, I suggest that you use the configuration I suggest to confirm that it works properly. Then it's about improving its performance in other configurations.
Currently, I'm using the following configuration:
Camera: BF3005 I2C speed: 800000kHz (lower values simply do not work) XCLK Frequency: 16MHz Picture format: PIXFORMAT_RGB565 Frame size: FRAMESIZE_QVGA JPEG quality: 6 fb_count: 2 Grab mode: CAMERA_GRAB_LATEST fb_location: CAMERA_FB_IN_PSRAM
I'm planning to use several UART interfaces + BLE beside of the camera.
The configuration I've detailed above works fine, the problem is that I have to set fb_count to 2 to make it work. Otherwise, the doubled picture problem appears.
Right now I'm fine with these settings, though I would prefer to use fb_count set to 1.
Though, it seems like the configuration you are sugegsting me does not work at all. XCLK frequency and I2C speed are too low, giving me other errors than the one I encountered with my own settings. May be I should open another issue as it is not directly related to the original problem?
Currently, I'm using the following configuration:
Camera: BF3005 I2C speed: 800000kHz (lower values simply do not work) XCLK Frequency: 16MHz Picture format: PIXFORMAT_RGB565 Frame size: FRAMESIZE_QVGA JPEG quality: 6 fb_count: 2 Grab mode: CAMERA_GRAB_LATEST fb_location: CAMERA_FB_IN_PSRAM
I'm planning to use several UART interfaces + BLE beside of the camera.
The configuration I've detailed above works fine, the problem is that I have to set fb_count to 2 to make it work. Otherwise, the doubled picture problem appears.
Right now I'm fine with these settings, though I would prefer to use fb_count set to 1.
Though, it seems like the configuration you are sugegsting me does not work at all. XCLK frequency and I2C speed are too low, giving me other errors than the one I encountered with my own settings. May be I should open another issue as it is not directly related to the original problem?
What is the 'double picture problem', could you provide specific some pictures? Or I suggest you use the example here for testing, simply using the following configuration:
init_camera(10000000, PIXFORMAT_RGB565, FRAMESIZE_QVGA, 1)
In the above example, I have no problem using the above configuration.
@WangYuxin-esp Ok, I'll rexplain with pictures so you can understand better:
My code basically takes a picture every 10 second, and logs the JPEG hex code that I convert to an image later to check the content. I have 3 papers written from 1 to 3, and I take a picture of each of them. Here are the outputs I get for each of them, using fb_count set to 1, FRAMESIZE_QVGA, PIXFORMAT_RGB565 and XCLK = 16MHz :
First take:
Second take (10 seconds later):
Third take (10 seconds later):
As you can see, I should have gotten 1, 2 and then 3, but instead, I get 1, 1 and then 2, which means the first picture is duplicated (or 2 picures are taken almost at the same time and saved), and all other picture are returned displaced.
Using the parameters you gave me, it does work either. The only way to make it work properly is to set fb_count to 2
So, I tried the esp-iot-solution and took a look at the code, and it seems to me that 2 pictures are taken in a row in pic_server.c, line 43:
esp_camera_fb_return(esp_camera_fb_get());
frame = esp_camera_fb_get();
So, do I have to do the same in my code? Because the examples from esp32-camera repository do not show that king of code in the examples. It seems like a major difference to me
So, I tried the esp-iot-solution and took a look at the code, and it seems to me that 2 pictures are taken in a row in pic_server.c, line 43:
esp_camera_fb_return(esp_camera_fb_get());
frame = esp_camera_fb_get();
So, do I have to do the same in my code? Because the examples from esp32-camera repository do not show that king of code in the examples. It seems like a major difference to me
Thank you for your patient explanation.
Firstly, we should talk about how the current driver receives image data.
After the initialization of the sensor is completed, the sensor will continuously collect data and send it to ESP32. When esp32 has an idle framebuffer
, the received data is stored in the buffer. If there is no idle buffer, ESP32 will only stop receiving data, while the sensor is still collecting data.
When the driver is working in GRAB_LASTEST
mode, esp32 always tries to cache the latest data to the buffer. In this mode, the value of fb_count
must be greater than 2.
When the driver is working in GRAB_WHEN_EMPTY
mode, esp32 will stop working after filling fb_count
buffers.
The value of fb_count
in the sample program is 1. In order to receive the latest data every time the webpage is refreshed, I always consume the old data (by esp_camera_fb_return(esp_camera_fb_get());
) in the program first and then retrieve the latest data again.
Thank you for all these details,
So, I should either use:
1) fb_count = 2
and GRAB_LATEST
or
2) fb_count = 1
, GRAB_WHEN_EMPTY
and esp_camera_fb_return(esp_camera_fb_get());
to consume the old data
Is that right?
Can someone help me, I have the camera initialization problem.
the software returns that the camera is not supported:
ESP-ROM: esp32s3-20210327 Build: Mar 27 2021 rst:0x1 (POWERON),boot:0x8 (SPI_FAST_FLASH_BOOT) SPIWP:0xee mode:DIO, clock div:1 load:0x3fce3808,len:0x44c load:0x403c9700,len:0xbe4 load:0x403cc700,len:0x2a38 entry 0x403c98d4
E (33) camera: Detected camera not supported. E (33) camera: Camera probe failed with error 0x106(ESP_ERR_NOT_SUPPORTED) Camera init failed with error 0x106
ESP32-S3 - Platformio - Arduino.
#include #include "esp_camera.h" #include // =================== // Select camera model // =================== //#define CAMERA_MODEL_WROVER_KIT // Has PSRAM //#define CAMERA_MODEL_ESP_EYE // Has PSRAM #define CAMERA_MODEL_ESP32S3_EYE // Has PSRAM //#define CAMERA_MODEL_M5STACK_PSRAM // Has PSRAM //#define CAMERA_MODEL_M5STACK_V2_PSRAM // M5Camera version B Has PSRAM //#define CAMERA_MODEL_M5STACK_WIDE // Has PSRAM //#define CAMERA_MODEL_M5STACK_ESP32CAM // No PSRAM //#define CAMERA_MODEL_M5STACK_UNITCAM // No PSRAM //#define CAMERA_MODEL_AI_THINKER // Has PSRAM //#define CAMERA_MODEL_TTGO_T_JOURNAL // No PSRAM // ** Espressif Internal Boards ** //#define CAMERA_MODEL_ESP32_CAM_BOARD //#define CAMERA_MODEL_ESP32S2_CAM_BOARD //#define CAMERA_MODEL_ESP32S3_CAM_LCD #include "camera_pins.h" #define USE_OV2640 0 // =========================== // Enter your WiFi credentials // =========================== const char* ssid = "Athenas 2.4G"; const char* password = "HILGEMBERG"; sensor_t * s; void startCameraServer(); void camera_ini(void); void setup() { Serial.begin(115200); Serial.setDebugOutput(true); Serial.println(); // camera_ini(); 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; #if USE_OV2640 config.xclk_freq_hz = 20000000; config.frame_size = FRAMESIZE_UXGA; config.pixel_format = PIXFORMAT_JPEG; // for streaming config.grab_mode = CAMERA_GRAB_WHEN_EMPTY; config.fb_location = CAMERA_FB_IN_PSRAM; config.jpeg_quality = 12; config.fb_count = 1; #else config.xclk_freq_hz = 10000000; config.frame_size = FRAMESIZE_VGA; config.pixel_format = PIXFORMAT_RGB565; // for streaming config.grab_mode = CAMERA_GRAB_LATEST; config.fb_location = CAMERA_FB_IN_PSRAM; config.jpeg_quality = 6; config.fb_count = 2; #endif // if PSRAM IC present, init with UXGA resolution and higher JPEG quality // for larger pre-allocated frame buffer. if(psramFound()){ config.jpeg_quality = 10; config.fb_count = 2; config.grab_mode = CAMERA_GRAB_LATEST; } else { // Limit the frame size when PSRAM is not available config.frame_size = FRAMESIZE_SVGA; config.fb_location = CAMERA_FB_IN_DRAM; } // camera init 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(); // initial sensors are flipped vertically and colors are a bit saturated s->set_vflip(s, 1); // flip it back s->set_brightness(s, 1); // up the brightness just a bit s->set_saturation(s, 0); // lower the saturation WiFi.begin(ssid, password); WiFi.setSleep(false); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.println("WiFi connected"); startCameraServer(); Serial.print("Camera Ready! Use 'http://"); Serial.print(WiFi.localIP()); Serial.println("' to connect"); } void loop() { // Do nothing. Everything is done in another task by the web server delay(10000); }
Try tuning the xclk_freq_hz parameter as well as the I2C speed. I used 16MHz for XCLK and 800k for I2C, may be you can try that first. If it does not work, I suggest you open another issue as your problem is probably not related to the original issue here
Sorry for my ignorance, but where can I change the i2c speed to 800k, I'm not finding where to make this change.
I am not familiar with ESP-IDF combined with Arduino environment. When using ESP-IDF, this option is situated in sdkconfig file, where you also enable the camera support. Do you have something similar in your project?
the code I sent earlier was tested on ESP32-S3, and I didn't get any results.
Now this code I got a different result, it's using ESP32-CAM, but I still couldn't make it work.
have you seen this log?
#include "esp_camera.h" // #include "camera_index.h" #include "Arduino.h" // #include "fd_forward.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 the number of bytes you want to access #define EEPROM_SIZE 1 #define CONFIG_CAMERA_CONVERTER_ENABLED 1 #define USE_OV2640 0 #include #include #include TFT_eSPI tft = TFT_eSPI(); TFT_eFEX fex = TFT_eFEX(&tft); camera_fb_t *fb1 = NULL; camera_fb_t *fb2 = NULL; camera_fb_t *current_fb = NULL; bool buffer_ready = false; // 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 //Controle de foco/exposição automatico #define MAX_BRIGHTNESS 170 // valor máximo de brilho [200/0-255] #define MIN_BRIGHTNESS 70 // valor mínimo de brilho [50/0-255] #define AEC_STEP 100 // passo de ajuste do AEC [50] velocidade de atualzação #define AGC_GAIN_STEP 10 // passo de ajuste do ganho do AGC [1] velocidade de atualzação int pictureNumber = 0; sensor_t * s; unsigned long lastButtonPress = 0; const unsigned long debounceTime = 200; // Tempo em milissegundos int specialEffect = 0; // https://github.com/espressif/esp32-camera/issues/545 void camera_ini(void); void display_ini(void); void setup() { WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector // put your setup code here, to run once: Serial.begin(115200); Serial.println("V1.0.16 - Inicializa comunicacao Serial"); camera_ini(); display_ini(); } void loop() { camera_fb_t * fb = NULL; if (buffer_ready) { // Swap the two frame buffers if (current_fb == fb1) { current_fb = fb2; } else { current_fb = fb1; } // Capture a new frame from the camera esp_camera_fb_return(current_fb); current_fb = esp_camera_fb_get(); } if (buffer_ready) { // Display the current frame buffer using a fast DMA transfer tft.pushImageDMA(0, 0, current_fb->width, current_fb->height, (uint16_t*)current_fb->buf); } // Take Picture with Camera fb = esp_camera_fb_get(); if(!fb) { Serial.println("Camera capture failed"); return; } else{ //tft.fillScreen(random(0xFFFF)); fex.drawJpg((const uint8_t*)fb->buf, fb->len,0,0,240,240); } esp_camera_fb_return(fb); } void dmaTransferComplete() { buffer_ready = true; } void camera_ini(void){ Serial.println("Inicializa a camera..."); camera_config_t camera_config = { .pin_pwdn = PWDN_GPIO_NUM, .pin_reset = RESET_GPIO_NUM, .pin_xclk = XCLK_GPIO_NUM, .pin_sccb_sda = SIOD_GPIO_NUM, .pin_sccb_scl = SIOC_GPIO_NUM, .pin_d7 = Y9_GPIO_NUM, .pin_d6 = Y8_GPIO_NUM, .pin_d5 = Y7_GPIO_NUM, .pin_d4 = Y6_GPIO_NUM, .pin_d3 = Y5_GPIO_NUM, .pin_d2 = Y4_GPIO_NUM, .pin_d1 = Y3_GPIO_NUM, .pin_d0 = Y2_GPIO_NUM, .pin_vsync = VSYNC_GPIO_NUM, .pin_href = HREF_GPIO_NUM, .pin_pclk = PCLK_GPIO_NUM, #if USE_OV2640 .xclk_freq_hz = 20000000, .ledc_timer = LEDC_TIMER_0, .ledc_channel = LEDC_CHANNEL_0, .pixel_format = PIXFORMAT_JPEG, // PIXFORMAT_YUV422, // , .frame_size = FRAMESIZE_240X240, // , // FRAMESIZE_QVGA, // FRAMESIZE_240X240, .jpeg_quality = 12, .fb_count = 4, .grab_mode = CAMERA_GRAB_LATEST #else .xclk_freq_hz = 16000000, .ledc_timer = LEDC_TIMER_0, .ledc_channel = LEDC_CHANNEL_0, .pixel_format = PIXFORMAT_RGB565, // PIXFORMAT_YUV422, // PIXFORMAT_JPEG, .frame_size = FRAMESIZE_QVGA, // FRAMESIZE_240X240, // FRAMESIZE_QVGA, // FRAMESIZE_240X240, .jpeg_quality = 12, .fb_count = 2, .grab_mode = CAMERA_GRAB_LATEST #endif }; camera_config.fb_location = CAMERA_FB_IN_PSRAM; Serial.println("Define pinos camera"); Serial.println("Obtem os bufers"); // Init Camera esp_err_t err = esp_camera_init(&camera_config); if (err != ESP_OK) { Serial.printf("Camera init failed with error 0x%x", err); return; } Serial.printf("Pixel Format: %d\n", camera_config.pixel_format); Serial.printf("Frame Size: %d\n", camera_config.frame_size); Serial.printf("JPEG Quality: %d\n", camera_config.jpeg_quality); // right here s = esp_camera_sensor_get(); pinMode(12, INPUT_PULLUP); if (s->id.PID == BF3005_PID) { Serial.println("Camera BF3005 detectada"); } else { Serial.print("Camera desconhecida detectada: "); Serial.println(s->id.PID); return; // Finaliza se a câmera não for a esperada } Serial.println("Configurando parametros da camera"); //Comandos a baixo servem para controle do sensor Luz, imagem, posição... Serial.println("Configuracao da camera concluida"); } void display_ini(void){ tft.begin(); tft.setRotation(0); // 0 & 2 Portrait. 1 & 3 landscape (rotação de tela) tft.fillScreen(TFT_BLACK); } void adjust_aec_agc(camera_fb_t *fb) { // calcular o brilho médio da imagem int brightness = 0; for (int i = 0; i < fb->len; i++) { brightness += fb->buf[i]; } brightness /= fb->len; // ajustar o valor do AEC e do ganho do AGC com base no brilho da imagem sensor_t *s = esp_camera_sensor_get(); if (brightness > MAX_BRIGHTNESS) { // diminuir a exposição e o ganho se o brilho estiver muito alto s->set_exposure_ctrl(s, 1); s->set_aec_value(s, s->status.aec_value - AEC_STEP); s->set_agc_gain(s, s->status.agc_gain - AGC_GAIN_STEP); } else if (brightness < MIN_BRIGHTNESS) { // aumentar a exposição e o ganho se o brilho estiver muito baixo s->set_exposure_ctrl(s, 1); s->set_aec_value(s, s->status.aec_value + AEC_STEP); s->set_agc_gain(s, s->status.agc_gain + AGC_GAIN_STEP); } } //Controle de brilho automatico void adjust_brightness(camera_fb_t *fb) { // calcular o brilho médio da imagem int brightness = 0; for (int i = 0; i < fb->len; i++) { brightness += fb->buf[i]; } brightness /= fb->len; // ajustar o valor do brilho com base no brilho da imagem sensor_t *s = esp_camera_sensor_get(); if (brightness > MAX_BRIGHTNESS) { // diminuir o brilho se estiver muito alto s->set_brightness(s, -2); } else if (brightness < MIN_BRIGHTNESS) { // aumentar o brilho se estiver muito baixo s->set_brightness(s, -1); } else { // manter o brilho se estiver dentro do intervalo aceitável s->set_brightness(s, 0); } }
Camera capture failed E (17851) cam_hal: FB-SIZE: 149760 != 153600 E (17885) cam_hal: FB-SIZE: 149760 != 153600 E (17918) cam_hal: FB-SIZE: 149760 != 153600 E (17952) cam_hal: FB-SIZE: 149760 != 153600 E (17986) cam_hal: FB-SIZE: 149760 != 153600
the code I sent earlier was tested on ESP32-S3, and I didn't get any results.
Now this code I got a different result, it's using ESP32-CAM, but I still couldn't make it work.
have you seen this log?
include "esp_camera.h"
// #include "camera_index.h"
include "Arduino.h"
// #include "fd_forward.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 the number of bytes you want to access
define EEPROM_SIZE 1
define CONFIG_CAMERA_CONVERTER_ENABLED 1
define USE_OV2640 0
include
include
include
TFT_eSPI tft = TFT_eSPI(); TFT_eFEX fex = TFT_eFEX(&tft);
camera_fb_t fb1 = NULL; camera_fb_t fb2 = NULL; camera_fb_t *current_fb = NULL; bool buffer_ready = false;
// 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
//Controle de foco/exposição automatico
define MAX_BRIGHTNESS 170 // valor máximo de brilho [200/0-255]
define MIN_BRIGHTNESS 70 // valor mínimo de brilho [50/0-255]
define AEC_STEP 100 // passo de ajuste do AEC [50] velocidade de atualzação
define AGC_GAIN_STEP 10 // passo de ajuste do ganho do AGC [1] velocidade de atualzação
int pictureNumber = 0;
sensor_t * s;
unsigned long lastButtonPress = 0; const unsigned long debounceTime = 200; // Tempo em milissegundos int specialEffect = 0;
// https://github.com/espressif/esp32-camera/issues/545
void camera_ini(void); void display_ini(void);
void setup() { WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector // put your setup code here, to run once: Serial.begin(115200); Serial.println("V1.0.16 - Inicializa comunicacao Serial"); camera_ini(); display_ini(); }
void loop() { camera_fb_t * fb = NULL;
if (buffer_ready) { // Swap the two frame buffers if (current_fb == fb1) { current_fb = fb2; } else { current_fb = fb1; } // Capture a new frame from the camera esp_camera_fb_return(current_fb); current_fb = esp_camera_fb_get(); } if (buffer_ready) { // Display the current frame buffer using a fast DMA transfer tft.pushImageDMA(0, 0, current_fb->width, current_fb->height, (uint16_t*)current_fb->buf); } // Take Picture with Camera fb = esp_camera_fb_get(); if(!fb) { Serial.println("Camera capture failed"); return; } else{ //tft.fillScreen(random(0xFFFF)); fex.drawJpg((const uint8_t*)fb->buf, fb->len,0,0,240,240); } esp_camera_fb_return(fb);
}
void dmaTransferComplete() { buffer_ready = true; }
void camera_ini(void){ Serial.println("Inicializa a camera...");
camera_config_t camera_config = { .pin_pwdn = PWDN_GPIO_NUM, .pin_reset = RESET_GPIO_NUM, .pin_xclk = XCLK_GPIO_NUM, .pin_sccb_sda = SIOD_GPIO_NUM, .pin_sccb_scl = SIOC_GPIO_NUM, .pin_d7 = Y9_GPIO_NUM, .pin_d6 = Y8_GPIO_NUM, .pin_d5 = Y7_GPIO_NUM, .pin_d4 = Y6_GPIO_NUM, .pin_d3 = Y5_GPIO_NUM, .pin_d2 = Y4_GPIO_NUM, .pin_d1 = Y3_GPIO_NUM, .pin_d0 = Y2_GPIO_NUM, .pin_vsync = VSYNC_GPIO_NUM, .pin_href = HREF_GPIO_NUM, .pin_pclk = PCLK_GPIO_NUM,
if USE_OV2640
.xclk_freq_hz = 20000000, .ledc_timer = LEDC_TIMER_0, .ledc_channel = LEDC_CHANNEL_0, .pixel_format = PIXFORMAT_JPEG, // PIXFORMAT_YUV422, // , .frame_size = FRAMESIZE_240X240, // , // FRAMESIZE_QVGA, // FRAMESIZE_240X240, .jpeg_quality = 12, .fb_count = 4, .grab_mode = CAMERA_GRAB_LATEST
else
.xclk_freq_hz = 16000000, .ledc_timer = LEDC_TIMER_0, .ledc_channel = LEDC_CHANNEL_0, .pixel_format = PIXFORMAT_RGB565, // PIXFORMAT_YUV422, // PIXFORMAT_JPEG, .frame_size = FRAMESIZE_QVGA, // FRAMESIZE_240X240, // FRAMESIZE_QVGA, // FRAMESIZE_240X240, .jpeg_quality = 12, .fb_count = 2, .grab_mode = CAMERA_GRAB_LATEST
endif
}; camera_config.fb_location = CAMERA_FB_IN_PSRAM; Serial.println("Define pinos camera"); Serial.println("Obtem os bufers"); // Init Camera esp_err_t err = esp_camera_init(&camera_config); if (err != ESP_OK) { Serial.printf("Camera init failed with error 0x%x", err); return; } Serial.printf("Pixel Format: %d\n", camera_config.pixel_format); Serial.printf("Frame Size: %d\n", camera_config.frame_size); Serial.printf("JPEG Quality: %d\n", camera_config.jpeg_quality); // right here s = esp_camera_sensor_get(); pinMode(12, INPUT_PULLUP); if (s->id.PID == BF3005_PID) { Serial.println("Camera BF3005 detectada"); } else { Serial.print("Camera desconhecida detectada: "); Serial.println(s->id.PID); return; // Finaliza se a câmera não for a esperada } Serial.println("Configurando parametros da camera"); //Comandos a baixo servem para controle do sensor Luz, imagem, posição... Serial.println("Configuracao da camera concluida");
}
void display_ini(void){ tft.begin(); tft.setRotation(0); // 0 & 2 Portrait. 1 & 3 landscape (rotação de tela) tft.fillScreen(TFT_BLACK); }
void adjust_aec_agc(camera_fb_t *fb) { // calcular o brilho médio da imagem int brightness = 0; for (int i = 0; i < fb->len; i++) { brightness += fb->buf[i]; } brightness /= fb->len;
// ajustar o valor do AEC e do ganho do AGC com base no brilho da imagem sensor_t *s = esp_camera_sensor_get(); if (brightness > MAX_BRIGHTNESS) { // diminuir a exposição e o ganho se o brilho estiver muito alto s->set_exposure_ctrl(s, 1); s->set_aec_value(s, s->status.aec_value - AEC_STEP); s->set_agc_gain(s, s->status.agc_gain - AGC_GAIN_STEP); } else if (brightness < MIN_BRIGHTNESS) { // aumentar a exposição e o ganho se o brilho estiver muito baixo s->set_exposure_ctrl(s, 1); s->set_aec_value(s, s->status.aec_value + AEC_STEP); s->set_agc_gain(s, s->status.agc_gain + AGC_GAIN_STEP); }
}
//Controle de brilho automatico void adjust_brightness(camera_fb_t *fb) { // calcular o brilho médio da imagem int brightness = 0; for (int i = 0; i < fb->len; i++) { brightness += fb->buf[i]; } brightness /= fb->len;
// ajustar o valor do brilho com base no brilho da imagem sensor_t *s = esp_camera_sensor_get(); if (brightness > MAX_BRIGHTNESS) { // diminuir o brilho se estiver muito alto s->set_brightness(s, -2); } else if (brightness < MIN_BRIGHTNESS) { // aumentar o brilho se estiver muito baixo s->set_brightness(s, -1); } else { // manter o brilho se estiver dentro do intervalo aceitável s->set_brightness(s, 0); }
}
Camera capture failed E (17851) cam_hal: FB-SIZE: 149760 != 153600 E (17885) cam_hal: FB-SIZE: 149760 != 153600 E (17918) cam_hal: FB-SIZE: 149760 != 153600 E (17952) cam_hal: FB-SIZE: 149760 != 153600 E (17986) cam_hal: FB-SIZE: 149760 != 153600
For BF3005, you can try using Format = RGB565, XCLK=10M, and Framesize = VGA.
Hi,
I have been trying to use BF3005 camera and simple example code to take a picture every 10 seconds in the main loop. I notice a very strange behavior : the very first picture seem to be fine, but when I take a second one 10 seconds later, it outputs the same picture as the previous one. On the third loop, the picture output is a copy of the actual second picture, and it goes on and on until next reboot. Basically, the only picture that has the right content is the first one, every other picture is shifted. Here is the code I used to test it:
Does anyone has the same problem with the BF3005 camera? Or is there something wrong in my code?