Камера ESP32-CAM: справка по SD

esp32-cam

Я изо всех сил пытаюсь сделать простой эскиз, чтобы сделать фотографию с помощью ESP32-CAM и сохранить ее на SD-карту.

Я нашел кучу примеров, которые делают то, что я хочу, но в основном они просто делают фотографию и переходят в режим сна, поэтому каждый раз, когда вы перезагружаете устройство, оно запускает некоторый код, чтобы сделать снимок, а затем переходит в глубокий сон. .

Дело в том, что фотографии отстойные: они зеленые и без регулировки экспозиции. Я думаю, это известная проблема: первая фотография всегда зеленая, а автоматическое усиление еще не определило экспозицию. А поскольку каждая фотография — это первая фотография после пробуждения, все они отстой.

Я пытался переместить настройки в цикл и удалить часть сна, но это просто не работает, и я недостаточно разбираюсь в кодировании, чтобы даже использовать ChatGPT.

Ниже я приведу рабочий код, а затем ту часть, которую я изменил. Любая помощь будет отличной. Я думал, что это будет так просто: я просто хочу сделать снимок, когда нажимаю кнопку.

/*
CAM-камера ESP32 с памятью MicroSD
esp32cam-microsd.ino
Сделать снимок при нажатии кнопки
Сохранение изображения на карте MicroSD
 
Мастер-класс DroneBot 2022
https://dronebotworkshop.com
*/
// Включаем необходимые библиотеки
 
// Библиотеки камер
#include "esp_camera.h"
#include "soc/soc.h"
#include "soc/rtc_cntl_reg.h"
#include "driver/rtc_io.h"
 
// Библиотеки MicroSD
#include "FS.h"
#include "SD_MMC.h"
 
// Библиотека ЭСППЗУ
#include "EEPROM.h"
 
// Используем 1 байт пространства EEPROM
#define EEPROM_SIZE 1
 
// Счетчик номера изображения
unsigned int pictureCount = 0;
 
// Определения выводов для 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
 
void configESPCamera() {
  // Настраиваем параметры камеры
 
  // Объект для хранения параметров конфигурации камеры
  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; // Возможные варианты: YUV422, СЕРЫЙ, RGB565, JPEG.
 
  // Выбор меньшего размера кадра, если камера не поддерживает PSRAM
  if (psramFound()) {
    config.frame_size = FRAMESIZE_UXGA; // РАЗМЕР_КАРА_ + QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA
    config.jpeg_quality = 10; //10-63 меньшее число означает более высокое качество
    config.fb_count = 2;
  } else {
    config.frame_size = FRAMESIZE_UXGA;
    config.jpeg_quality = 12;
    config.fb_count = 1;
  }
 
  // Инициализируем камеру
  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();
 
  // ЯРКОСТЬ (от -2 до 2)
  s->set_brightness(s, 0);
  // КОНТРАСТ (от -2 до 2)
  s->set_contrast(s, 1);
  // НАСЫЩЕННОСТЬ (от -2 до 2)
  s->set_saturation(s, 0);
  // СПЕЦИАЛЬНЫЕ ЭФФЕКТЫ (0 — без эффекта, 1 — негатив, 2 — оттенки серого, 3 — красный оттенок, 4 — зеленый оттенок, 5 — синий оттенок, 6 — сепия)
  s->set_special_effect(s, 2);
  // БАЛАНС БЕЛОГО (0 = отключить, 1 = включить)
  s->set_whitebal(s, 1);
  // УСИЛЕНИЕ AWB (0 = отключить, 1 = включить)
  s->set_awb_gain(s, 1);
  // РЕЖИМЫ ББ (0 - Авто, 1 - Солнечно, 2 - Облачно, 3 - Офис, 4 - Дом)
  s->set_wb_mode(s, 0);
  // КОНТРОЛЬ ВОЗДЕЙСТВИЯ (0 = отключить, 1 = включить)
  s->set_exposure_ctrl(s, 1);
  // AEC2 (0 = отключить, 1 = включить)
  s->set_aec2(s, 0);
  // УРОВНИ AE (от -2 до 2)
  s->set_ae_level(s, 0);
  // ЗНАЧЕНИЯ AEC (от 0 до 1200)
  s->set_aec_value(s, 300);
  // УПРАВЛЕНИЕ УСИЛЕНИЕМ (0 = отключить, 1 = включить)
  s->set_gain_ctrl(s, 1);
  // УСИЛЕНИЕ АРУ (от 0 до 30)
  s->set_agc_gain(s, 0);
  // ПОТОЛОК УЛУЧШЕНИЯ (от 0 до 6)
  s->set_gainceiling(s, (gainceiling_t)0);
  // BPC (0 = отключить, 1 = включить)
  s->set_bpc(s, 0);
  // WPC (0 = отключить, 1 = включить)
  s->set_wpc(s, 1);
  // RAW GMA (0 = отключить, 1 = включить)
  s->set_raw_gma(s, 1);
  // LENC (0 = отключить, 1 = включить)
  s->set_lenc(s, 1);
  // ГОРИЗОНТ. ЗЕРКАЛО (0 = отключить, 1 = включить)
  s->set_hmirror(s, 0);
  // VERT FLIP (0 = отключить, 1 = включить)
  s->set_vflip(s, 0);
  // DCW (0 = отключить, 1 = включить)
  s->set_dcw(s, 1);
  // ШАБЛОН ЦВЕТНЫХ ПОЛОС (0 = отключить, 1 = включить)
  s->set_colorbar(s, 0);
}
 
void initMicroSDCard() {
  // Запускаем карту MicroSD
  Serial.println("Mounting MicroSD Card");
  if (!SD_MMC.begin()) {
    Serial.println("MicroSD Card Mount Failed");
    return;
  }
  uint8_t cardType = SD_MMC.cardType();
  if (cardType == CARD_NONE) {
    Serial.println("No MicroSD Card found");
    return;
  }
}
 
void takeNewPhoto(String path) {
  // Сделать снимок с помощью камеры
  // Настройка буфера кадра
  camera_fb_t  * fb = esp_camera_fb_get();
 
  if (!fb) {
    Serial.println("Camera capture failed");
    return;
  }
 
  // Сохраняем изображение на карту microSD
  fs::FS &fs = SD_MMC;
  File file = fs.open(path.c_str(), FILE_WRITE);
  if (!file) {
    Serial.println("Failed to open file in write mode");
  }
  else {
    file.write(fb->buf, fb->len); // полезная нагрузка (изображение), длина полезной нагрузки
    Serial.printf("Saved file to path: %s\n", path.c_str());
  }
  // Закрываем файл
  file.close();
 
  // Возвращаем буфер кадра обратно драйверу для повторного использования
  esp_camera_fb_return(fb);
}
 
void setup() {
  // Отключить детектор провалов напряжения
  WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);
 
  // Запускаем последовательный монитор
  Serial.begin(115200);
 
  // Инициализируем камеру
  Serial.print("Initializing the camera module...");
  configESPCamera();
  Serial.println("Camera OK!");
 
  // Инициализируем MicroSD
  Serial.print("Initializing the MicroSD card module... ");
  initMicroSDCard();
 
  // инициализируем EEPROM заранее определенного размера
  EEPROM.begin(EEPROM_SIZE);
  pictureCount = EEPROM.read(0) + 1;
 
  // Путь, по которому новое изображение будет сохранено на SD-карте
  String path = "/image" + String(pictureCount) + ".jpg";
  Serial.printf("Picture file name: %s\n", path.c_str());
 
  // Сделать и сохранить фотографию
  takeNewPhoto(path);
 
  // Обновляем счетчик количества изображений EEPROM
  EEPROM.write(0, pictureCount);
  EEPROM.commit();
 
  // Привязываем пробуждение к GPIO13, переходя на НИЗКИЙ уровень
  esp_sleep_enable_ext0_wakeup(GPIO_NUM_13, 0);
 
  Serial.println("Entering sleep mode");
  delay(1000);
 
  // Вход в режим глубокого сна
  esp_deep_sleep_start();
}
 
void loop() {
}

Я изменил настройку и цикл:

void setup() {
  // Отключить детектор провалов напряжения
  WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);
 
  // Запускаем последовательный монитор
  Serial.begin(115200);
 
  // Инициализируем камеру
  Serial.print("Initializing the camera module...");
  configESPCamera();
  Serial.println("Camera OK!");
 
  // Инициализируем MicroSD
  Serial.print("Initializing the MicroSD card module... ");
  initMicroSDCard();
 
  // инициализируем EEPROM заранее определенного размера
  EEPROM.begin(EEPROM_SIZE);
  pictureCount = EEPROM.read(0) + 1;
}
 
void loop() {
  // Путь, по которому новое изображение будет сохранено на SD-карте
  String path = "/image" + String(pictureCount) + ".jpg";
  Serial.printf("Picture file name: %s\n", path.c_str());

  // Проверяем, низкий ли уровень GPIO13
  if (digitalRead(GPIO_NUM_13) == LOW) {
    // Сделать и сохранить фотографию
    takeNewPhoto(path);

    // Обновляем счетчик количества изображений EEPROM
    EEPROM.write(0, pictureCount);
    EEPROM.commit();

  }
}

, 👍-1


1 ответ


0

Прочитайте эту веб-страницу в разделе "Сфотографировать на SD". карта

fb = esp_camera_fb_get(); 
dealy(1000)////

Это ключ к тому, чтобы избежать проблемы с темным и зеленым изображением. При необходимости отрегулируйте общее время задержки.

fb = esp_camera_fb_get(); 

Надеюсь, это поможет

Я бы посоветовал сначала взять несколько буферов изображений, разбудить камеру, а затем записать данные на SD-карту.

,

спасибо, иногда это помогало с зеленым, но слишком запоздало, чтобы быть пиратским, и не решает проблему воздействия. Мне действительно нужно оставить ESP включенным и просто активировать код захвата фотографии с помощью кнопки., @SV Savannah