View Categories

ESP32-CAM

ESP32-CAM - плата на базе ESP32S, предназначенная для экспериментов с камерой: запись фото и видео, машинное зрение и так далее. В данном уроке рассмотрена самая популярная и дешёвая версия от Ai-Thinker:

В наборе GyverKIT START IOT EXTRA
ESP32-CAM

На плате есть:

  • ESP32S (ESP32-D0WD)
    • Частота 240 MHz
    • Оперативная память: 512 кБ
    • Flash-память: 4 МБ
  • Камера OV2640
    • Разрешение: до 1600x1200 (UXGA)
    • Много форматов вывода изображения (JPEG, BMP, оттенки серого)
    • Частота кадров: до 60 к/с
    • Бывают с разными объективами
  • Мощный светодиод (вспышка/фонарик)
  • Слот для карты памяти Micro SD
  • Разъём для внешней WiFi антенны
  • 4 МБ внешней оперативной памяти PSRAM для работы со снимками

Распиновка #

Особенности:

  • Распиновка явно сделана для совместимости с Wemos mini - такая же колодка, на тех же местах находятся пины питания
  • Аналоговые входы: на плату выведены только пины второго АЦП (ADC2), а он не работает при включенном WiFi! Т.е. на этой плате невозможно читать аналоговый сигнал и пользоваться WiFi одновременно
  • На плате стоит стабилизатор AMS1117-3.3 (пин 5V). По сути, плату можно питать от напряжения до 15V в этот пин, но плата довольно прожорливая: камера, WiFi, фонарик, сама еспшка. Даже если использовать не всю периферию, на высоком напряжении стабилизатор всё равно будет перегреваться и сгорит. Производитель не рекомендует подавать выше ~5.5V
  • Ближайший к фонарику пин может быть подписан как GND или GND/R - в первых версиях платы разработчик забыл вынести пин reset, потом его добавили на этот пин (как у Wemos mini)
  • Пин 16 является переключателем внешней PSRAM памяти. Если она используется вручную или в настройках камеры (режим для снимков с высоким разрешением) - то руками его трогать нельзя. В остальных случаях - можно использовать как обычный GPIO
  • Пин VCC выводит выбранное перемычкой-резистором напряжение (см. распиновку). Обычно по умолчанию запаяна нижняя, т.е. 3.3 V
  • Фонарик подключен к пину 4, управление прямое. Также светодиод есть на самом чипе ESP - подключен к пину 33, управление обратное (LOW - включить)

Нумерация пинов #

  • Цифровые пины соответствуют своим номерам на плате - IO4 в программе будет просто 4
  • АЦП - по тем же номерам, например analogRead(4) для IO4

Антенна #

Для подключения внешней антенны нужно перепаять перемычку с R3 на R2 (не всегда подписаны):

Начало работы #

Arduino IDE #

  • Ссылка для менеджера плат: https://espressif.github.io/arduino-esp32/package_esp32_index.json
  • Установить esp32 by Espressif Systems
  • Выбрать плату Ai Thinker ESP32-CAM

platformio.ini #

Конфиг для PlatformIO:

[env:esp32cam]
framework = arduino
monitor_speed = 115200
upload_speed = 921600
platform = espressif32
board = esp32cam
board_build.mcu = esp32
board_build.f_cpu = 240000000L
monitor_dtr = 0 ; об этом ниже
monitor_rts = 0 ; об этом ниже
lib_deps =

Загрузка прошивки #

ESP32-CAM не имеет USB порта и даже USB-UART преобразователя на борту. Это печально, но есть варианты. А вот проверочный скетч, который мигает вспышкой:

#define FLSH_PIN 4

void setup() {
    pinMode(FLSH_PIN, OUTPUT);
}

void loop() {
    digitalWrite(FLSH_PIN, 1);
    delay(500);
    digitalWrite(FLSH_PIN, 0);
    delay(500);
}

ESP32-CAM MB #

Самый удобный вариант - купить специальную плату-прошиватор ESP32-CAM MB. Я предпочитаю первый вариант на картинке ниже.

В наборе GyverKIT START IOT EXTRA
ESP32-CAM MB

С этими платами нужно быть аккуратнее - встречаются варианты с корявой микросхемой USB-UART с затёртой маркировкой. На нормальной должно быть написано CH340, например вот ссылка на нормальные платы.

Если вам попалась без маркировки и она не работает при установленных драйверах (см. урок по началу работы с Arduino) - нужно удалить драйвер и установить версию 2022 года (Яндекс.Диск), с ней плата будет работать

Далее всё как обычно - подключаем плату, выбираем Ai Thinker ESP32-CAM и загружаем прошивку.

На некоторых платах прошивка может не запуститься после загрузки, может потребоваться нажатие на кнопку RST на плате

Режим прошивки #

Если на плате две кнопки, то они отвечают за перезагрузку (RST) и за переход в режим прошивки (BOOT, IO0, FLASH). Обычно при загрузке прошивки плата сама переводит МК в режим прошивки, но это можно сделать и вручную:

  1. Зажать IO0
  2. Кликнуть RST
  3. отпустить IO0

Проблема с монитором порта #

Существует некоторая проблема с монитором порта - при его открытии МК просто зависает, потому что порт зажимает сброс сигналами DTR и RTS. Где наблюдается и как решить:

  • Arduino IDE 1 и 2
    • Убедитесь, что выбрана плата Ai Thinker ESP32-CAM. На других платах сброс настроен по другому и монитор порта может не работать
  • PlatformIO
    • Добавьте в env platformio.ini параметры monitor_dtr = 0 и monitor_rts = 0, как в примере конфига выше

Теперь открытие порта не будет перезагружать МК, но сам порт будет работать корректно.

USB-UART #

Загрузить прошивку можно при помощи любого USB-UART (USB-TTL) преобразователя с напряжением 3.3V. Бывают платы с переключением напряжения между 5 и 3.3V, также подойдёт плата прошивки для ESP-01:

В наборе GyverKIT START IOT EXTRA
ESP-USB

Для прошивки нужно подключить RX, TX и питание:

Перед прошивкой нужно перевести МК в режим прошивки, замкнув пин IO0 на GND:

  • При подключенном питании:
    1. Замкнуть IO0
    2. Кликнуть RST
    3. Отпустить IO0
  • При отключенном питании:
    1. Замкнуть IO0
    2. Подать питание на плату
    3. Отпустить IO0 сейчас или после загрузки прошивки

После загрузки прошивки нужно вручную перезагрузить МК при помощи кнопки RST или сброса питания

Можно припаять обычную кнопку к плате прошивки вот таким образом:

Нажатие на кнопку равносильно замыканию IO0 на GND, что упрощает процесс прошивки.

xBoard #

Ещё один вариант - использование платы расширения GyverKIT xBoard ESP в паре с обычным еспшным USB-UART:

В наборе GyverKIT START IOT EXTRA
xBoard ESP
ESP-USB

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

  1. Зажать FLASH
  2. Кликнуть RESET
  3. отпустить FLASH

Кнопки расположены рядом, поэтому прожать их можно одним пальцем.

После загрузки прошивки нужно вручную перезагрузить МК при помощи кнопки RESET

Особенности #

Справедливы почти все особенности esp, описанные в уроке про ESP8266:

  • Нетерпимость к долгим глухим циклам - в них нужно вызывать delay(0) или yield()
  • Деление на 0
  • Функции map(), min(), max()
  • Типы данных
  • Аппаратные прерывания
  • EEPROM

Проверка камеры #

Встроенный пример #

В Arduino IDE есть большой пример для проверки камеры, находится в меню примеров: Файл / Примеры / ESP32 / Camera / CameraWebServer.

  1. В самом начале скетча нужно ввести логин и пароль от роутера:
const char *ssid = "**********";
const char *password = "**********";
  1. В файле board_config.h нужно закомментировать текущую настройку и раскомментировать строку с выбором модели Ai Thinker:
#define CAMERA_MODEL_AI_THINKER
  1. После загрузки открыть монитор порта - там будет указан локальный IP платы. Нужно перейти по нему в браузере - откроется страница управления камерой. На ней можно покрутить настройки, эти же настройки можно делать вручную из программы в будущем:

В самом низу настроек есть две кнопки: сделать фото и начать видео-трансляцию:

Минимальный пример #

Также прилагаю минимальный пример теста камеры, в котором запускается вебсервер и по адресу платы в локальной сети выводится свежий снимок с камеры (для обновления снимка нужно перезагрузить страницу). В скетче нужно ввести логин-пароль от роутера, в мониторе порта будет выведен IP адрес платы для подключения:

#include <Arduino.h>
#include <WebServer.h>
#include <WiFi.h>
#include <esp_camera.h>
#include <esp_wifi.h>
#include <soc/rtc_cntl_reg.h>
#include <soc/soc.h>

// wifi
#define WIFI_SSID ""
#define WIFI_PASS ""

// camera pins 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

// camera init
bool cameraInit(framesize_t frame_size, pixformat_t pixel_format, int jpeg_quality) {
    esp_wifi_set_ps(WIFI_PS_NONE);              // no power save
    WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);  // disable brownout

    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_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 = pixel_format;
    config.frame_size = frame_size;
    config.jpeg_quality = jpeg_quality;
    config.fb_count = 1;

    return esp_camera_init(&config) == ESP_OK;
}

WebServer server(80);

void setup() {
    Serial.begin(115200);
    Serial.println();

    // camera
    if (!cameraInit(FRAMESIZE_VGA, PIXFORMAT_JPEG, 12)) {
        Serial.println("Camera error");
        for (;;);
    }

    // wifi
    WiFi.mode(WIFI_STA);
    WiFi.begin(WIFI_SSID, WIFI_PASS);
    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
    }
    Serial.println();
    Serial.print("Connected: ");
    Serial.println(WiFi.localIP());

    // server
    server.on("/", []() {
        camera_fb_t* fb = esp_camera_fb_get();
        if (fb) {
            server.setContentLength(fb->len);
            server.send(200, "image/jpeg", "");
            server.sendContent((const char*)fb->buf, fb->len);
        }
        esp_camera_fb_return(fb);
    });
    server.begin();
}

void loop() {
    server.handleClient();
}

Более подробно работу с камерой разберём в отдельных уроках по ESP32-CAM.

Полезные страницы #

Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
Прокрутить вверх