Найти тему

esp32-cam и Творчески мазохизм.

Творчески мазохизм = метод тыка в ИТ! Особо прошу обратить внимание на sdKconfig, который влияет на сборку пакетов и отладку. МНОГИЕ не оценили важность sdKconfig🤢🤮

Поиск решений = важная часть результата. Почему не обожаю СИ ? Да он просто разный. В восторге от assembler. PASCAL

😉Кто там предлагал грызть гранит НАУКИ ? ТРОЦКИЙ? Менделеев предлогам бродить не страшась усталости по тропам для поиска ВЕРШИН?

Счастливчики)))✔

ИТЕШКАМ никогда не бродить по науке и не грызнуть науку , а копать и рыть проблемы себе и разгребать и распутывать проблемы другим.? Так вот, чтобы творческого мазохизма не было продвинуто до маразма, то толкают языки другие , но не СИ. Под ПЛК и т.п. например Ld . IL FBD. CFS .SFX. verilog. HDLC..... Основная проблема это код чужой, который не всегда идеален и библиотеки , которые не всегда нормальны и полны. Ну естественно , когда с таким хозяйством сталкивается спец, то он тоже не идеален. К чему это всё? БУДЬТЕ СНИСХОДИТЕЛЬНЫ к себе и ДРУГИМ. ОСНОВНА проблема - это обеспечение повторяемости результата?😜 Ну вы прошли по тропинке , а потом забыли про её? Так у нас САДКО и СУСАНИН ещё те были? У КСТАТИ А АМЕРИКО? А ВИКИНГИ? Марко Поло, тот всё записал вроде? 😋

🤢Сидел долго на примерах, а наиболее удачный код излагается тут но не под espressif ЦЕЛЬ: опробовать пример в espressif 😊

https://esp32tutorials.com/esp32-cam-esp-idf-live-streaming-web-server/

ЗАПУСТИМ espressif если вы его установили , а ранее про это рассматривали и простую задачу решили. если кто не в курсах , то в просторах ИНЕТ много есть роликов и примеров!

есть три пункта ))
есть три пункта ))

Три пункта выполним?✔

три шелка нада сделать😊
три шелка нада сделать😊

Выполним ещё три пункта?

всё выделить
всё выделить

Два пункта и не сложно.🏳‍🌈

два пункта смело
два пункта смело

Удалим всё по пунктам , а их два.🚀

  • КАК выделить текст знаете ? CTRL+C - скопировать CTRL+V - вставить.
    Ниже код. Выделить и вставить в espressif!!!
#include <esp_system.h>
#include <nvs_flash.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "esp_camera.h"
#include "esp_http_server.h"
#include "esp_timer.h"
#include "camera_pins.h"
#include "connect_wifi.h"

должно выглядеть так✔
должно выглядеть так✔

Кстати: PART_BOUNDARY - используется для разделения частей в HTTP-ответе. _STREAM_CONTENT_TYPE- определяет тип содержимого HTTP-ответа. _STREAM_BOUNDARY- используется для разделения частей в HTTP-ответе. _STREAM_PART - определяет формат части в HTTP-ответе.🚩

  • КАК выделить текст знаете ? CTRL+C - скопировать CTRL+V - вставить. Ниже код. Выделить и вставить в espressif!!!
static const char *TAG = "esp32-cam Webserver"; #define PART_BOUNDARY "123456789000000000000987654321"
static const char* _STREAM_CONTENT_TYPE = "multipart/x-mixed-replace; boundary=" PART_BOUNDARY;
static const char* _STREAM_BOUNDARY = "\r\n--" PART_BOUNDARY "\r\n";
static const char* _STREAM_PART = "Content-Type: image/jpeg\r\nContent-Length: %u\r\n\r\n";
#define CONFIG_XCLK_FREQ 20000000

🏳‍🌈НИЖЕ описана функция init_camera(void) , где определена структура и условия вставлены в данную структуру, а затем структура передана функции esp_camera_init(&camera_config) . Условия переданные структуре будут определены в файле с расширением .h Далее проверка и флаг на успех на возврат из функции.👌

  • КАК выделить текст знаете ? CTRL+C - скопировать CTRL+V - вставить.
    Ниже код. Выделить и вставить в espressif!!!
static esp_err_t init_camera(void) { camera_config_t camera_config = {
.pin_pwdn = CAM_PIN_PWDN, .pin_reset = CAM_PIN_RESET,
.pin_xclk = CAM_PIN_XCLK, .pin_sccb_sda = CAM_PIN_SIOD,
.pin_sccb_scl = CAM_PIN_SIOC, .pin_d7 = CAM_PIN_D7,
.pin_d6 = CAM_PIN_D6, .pin_d5 = CAM_PIN_D5,
.pin_d4 = CAM_PIN_D4, .pin_d3 = CAM_PIN_D3,
.pin_d2 = CAM_PIN_D2, .pin_d1 = CAM_PIN_D1,
.pin_d0 = CAM_PIN_D0, .pin_vsync = CAM_PIN_VSYNC,
.pin_href = CAM_PIN_HREF, .pin_pclk = CAM_PIN_PCLK,
.xclk_freq_hz = CONFIG_XCLK_FREQ, .ledc_timer = LEDC_TIMER_0,
.ledc_channel = LEDC_CHANNEL_0, .pixel_format = PIXFORMAT_JPEG,
.frame_size = FRAMESIZE_UXGA, .jpeg_quality = 12, .fb_count = 1,
.grab_mode = CAMERA_GRAB_WHEN_EMPTY};esp_err_t err=esp_camera_init(&camera_config);
if (err != ESP_OK) { return err; } return ESP_OK;
}

Всё должно выглядеть так как ниже ✔

ужатый код не по традиции 😎
ужатый код не по традиции 😎

ДАЛЕЕ Функция setup_server возвращает дескриптор HTTP-серверу, который можно использовать для управления сервером (например, остановить его, отменить регистрацию обработчиков URI).

  • КАК выделить текст знаете ? CTRL+C - скопировать CTRL+V - вставить.
    Ниже код. Выделить и вставить в espressif!!!👌
httpd_uri_t uri_get = { .uri = "/", .method = HTTP_GET, .handler = jpg_stream_httpd_handler, .user_ctx = NULL};
httpd_handle_t setup_server(void) {
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
httpd_handle_t stream_httpd = NULL;
if (httpd_start(&stream_httpd , &config) == ESP_OK) { httpd_register_uri_handler(stream_httpd , &uri_get); }
return stream_httpd;
}
выглядит ужасно?  примерно так 😜  обрамил комментариями, чтобы читабельней , было.
выглядит ужасно? примерно так 😜 обрамил комментариями, чтобы читабельней , было.

Функция обработки прямой трансляции jpg_stream_httpd_handler

- это обработчик, которая вызывается для обработки запросов GET в корневом URI HTTP-сервера. Он транслирует видеоконтент в реальном времени, отправляя буфер кадров камеры в виде изображений JPEG в HTTP-ответе.

  • ВНИМАТЕЛЬНО почитать: Начинается с установки типа содержимого HTTP-ответа в _STREAM_CONTENT_TYPE с помощью функции httpd_resp_set_type и входит в цикл, который захватывает кадр с камеры, при необходимости преобразует его в формат JPEG и отправляет его в виде фрагмента в HTTP-ответе. Цикл продолжается до тех пор, пока не произойдет ошибка или соединение не будет разорвано. На каждой итерации цикла функция сначала захватывает кадр с камеры, используя функцию esp_camera_fb_get . Если захват завершается неудачно, она регистрирует сообщение об ошибке и прерывает цикл. Если кадр был захвачен успешно, функция проверяет формат кадра. Если он не в формате JPEG, она преобразует его в JPEG с помощью функции frame2jpg. Если преобразование завершается неудачно, он регистрирует сообщение об ошибке, возвращает буфер кадров в камеру с помощью esp_camera_fb_return и прерывает цикл. Если кадр уже в формате JPEG или преобразование в JPEG прошло успешно, функция отправляет граничную строку, заголовок части (который включает тип содержимого и длину содержимого) и изображение JPEG в виде фрагментов в HTTP-ответе с использованием функции httpd_resp_send_chunk. Если какая-либо из этих операций завершается неудачей, она выходит из цикла. После отправки фрагментов функция возвращает буфер кадров в камеру с помощью esp_camera_fb_return и регистрирует размер и время обработки изображения в формате JPEG. Наконец, функция устанавливает переменной last_frame значение 0 и возвращает результат последней операции. Другими словами, эта функция фактически выполняет прямую трансляцию видео.
  • КАК выделить текст знаете ? CTRL+C - скопировать CTRL+V - вставить.
    Ниже код. Выделить и вставить в espressif!!!🌹
esp_err_t jpg_stream_httpd_handler(httpd_req_t *req){
camera_fb_t * fb = NULL; esp_err_t res = ESP_OK; size_t _jpg_buf_len;
uint8_t * _jpg_buf; char * part_buf[64]; static int64_t last_frame = 0;
if(!last_frame) { last_frame = esp_timer_get_time(); }
res = httpd_resp_set_type(req, _STREAM_CONTENT_TYPE);
if(res != ESP_OK){ return res; }
while(true){ fb = esp_camera_fb_get();
if (!fb) { ESP_LOGE(TAG, "Camera capture failed"); res = ESP_FAIL; break; }
if(fb->format != PIXFORMAT_JPEG){ bool jpeg_converted = frame2jpg(fb, 80, &_jpg_buf, &_jpg_buf_len);
if(!jpeg_converted){ ESP_LOGE(TAG, "JPEG compression failed"); esp_camera_fb_return(fb); res = ESP_FAIL; } } else {_jpg_buf_len = fb->len; _jpg_buf = fb->buf; }
if(res == ESP_OK){ res = httpd_resp_send_chunk(req, _STREAM_BOUNDARY, strlen(_STREAM_BOUNDARY)); }
if(res == ESP_OK){ size_t hlen = snprintf((char *)part_buf, 64, _STREAM_PART, _jpg_buf_len); res = httpd_resp_send_chunk(req, (const char *)part_buf, hlen); }
if(res == ESP_OK){ res = httpd_resp_send_chunk(req, (const char *)_jpg_buf, _jpg_buf_len); }
if(fb->format != PIXFORMAT_JPEG){ free(_jpg_buf); }
esp_camera_fb_return(fb);
if(res != ESP_OK){ break; }
int64_t fr_end = esp_timer_get_time(); int64_t frame_time = fr_end - last_frame; last_frame = fr_end; frame_time /= 1000;
ESP_LOGI(TAG, "MJPG: %uKB %ums (%.1ffps)", (uint32_t)(_jpg_buf_len/1024), (uint32_t)frame_time, 1000.0 / (uint32_t)frame_time);
}
last_frame = 0; return res;
}
вышло так!  можете  сделать по желанию более читабельным😉
вышло так! можете сделать по желанию более читабельным😉

В основной функции : Если камера была успешно инициализирована, функция настраивает веб-сервер прямой трансляции HTTP с помощью функции setup_server и регистрирует сообщение, указывающее, что сервер запущен. Если подключение к сети Wi-Fi не было успешным, он регистрирует сообщение, указывающее на сбой, и не запускает сервер.

  • КАК выделить текст знаете ? CTRL+C - скопировать CTRL+V - вставить.
    Ниже код. Выделить и вставить в espressif!!!🏴
void app_main() { esp_err_t err; esp_err_t ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_ERROR_CHECK(nvs_flash_erase()); ret = nvs_flash_init(); } connect_wifi();
if (wifi_connect_status) { err = init_camera();
if (err != ESP_OK) { printf("err: %s\n", esp_err_to_name(err)); return; }
setup_server();
ESP_LOGI(TAG, "ESP32 CAM Web Server is up and running\n"); } else
ESP_LOGI(TAG, "Failed to connected with Wi-Fi, check your network Credentials\n");
}

скачать исходник можно тут

можете от рихтовать код согласно правилам.
можете от рихтовать код согласно правилам.
обычно для создания каталога достаточно три пункта🏳‍🌈
обычно для создания каталога достаточно три пункта🏳‍🌈

Три пункта выполним?

делаем  каталог
делаем каталог

два пункта выполним!

организуем файл
организуем файл

три пункта выполним?

раздел  создания файлов
раздел создания файлов

создадим файл ? camera_pins.h файл определяет константы для назначения pin-кодов.

  • КАК выделить текст знаете ? CTRL+C - скопировать CTRL+V - вставить.
    Ниже код. Выделить и вставить в espressif!!!

#ifndef CAMERA_PINS_H_

#define CAMERA_PINS_H_

#define CONFIG_BOARD_ESP32CAM_AITHINKER 1

// Freenove ESP32-WROVER CAM Board PIN Map

#if CONFIG_BOARD_WROVER_KIT

#define CAM_PIN_PWDN -1 //power down is not used

#define CAM_PIN_RESET -1

//software reset will be performed #define CAM_PIN_XCLK 21

#define CAM_PIN_SIOD 26

#define CAM_PIN_SIOC 27

#define CAM_PIN_D7 35

#define CAM_PIN_D6 34

#define CAM_PIN_D5 39

#define CAM_PIN_D4 36

#define CAM_PIN_D3 19

#define CAM_PIN_D2 18

#define CAM_PIN_D1 5

#define CAM_PIN_D0 4

#define CAM_PIN_VSYNC 25

#define CAM_PIN_HREF 23

#define CAM_PIN_PCLK 22

#endif // ESP-EYE PIN Map

#if CONFIG_BOARD_CAMERA_MODEL_ESP_EYE

#define PWDN_GPIO_NUM -1

#define RESET_GPIO_NUM -1

#define XCLK_GPIO_NUM 4

#define SIOD_GPIO_NUM 18

#define SIOC_GPIO_NUM 23

#define Y9_GPIO_NUM 36

#define Y8_GPIO_NUM 37

#define Y7_GPIO_NUM 38

#define Y6_GPIO_NUM 39

#define Y5_GPIO_NUM 35

#define Y4_GPIO_NUM 14

#define Y3_GPIO_NUM 13

#define Y2_GPIO_NUM 34

#define VSYNC_GPIO_NUM 5

#define HREF_GPIO_NUM 27

#define PCLK_GPIO_NUM 25

#endif // AiThinker ESP32Cam PIN Map

#if CONFIG_BOARD_ESP32CAM_AITHINKER

#define CAM_PIN_PWDN 32

#define CAM_PIN_RESET -1 //software reset will be performed

#define CAM_PIN_XCLK 0

#define CAM_PIN_SIOD 26

#define CAM_PIN_SIOC 27

#define CAM_PIN_D7 35

#define CAM_PIN_D6 34

#define CAM_PIN_D5 39

#define CAM_PIN_D4 36

#define CAM_PIN_D3 21

#define CAM_PIN_D2 19

#define CAM_PIN_D1 18

#define CAM_PIN_D0 5

#define CAM_PIN_VSYNC 25

#define CAM_PIN_HREF 23

#define CAM_PIN_PCLK 22

#endif // TTGO T-Journal ESP32 Camera PIN Map

#if CONFIG_BOARD_CAMERA_MODEL_TTGO_T_JOURNAL

#define PWDN_GPIO_NUM 0

#define RESET_GPIO_NUM 15

#define XCLK_GPIO_NUM 27

#define SIOD_GPIO_NUM 25

#define SIOC_GPIO_NUM 23

#define Y9_GPIO_NUM 19

#define Y8_GPIO_NUM 36

#define Y7_GPIO_NUM 18

#define Y6_GPIO_NUM 39

#define Y5_GPIO_NUM 5

#define Y4_GPIO_NUM 34

#define Y3_GPIO_NUM 35

#define Y2_GPIO_NUM 17

#define VSYNC_GPIO_NUM 22

#define HREF_GPIO_NUM 26

#define PCLK_GPIO_NUM 21

#endif

#endif

укажем поиск в подкаталогах
укажем поиск в подкаталогах

Выполним два пункта с выше?

три щёлка мышки
три щёлка мышки

выполнить три пункта)

поле для ввода имени файла
поле для ввода имени файла

выполним два пункта.

connnect_wifi.h: заголовочный файл предоставляет функции для подключения устройства к сети Wi-Fi. Вы можете обратиться к этой статье для получения дополнительных объяснений функций и API, используемых в библиотеке

  • КАК выделить текст знаете ? CTRL+C - скопировать CTRL+V - вставить. Ниже код. Выделить и вставить в espressif!!! connnect_wifi.h:
#ifndef CONNECT_WIFI_H_
#define CONNECT_WIFI_H_

#include <esp_system.h>
#include <nvs_flash.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "freertos/event_groups.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "esp_netif.h"
#include "driver/gpio.h"
#include <lwip/sockets.h>
#include <lwip/sys.h>
#include <lwip/api.h>
#include <lwip/netdb.h>
extern int wifi_connect_status;
void connect_wifi(void);
#endif
три щелка мышки
три щелка мышки

выполним три пункта?

создание файла
создание файла

Два пункта выполнить?

  • КАК выделить текст знаете ? CTRL+C - скопировать CTRL+V - вставить. Ниже код. Выделить и вставить в espressif!!! connnect_wifi.h:
#include "connect_wifi.h"
int wifi_connect_status = 0;
static const char *TAG = "Connect_WiFi";
int s_retry_num = 0;
#define WIFI_SSID "replace_with_your_ssid"
#define WIFI_PASSWORD "replace_with_your_password"
#define MAXIMUM_RETRY 5
EventGroupHandle_t s_wifi_event_group;
#define WIFI_CONNECTED_BIT BIT0
#define WIFI_FAIL_BIT BIT1
static void event_handler(void *arg, esp_event_base_t event_base,
int32_t event_id, void *event_data)
{
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START)
{ esp_wifi_connect(); }
else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED)
{ if (s_retry_num < MAXIMUM_RETRY)
{ esp_wifi_connect(); s_retry_num++;
ESP_LOGI(TAG, "retry to connect to the AP");
} else {xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT);
}
wifi_connect_status = 0; ESP_LOGI(TAG, "connect to the AP fail");
}
else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP)
{ ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data;
ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip));
s_retry_num = 0;
xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
wifi_connect_status = 1; }
}
void connect_wifi(void)
{ s_wifi_event_group = xEventGroupCreate();
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
esp_netif_create_default_wifi_sta();
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
esp_event_handler_instance_t instance_any_id;
esp_event_handler_instance_t instance_got_ip;
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
ESP_EVENT_ANY_ID, &event_handler, NULL, &instance_any_id));
ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT,
IP_EVENT_STA_GOT_IP, &event_handler, NULL, &instance_got_ip));
wifi_config_t wifi_config = {
.sta = { .ssid = WIFI_SSID, .password = WIFI_PASSWORD,
.threshold.authmode = WIFI_AUTH_WPA2_PSK, }
};
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
ESP_ERROR_CHECK(esp_wifi_start());
ESP_LOGI(TAG, "wifi_init_sta finished.");
EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group,
WIFI_CONNECTED_BIT | WIFI_FAIL_BIT,
pdFALSE, pdFALSE, portMAX_DELAY);
if (bits & WIFI_CONNECTED_BIT)
{ ESP_LOGI(TAG, "connected to ap SSID:%s password:%s",
WIFI_SSID, WIFI_PASSWORD);
} else if (bits & WIFI_FAIL_BIT)
{ ESP_LOGI(TAG, "Failed to connect to SSID:%s, password:%s",
WIFI_SSID, WIFI_PASSWORD);
} else { ESP_LOGE(TAG, "UNEXPECTED EVENT"); }
vEventGroupDelete(s_wifi_event_group);
}

ВАЖНО ОЧЕНЬ ДАЖЕ 🏳‍🌈 обратите внимание на строки в коде

#define WIFI_SSID "replace_with_your_ssid"
#define WIFI_PASSWORD "replace_with_your_password"

Это для идентификации ИМЯ и пароль к точки доступа (модем или роутер, который раздаёт ip адреса) если неправильно указать , то всё выше зря делали. ранее про список необходимого шла речь

#define WIFI_SSID "QQQ" //имя раздатчика ip адресов
#define WIFI_PASSWORD "!43405xaa" // пароль для его использования

это доступ к wifi . который даётся к ПК и раздаёт ip адреса свободные. esp32-cam будет станцией, которая подключится к раздатчику ip адресов и после этого станет открытым WEB сервером для всех получив свой ip адрес. Зная его подключимся к нему по wifi.

ПРИМ: Если точек доступа много , то выберите ту , которая вам раздаёт
ip адреса .
Так, что выберете узнайте имя точки доступа - раздатчика ip адресов и пароль к нему? 😉 Введите данные!!! Пароль и имя точки ДОСТУПА)))👌 Ниже указано как настроить точку доступа wifi yota(😊

убедитесь в соответствии паролей. кстати DHCP должен быть тоже настроен на раздачу  ip адресов.👌
убедитесь в соответствии паролей. кстати DHCP должен быть тоже настроен на раздачу ip адресов.👌

Запустим отладчик🏳‍🌈

будем надеяться , что библиотека нас не подведёт
будем надеяться , что библиотека нас не подведёт

Нажимаем на отладку! начнётся сборка.

ОБЛОМММ  ОЛБЛОММ облом🤢
ОБЛОМММ ОЛБЛОММ облом🤢

А появился сам sdcconfig(🚩 два раз щёлк! ПО sdcconfig( клац, клац МЫШЕЙ?

в настройки забурились , где чёрт нору  уже не раз ломал.🤔
в настройки забурились , где чёрт нору уже не раз ломал.🤔

ВЫПОЛНИМ пункты?

разрешили и включили
разрешили и включили

пункты два выполним!🚩

камеру надо выбирать и её настройки сохранять
камеру надо выбирать и её настройки сохранять

выберем камеру в два пункта😂 сохранимся - закроем - это третий пункт

отладка  -это когда за вас и всё  нормально
отладка -это когда за вас и всё нормально

Возникли две ошибки по первой ниже смотрим и выполняем - устраняем причину.

может это не возникнуть , но имейте в виду всё возможно.
может это не возникнуть , но имейте в виду всё возможно.

верхний код удалим , а ниже укажем

httpd_uri_t uri_get = {
.uri = "/",
.method = HTTP_GET,
.handler = jpg_stream_httpd_handler,
.user_ctx = NULL};
///----------------------
httpd_handle_t setup_server(void) {
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
httpd_handle_t stream_httpd = NULL;
if (httpd_start(&stream_httpd , &config) == ESP_OK)
{httpd_register_uri_handler(stream_httpd , &uri_get); }
return stream_httpd;
}

Устраним согласно стрелкам.

ESP_LOGI(TAG, "MJPG: %uKB %ums (%.1ffps)", (uint32_t)(_jpg_buf_len/1024), (uint32_t)frame_time, 1000.0 / (uint32_t)frame_time);

(данный код чисто информирует и не важно на данном этапе насколько правильно) заменим

ESP_LOGI(TAG, "MJPG: %uKB %ums (%.1ffps)", (uint8_t)(_jpg_buf_len/1024), (uint8_t)frame_time, 1000.0 / (uint8_t)frame_time);
данная кнопка запуск отладки
данная кнопка запуск отладки

Запустим отладчик.

и видим засаду?
и видим засаду?

СНОВА в cdkconfig и далее по смыслу = сохраним?

изменили  настройки
изменили настройки
пункт 2 - это сброс ссылок после первой настройки
пункт 2 - это сброс ссылок после первой настройки

Выполним три пункта 😉

если красного нет нигде.  error =0 ✔
если красного нет нигде. error =0 ✔

ПОБЕДА? подсоединим esp32-cam

пункт 2  сообщил , что контакт произощёл
пункт 2 сообщил , что контакт произощёл

на плате перемычка стоит на прошивку стоит ? RZT - нажата?

По пунктам выполняем и смотрим результат.

проценты натекли?
проценты натекли?

Если проценты есть, то значит прошивка прошла.

Перемычку снимаем и REZET запускаем?

смотрим номер порта?
смотрим номер порта?

ЗАПУСТИ УТИЛИТУ ( НА ПРОСТОРАХ НАЙТИ МОЖНО

ПО ПУНКТАМ
ПО ПУНКТАМ

НА esp32-cam нажимаем RZT👌

ИЩЕМ IP АДРЕС. есть!!!!😃 = ПУНКТ 5😙

КАБЫ  В ПОТОЛОК КАМЕРА СМОТРИТ.
КАБЫ В ПОТОЛОК КАМЕРА СМОТРИТ.

ПРОШЛЫЙ МАТЕРИАЛ

ТОЖЕ ПРОШЛЫЙ МАТЕРИАЛ

ранее ПОДАННЫЙ МАТЕРИАЛ