В современных встраиваемых системах возможности подключения так же важны, как и вычислительная мощность. Wi-Fi — это технология беспроводной связи, позволяющая устройствам обмениваться данными по локальным сетям с использованием стандартов IEEE 802.11. Благодаря интеграции Wi-Fi наш микроконтроллер превращается из изолированного калькулятора в устройство Интернета вещей (IoT), способное синхронизироваться с облачными серверами, предоставлять веб-интерфейсы пользователя и взаимодействовать с другими интеллектуальными устройствами.

ESP32-S3 оснащен высокоинтегрированным модулем Wi-Fi и MAC (Media Access Control). В рамках ESP-IDF драйвер Wi-Fi использует несколько основных системных компонентов, в первую очередь энергонезависимую память (NVS) для сохранения сетевых учетных данных и цикл событий для управления асинхронными сетевыми событиями, такими как подключение, отключение или получение IP-адреса.
Wi-Fi-устройство может работать в различных режимах в зависимости от потребностей проекта:
- Режим станции (STA): ESP32-S3 выступает в качестве клиента и подключается к существующему маршрутизатору.
- Режим точки доступа (AP): ESP32-S3 создает собственную сеть Wi-Fi, позволяя другим устройствам, таким как смартфоны или ноутбуки, подключаться к ней напрямую.
- Режим AP+STA: чип выполняет обе функции одновременно.
Wi-Fi-связь на ESP32-S3 осуществляется через сетевой стек ESP-IDF, построенный на основе TCP/IP и FreeRTOS.
- Изучение возможностей Wi-Fi на ESP32-S3.
- Настройка режима точки доступа (AP).
- Настройка режима станции (STA).
Wi-Fi — это технология беспроводной связи, основанная на стандарте IEEE 802.11. Вместо использования физических кабелей Ethernet устройства обмениваются данными, передавая их посредством радиоволн.
Типичная сеть Wi-Fi включает в себя:
- Маршрутизатор или точка доступа (AP), управляющая сетью.
- Множество клиентских устройств, таких как смартфоны, ноутбуки, датчики или микроконтроллеры, например, ESP32-S3.
Когда устройства подключаются к одной и той же сети Wi-Fi, они могут обмениваться данными, используя сетевые протоколы и уникальные IP-адреса. Когда устройство подключается к сети:
- Маршрутизатор выполняет аутентификацию устройства.
- Устройство получает IP-адрес.
- Обмен данными происходит в виде пакетов.
Wi-Fi обеспечивает лишь беспроводное соединение между устройствами. Он действует как канал, позволяющий устройствам передавать сигналы по воздуху. Однако сам по себе Wi-Fi не определяет, как данные организуются, передаются, доставляются или понимаются между устройствами.
Для обеспечения связи ESP32-S3 использует сетевые протоколы более высокого уровня, в основном:
- TCP/IP обеспечивает обмен данными между устройствами по сети.
- Протокол HTTP обеспечивает обмен данными между веб-клиентами и веб-серверами.
TCP/IP — это базовая структура, позволяющая устройствам взаимодействовать друг с другом в любой сети. Это сочетание двух различных протоколов:
- Интернет-протокол (IP): сосредоточен на адресации и маршрутизации. Каждому устройству присваивается цифровой адрес (например,
192.168.1.50) и данные разбиваются на более мелкие пакеты для их отправки. Не гарантируется безопасная доставка. - Протокол управления передачей (TCP), который работает поверх IP и обеспечивает надежность. Он устанавливает стабильное соединение перед отправкой данных, отслеживает пакеты, упорядочивает их в правильном порядке и запрашивает повторную отправку, если что-либо потеряно или повреждено.
В ESP32-S3 протокол TCP/IP интегрирован в сетевой стек ESP-IDF, который автоматически обрабатывает все низкоуровневые сетевые коммуникации. После подключения к Wi-Fi устройство может получить IP-адрес, установить TCP-соединения и взаимодействовать с другими устройствами без необходимости ручного управления обработкой пакетов.
HTTP, или протокол передачи гипертекста, построен на основе TCP/IP и используется специально для веб-коммуникаций. В то время как TCP/IP определяет способ передачи данных, HTTP определяет, что означают эти данные и как они должны быть структурированы при обмене между такими системами, как веб-браузеры, серверы и устройства IoT.
Протокол HTTP использует модель «клиент-сервер», где одно устройство отправляет запрос, а другое — отвечает. Клиент запрашивает ресурс или отправляет данные, а сервер обрабатывает этот запрос и возвращает ответ. Такая структурированная коммуникация позволяет устройствам взаимодействовать предсказуемым и стандартизированным образом.
Например, когда ESP32-S3 выступает в качестве HTTP-клиента, он может отправлять данные с датчиков на веб-сервер с помощью HTTP-запроса. Запрос содержит как сами данные, так и инструкции о том, какое действие следует выполнить, например, сохранить данные или проанализировать их. Затем сервер отвечает сообщением о состоянии, подтверждающим успешность запроса или возвращающим дополнительную информацию.
В протоколе HTTP используются различные методы для определения способа обмена данными между клиентом и сервером. Наиболее распространенными являются GET, POST и PUT.
- Метод GET используется для получения данных с сервера без внесения каких-либо изменений. Он в основном используется для чтения информации.
- Метод POST используется для отправки данных на сервер, например, для загрузки значений датчиков, таких как температура или влажность.
- Метод PUT используется для обновления существующих данных на сервере.
Когда ESP32-S3 настроен в режиме точки доступа (AP), он создает собственную беспроводную сеть и транслирует идентификатор набора служб (SSID). Находящиеся поблизости устройства, такие как смартфоны, ноутбуки или планшеты, могут сканировать этот SSID и подключаться непосредственно к ESP32-S3 так же, как они подключаются к стандартному Wi-Fi-роутеру.
В этом режиме ESP32-S3 также может работать как HTTP-сервер. Это позволяет микроконтроллеру функционировать как небольшой веб-сервер, способный размещать веб-страницы, получать данные из веб-форм и взаимодействовать с мобильными или веб-приложениями. В результате пользователи могут взаимодействовать с ESP32-S3 через браузерный интерфейс без необходимости внешнего подключения к Интернету или маршрутизатора.
Прежде чем устройства смогут подключаться к ESP32-S3, необходимо инициализировать и настроить драйвер Wi-Fi в режиме точки доступа (AP). Здесь приведен пример того, как можно инициализировать стек Wi-Fi, перевести ESP32-S3 в режим точки доступа и настроить основные сетевые учетные данные.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
#include "esp_wifi.h" #include "esp_event.h" #include "nvs_flash.h" #include <string.h> void wifi_init_ap(void) { // Initialize NVS nvs_flash_init(); // Initialize TCP/IP stack esp_netif_init(); // Create default event loop esp_event_loop_create_default(); // Create default Wi-Fi AP interface esp_netif_create_default_wifi_ap(); // Initialize Wi-Fi driver wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); esp_wifi_init(&cfg); // Configure Access Point settings wifi_config_t ap_config = { .ap = { .ssid = "ESP32_AP", .ssid_len = strlen("ESP32_AP"), .password = "mypassword123", .max_connection = 4, .authmode = WIFI_AUTH_WPA_WPA2_PSK }, }; // Set Wi-Fi mode to Access Point esp_wifi_set_mode(WIFI_MODE_AP); // Apply AP configuration esp_wifi_set_config(WIFI_IF_AP, &ap_config); // Start Wi-Fi esp_wifi_start(); } |
Прежде чем модуль Wi-Fi сможет включиться, код инициализирует основную программную среду:
nvs_flash_init(): настраивает энергонезависимую память (NVS). Драйвер Wi-Fi ESP32 использует эту постоянную память для хранения данных калибровки и внутренних конфигураций Wi-Fi.esp_netif_init(): инициализирует базовый сетевой стек TCP/IP, который позволяет микросхеме управлять IP-адресами и сетевыми пакетами.esp_event_loop_create_default(): создает общесистемный цикл событий. Поскольку операции Wi-Fi происходят асинхронно (например, подключение или отключение устройства), этот цикл отправляет оповещения, на которые ваш код сможет отреагировать позже.esp_netif_create_default_wifi_ap(): создает сетевой интерфейс по умолчанию, специально адаптированный для точки доступа, привязывая стек TCP/IP к оборудованию Wi-Fi.esp_wifi_init(&cfg): код загружает набор стандартных, безопасных внутренних конфигурацийWIFI_INIT_CONFIG_DEFAULT()и передает их функции инициализации Wi-Fi. Это выделяет необходимую память, запускает задачу Wi-Fi и пробуждает драйвер Wi-Fi.
Далее, код определяет функциональность вашей точки доступа, используя структуру wifi_config_t:
- SSID (
"ESP32_AP"): это общедоступное имя сети Wi-Fi, которое устройства будут видеть при сканировании. - Пароль (
"mypassword123"): ключ безопасности, необходимый для подключения к сети. - Максимальное количество подключений (
4): ограничивает количество одновременно подключенных клиентских устройств в сети до 4, экономя оперативную память и вычислительную мощность. - Режим аутентификации (
WIFI_AUTH_WPA_WPA2_PSK): обеспечивает стандартную безопасность WPA/WPA2. Последующее условиеifслужит проверкой безопасности: если строка пароля полностью пуста, режим безопасности автоматически понижается доWIFI_AUTH_OPEN, позволяя любому подключиться без пароля.
После определения конфигурации точки доступа ESP32 переключается в режим точки доступа, конфигурация применяется, и запускается служба Wi-Fi.
esp_wifi_set_mode(WIFI_MODE_AP): эта опция настраивает ESP32 на работу исключительно в режиме точки доступа, позволяя ему создавать и транслировать собственную беспроводную сеть вместо подключения к другому маршрутизатору в качестве клиента.esp_wifi_set_config(WIFI_IF_AP, &ap_config): применяет ранее определенные настройки точки доступа, включая SSID, пароль, режим аутентификации и максимальное количество подключенных клиентов.esp_wifi_start(): запускает драйвер Wi-Fi и позволяет радиомодулю ESP32 начать трансляцию настроенной сети и принимать входящие клиентские подключения.
На этом этапе устройства могут успешно подключаться к сети Wi-Fi ESP32-S3. Однако простого подключения к сети недостаточно для осуществления связи. ESP32 по-прежнему необходим способ приема запросов и отправки ответов подключенным устройствам. Именно здесь вступает в действие HTTP-сервер.
HTTP-сервер позволяет ESP32-S3 работать как миниатюрный веб-сервер. После запуска сервера телефоны, ноутбуки или браузеры, подключенные к точке доступа ESP32, могут отправлять HTTP-запросы, такие как:
- Открытие веб-страницы, размещенной на ESP32.
- Отправка команд для управления светодиодами или датчиками.
- Запрос показаний датчиков или информации о системе.
- Обмен данными с микроконтроллером через API.
Без HTTP-сервера ESP32 создаст сеть Wi-Fi, но подключенные устройства не смогут структурированно взаимодействовать с встроенным программным обеспечением микроконтроллера. Фреймворк ESP-IDF уже предоставляет легковесную встроенную библиотеку HTTP-сервера esp_http_server, которая значительно упрощает создание веб-интерфейсов и REST API.
Вот простой пример, демонстрирующий, как создать и запустить HTTP-сервер, а также зарегистрировать базовую веб-точку доступа на ESP32-S3:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
#include "esp_http_server.h" // 1. Define the handler function for incoming requests esp_err_t hello_get_handler(httpd_req_t *req) { const char* resp_str = "Hello from ESP32-S3!"; // Send the response back to the client httpd_resp_send(req, resp_str, HTTPD_RESP_USE_STRLEN); return ESP_OK; } // 2. Define the URI structure linking the URL to the handler httpd_uri_t hello_uri = { .uri = "/hello", .method = HTTP_GET, .handler = hello_get_handler, .user_ctx = NULL }; // 3. Function to initialize and start the server httpd_handle_t start_webserver(void) { httpd_handle_t server = NULL; // Pull default server configuration httpd_config_t config = HTTPD_DEFAULT_CONFIG(); // Start the HTTP server if (httpd_start(&server, &config) == ESP_OK) { // Register the URI handler if the server starts successfully httpd_register_uri_handler(server, &hello_uri); return server; } return NULL; // Return NULL if server failed to start } |
Прежде чем сервер сможет начать прослушивание входящих соединений, код инициализирует свои основные настройки и запускает соответствующую задачу:
httpd_config_t config = HTTPD_DEFAULT_CONFIG()- эта команда извлекает набор стандартных, безопасных внутренних конфигураций для веб-сервера. Она обрабатывает такие фоновые детали, как назначение порта веб-трафика по умолчанию (порт 80), установка максимального количества открытых сокетов и определение приоритетов задач.httpd_start(&server, &config): выделяет необходимую память, запускает фоновую задачу HTTP-сервера и открывает порт прослушивания на ранее созданном интерфейсе сети Wi-Fi. В случае успеха, присваивает запущенный экземпляр сервера нашей переменнойserver.
Далее, код определяет поведение нашей веб-конечной точки с помощью структуры httpd_uri_t. Это определяет, как сервер должен маршрутизировать входящий трафик:
- URI (
"/hello"): конкретный сетевой путь или конечная точка, к которой будет обращаться клиент (например,[http://192.168.4.1/hello](http://192.168.4.1/hello)). - Метод (
HTTP_GET): тип ожидаемого HTTP-запроса.HTTP_GETповсеместно используется для получения данных (например, при загрузке веб-страницы), тогда как другие методы, такие как ,HTTP_POSTиспользуются для получения данных от клиента. - Handler (
hello_get_handler): указатель на пользовательскую функцию на языке C, которую ESP32-S3 будет автоматически выполнять всякий раз, когда клиент переходит по этому конкретному URI. - Контекст пользователя (
NULL): необязательный указатель, позволяющий передавать пользовательские данные или переменные в функцию обработчика. Здесь мы оставляем его пустым.
После запуска сервера и определения правил маршрутизации код связывает их между собой и обрабатывает фактический ответ клиента:
httpd_register_uri_handler(server, &hello_uri): привязывает созданную нами структуру URI к активному серверу. Это действует как каталог сервера, точно указывая, какую функцию следует запустить при поступлении соответствующего запроса.httpd_resp_send(req, resp_str, HTTPD_RESP_USE_STRLEN): этот код, находящийся внутри нашей функции-обработчика, принимает нашу исходную строку ("Hello from ESP32-S3!"), автоматически вычисляет её длину с помощьюHTTPD_RESP_USE_STRLEN, и упаковывает её в стандартный HTTP-ответ. Затем он передаёт эту полезную нагрузку обратно по Wi-Fi в браузер или устройство, которое её запросило.
Обработка запросов
Теперь, когда HTTP-сервер запущен, следующим шагом будет изучение того, как ESP32 обрабатывает входящие запросы от подключенных устройств.
Когда браузер, мобильное приложение или другой клиент взаимодействует с ESP32, он отправляет HTTP-запрос на определенный адрес, называемый URI (Uniform Resource Identifier). URI работает как маршрут или конечная точка, которая указывает серверу, какая функциональность должна быть выполнена.
Например:
/→ Главная страница/led/on→ Включить светодиод/sensor→ Считывание данных с датчика/api/data→ Возвращает информацию в формате JSON
HTTP-сервер ESP32 позволяет прикреплять к этим URI функции-обработчики. При каждом обращении клиента к определенному маршруту соответствующая функция-обработчик автоматически выполняется.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
#include "esp_http_server.h" // Handler function esp_err_t hello_handler(httpd_req_t *req){ const char* response = "Hello from ESP32!"; httpd_resp_send(req, response, HTTPD_RESP_USE_STRLEN); return ESP_OK; } // URI configuration httpd_uri_t hello_uri = { .uri = "/hello", .method = HTTP_GET, .handler = hello_handler, .user_ctx = NULL }; |
Эта функция hello_handler() отвечает за генерацию ответа, отправляемого клиенту. Внутри функции httpd_resp_send() осуществляется передача данных через HTTP-соединение.
Структура httpd_uri_t определяет, как будет вести себя маршрут:
.uriуказывает адрес конечной точки..methodопределяет метод HTTP, напримерGET, илиPOST..handlerуказывает на функцию, выполняемую при поступлении запроса..user_ctxможет хранить необязательные пользовательские данные.
Однако одного лишь указания URI недостаточно. Обработчик также должен быть зарегистрирован на работающем HTTP-сервере.
|
1 |
httpd_register_uri_handler(server, &hello_uri); |
После регистрации посетите:
|
1 |
http://192.168.4.1/hello |
При подключении браузера к точке доступа ESP32 обработчик будет запущен, и будет возвращен следующий результат:
|
1 |
Hello from ESP32! |
Отправка обычного текста полезна для тестирования, но большинству реальных приложений требуются полноценные веб-страницы с кнопками, стилями и интерактивным контентом.
Вместо возврата простых строк, ESP32 может также отправлять полные HTML-документы непосредственно в браузер.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
esp_err_t webpage_handler(httpd_req_t *req){ const char* html_page = "<!DOCTYPE html>" "<html>" "<head>" "<title>ESP32 Web Server</title>" "</head>" "<body>" "<h1>ESP32-S3 Web Server</h1>" "<p>Hello from the ESP32!</p>" "</body>" "</html>"; httpd_resp_set_type(req, "text/html"); httpd_resp_send(req, html_page, HTTPD_RESP_USE_STRLEN); return ESP_OK; } |
Перед отправкой ответа тип содержимого изменяется следующим образом:
|
1 |
httpd_resp_set_type(req, "text/html"); |
Этот заголовок сообщает браузеру, что ответ содержит HTML-код, а не обычный текст. Без этого заголовка браузер просто отобразил бы необработанный HTML-код как текст.
После загрузки страницы в браузере ESP32 работает как миниатюрный веб-сервер, способный размещать панели мониторинга, панели управления и интерфейсы мониторинга.
Этот метод GET в основном используется, когда клиент хочет получить информацию с ESP32.
Например:
- Считывание показаний датчика.
- Загрузка веб-страниц.
- Запрос состояния системы.
- Получение информации о конфигурации.
Браузер автоматически отправляет запрос GET при каждом открытии веб-страницы.
|
1 2 3 4 5 6 |
httpd_uri_t sensor_uri = { .uri = "/sensor", .method = HTTP_GET, .handler = sensor_handler, .user_ctx = NULL }; |
Когда пользователь обращается к функции /sensor, она выполняет sensor_handler() и может возвращать показания датчиков или информацию об устройстве.
GET-запросы просты и не требуют больших объемов данных, поскольку обычно не содержат большого количества входящих данных.
В отличие от метода GET, который в основном используется для запроса или получения данных с сервера, метод POST применяется, когда клиенту необходимо отправить данные на ESP32. Используя этот метод POST, веб-интерфейс может напрямую взаимодействовать с ESP32 и безопасно и эффективно передавать пользовательский ввод, значения конфигурации или команды.
Вот простой обработчик POST-запросов:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
esp_err_t post_handler(httpd_req_t *req){ char buffer[100]; int received = httpd_req_recv(req, buffer, req->content_len); if (received <= 0) { return ESP_FAIL; } buffer[received] = '\0'; printf("Received Data: %s\n", buffer); httpd_resp_send(req, "Data Received", HTTPD_RESP_USE_STRLEN); return ESP_OK; } |
Самое важное здесь следующее:
|
1 |
httpd_req_recv() |
Эта функция считывает и извлекает входящие данные, отправленные клиентом. Например, веб-страница может отправить:
|
1 |
led=on&motor=off |
ESP32 получает эти данные, обрабатывает их и выполняет необходимое действие.
Для регистрации маршрута в качестве POST-запроса используется следующий код HTTP_POST:
|
1 2 3 4 5 6 |
httpd_uri_t post_uri = { .uri = "/submit", .method = HTTP_POST, .handler = post_handler, .user_ctx = NULL }; |
До этого момента мы рассматривали ESP32 как традиционный веб-сервер, генерирующий целые HTML-страницы и отправляющий их в браузер. Хотя это работает для базовых конфигураций, современная веб-разработка обычно работает иначе. Вместо отправки громоздких, предварительно отформатированных пользовательских интерфейсов устройства передают друг другу необработанные, легковесные данные, оставляя пользовательский интерфейс для отрисовки мобильным приложением, фронтенд-фреймворком (например, React или Vue) или настольным приложением.
Для эффективного выполнения этой задачи мы используем JSON.
JSON, что расшифровывается как JavaScript Object Notation (нотация объектов JavaScript), — это легковесный текстовый формат, используемый для хранения и передачи данных. Представьте его как универсальную валюту интернета. Независимо от того, написан ли ваш сервер на C (как ESP32), ваше мобильное приложение на Swift или ваш фронтенд на JavaScript, все они могут читать и записывать JSON без потери данных при передаче.
JSON полностью построен на двух структурах:
- Пары «ключ-значение»: ключ должен представлять собой строку в двойных кавычках, за которой следует двоеточие, а затем его значение.
- Объекты: наборы этих пар, заключенные в фигурные скобки
{}.
Вот как выглядят стандартные JSON-данные, представляющая показания датчиков:
|
1 2 3 4 5 6 |
{ "temperature": 24.5, "humidity": 60, "device_name": "ESP32_LivingRoom", "status_ok": true } |
Вот как мы реализуем чистый JSON-ответ с помощью компонента HTTP-сервера ESP-IDF:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
esp_err_t json_handler(httpd_req_t *req){ const char* json_response = "{" "\"temperature\":24," "\"humidity\":60" "}"; httpd_resp_set_type(req, "application/json"); httpd_resp_send(req, json_response, HTTPD_RESP_USE_STRLEN); return ESP_OK; } |
application/json: это ключевое изменение. Изменив заголовокContent-Type, браузер или API-клиент сразу понимает, что нужно интерпретировать этот ответ как объект, а не отображать его в виде одной строки текста.- Экранирование строк (
\"): поскольку в C для обозначения начала и конца строк используются двойные кавычки, нам необходимо использовать обратную косую черту (\), чтобы сообщить компилятору: «Эй, эта кавычка должна находиться внутри фактического текстового пакета, который мы отправляем».
Хотя режим точки доступа (AP) отлично подходит для локальной настройки и прямого управления, большинству IoT-приложений требуется доступ в интернет. Для этого мы настраиваем ESP32-S3 в режиме станции (STA). В этом режиме микроконтроллер работает точно так же, как ваш телефон или ноутбук: он аутентифицируется у локального маршрутизатора, используя SSID и пароль, подключается к сети и запрашивает IP-адрес через DHCP.
После подключения ESP32-S3 становится частью локальной сети. Это позволяет микроконтроллеру:
- Получите доступ к Интернету.
- Взаимодействие с облачными сервисами.
- Отправка HTTP-запросов на внешние серверы.
- Подключение к MQTT-брокерам.
- Обмен данными с мобильными или настольными приложениями.
- Получите доступ к устройствам, уже подключенным к сети.
Как и в режиме точки доступа, драйвер Wi-Fi необходимо тщательно инициализировать, прежде чем ESP32-S3 сможет попытаться подключиться к маршрутизатору. Процесс настройки очень похож, но основной сетевой интерфейс и структуры конфигурации специально разработаны для работы в качестве клиента.
Вот пример того, как мы инициализируем стек Wi-Fi, переводим ESP32-S3 в режим STA и настраиваем учетные данные целевой сети.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
#include "esp_wifi.h" #include "esp_event.h" #include "nvs_flash.h" #include <string.h> void wifi_init_sta(void) { // Initialize NVS nvs_flash_init(); // Initialize TCP/IP stack esp_netif_init(); // Create default event loop esp_event_loop_create_default(); // Create default Wi-Fi Station interface esp_netif_create_default_wifi_sta(); // Initialize Wi-Fi driver wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); esp_wifi_init(&cfg); // Configure Station settings wifi_config_t sta_config = { .sta = { .ssid = "Home_Network", .password = "myrouterpassword", // Require a minimum security standard .threshold.authmode = WIFI_AUTH_WPA2_PSK, }, }; // Set Wi-Fi mode to Station esp_wifi_set_mode(WIFI_MODE_STA); // Apply STA configuration esp_wifi_set_config(WIFI_IF_STA, &sta_config); // Start Wi-Fi esp_wifi_start(); // Connect to router esp_wifi_connect(); } |
Начальная настройка программной среды практически идентична режиму точки доступа, за исключением одного важного отличия:
esp_netif_create_default_wifi_sta(): вместо создания интерфейса точки доступа (AP) эта функция создает сетевой интерфейс по умолчанию, специально разработанный для Wi-Fi-станции. Она подготавливает стек TCP/IP для работы в качестве клиента, запрашивающего IP-адрес, а не в качестве маршрутизатора, назначающего их.
Далее мы определяем целевую сеть, используя структуру wifi_config_t, но на этот раз заполняем структуру (Station) .sta вместо структуры .ap:
- SSID (
"Home_Network"): название маршрутизатора или сети, которую ESP32 должен искать. - Пароль (
"myrouterpassword"): пароль Wi-Fi для конкретного роутера. - Режим пороговой аутентификации (Threshold Authmode
WIFI_AUTH_WPA2_PSK): это функция безопасности. Она указывает ESP32-S3 отказывать в подключении к маршрутизатору, если уровень безопасности маршрутизатора ниже WPA2. Это предотвращает случайное подключение устройства к поддельной, незащищенной «фиктивной» сети с тем же именем.
После определения конфигурации ESP32 переключается в режим STA, выполняется его настройка и запуск:
esp_wifi_set_mode(WIFI_MODE_STA): явно указывает Wi-Fi-модулю действовать в качестве клиента.esp_wifi_set_config(WIFI_IF_STA, &sta_config): загружает учетные данные целевого маршрутизатора в память.esp_wifi_start(): включает модуль Wi-Fi. Однако, в отличие от режима точки доступа (AP), запуск Wi-Fi в режиме станции (STA) не приводит к автоматическому подключению к сети. Он просто включает модуль и подготавливает его к началу процесса установления соединения.esp_wifi_connect(): запускает полный процесс подключения к Wi-Fi. ESP32 начинает сканирование целевой сети, обнаруживает маршрутизатор, выполняет аутентификацию и установление соединения, а затем запрашивает конфигурацию сети через DHCP. После успешного завершения процесса маршрутизатор назначает IP-адрес, позволяя ESP32 подключиться к локальной сети и обмениваться данными через Интернет.
Для подключения к маршрутизатору требуется асинхронное рукопожатие: ESP32 должен просканировать сеть, пройти аутентификацию, установить соединение и, наконец, запросить IP-адрес. Поскольку этот процесс занимает время и подвержен ошибкам, таким как неверный пароль или слабый сигнал, мы управляем им с помощью цикла событий (Event Loop).
ESP32 генерирует события для:
- успешного соединения;
- отключения;
- приобретения интеллектуальной собственности;
- ошибок аутентификации;
- в случае потери сигнала;
- попыток восстановления соединения.
При подключении к Wi-Fi важно зарегистрировать функцию обработчика событий, которая будет отслеживать события, связанные с Wi-Fi и IP-адресом. Это позволит программе точно знать, когда ESP32 успешно подключился к сети и получил IP-адрес, что обеспечит безопасную передачу данных через интернет.
Давайте создадим простую функцию, которая обрабатывает события Wi-Fi.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
// Define the event handler function static void wifi_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) { // The Wi-Fi radio has successfully started. Now, tell it to connect. esp_wifi_connect(); printf("Wi-Fi started, attempting to connect...\n"); } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) { // The connection failed, or we lost the signal. Try again. esp_wifi_connect(); printf("Disconnected from router. Retrying connection...\n"); } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) { // The router accepted us and assigned an IP address! ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data; printf("Successfully connected! My IP is: " IPSTR "\n", IP2STR(&event->ip_info.ip)); } } |
Эта функция выполняет функцию контроля трафика сетевых событий. Она отслеживает два основных момента: event_base (является ли это событие, связанное с Wi-Fi-оборудованием, или событие, связанное с IP-адресом?) и event_id (что именно произошло?).
WIFI_EVENT_STA_START: это событие срабатывает сразу после успешного завершенияesp_wifi_start(). Оно дает зеленый свет для вызова функцииesp_wifi_connect(), которая официально запускает процедуру установления соединения с вашим домашним маршрутизатором.WIFI_EVENT_STA_DISCONNECTED: это событие срабатывает, если маршрутизатор отклоняет пароль, если маршрутизатор выключен или если ESP32 выходит из зоны действия. Вызов функцииesp_wifi_connect()запускает автоматический бесконечный цикл повторных попыток.IP_EVENT_STA_GOT_IP: это конечная цель. Простого подключения к Wi-Fi недостаточно; ESP32 не сможет использовать интернет, пока DHCP-сервер маршрутизатора не назначит ему IP-адрес. Когда это событие происходит, процесс подключения полностью завершен.
Для корректной работы этого обработчика необходимо зарегистрировать обработчики событий до вызова метода esp_wifi_start(). Поскольку теперь метод esp_wifi_connect() вызывается внутри функции обработчика событий, мы можем удалить его из функции wifi_init_sta().
|
1 2 |
esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler, NULL, NULL); esp_event_handler_instance_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &wifi_event_handler, NULL, NULL); |
Функция esp_event_handler_instance_register() принимает пять аргументов:
- Базовый параметр события указывает категорию события, например
WIFI_EVENT, илиIP_EVENT. - Идентификатор события определяет конкретное событие, которое следует отслеживать.
ESP_EVENT_ANY_ID- отслеживает все события в этой категории. - Функция обработчика событий. Указатель на функцию обратного вызова, которая будет выполнена при возникновении события.
- Аргумент обработчика событий: необязательные пользовательские данные, передаваемые в функцию обработчика.
NULL- это означает, что дополнительные данные не предоставляются. - Объект экземпляра обработчика. Используется для хранения экземпляра обработчика с целью его последующего удаления при необходимости.
После срабатывания события IP_EVENT_STA_GOT_IP ESP32-S3 получает доступ к интернету. В то время как режим AP ориентирован на размещение HTTP-сервера для приема входящих запросов, режим STA в значительной степени полагается на HTTP-клиент для отправки исходящих запросов в остальной мир.
Вместо того чтобы ждать запроса веб-страницы от браузера, ESP32 действует как браузер. Он обращается к внешним API, веб-серверам или облачным платформам для получения или отправки данных методом GET или POST. Библиотека ESP-IDF предоставляет esp_http_client именно для этой цели.
Когда мы отправляем запрос на удалённый сервер, сервер отвечает HTTP-ответом (который включает коды состояния, такие как 200 OK или 404 Not Found, и фактические данные полезной нагрузки). Поскольку ответы могут быть большими и поступать с течением времени, HTTP-клиент использует обработчик событий для обработки данных по частям по мере их поступления.
Ниже приведён пример настройки клиента, отправки GET-запроса к внешнему API и обработки входящих данных ответа.
Сначала мы определяем обработчик событий для сбора данных ответа:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#include "esp_http_client.h" #include "esp_crt_bundle.h" esp_err_t client_event_handler(esp_http_client_event_t *evt) { switch(evt->event_id) { case HTTP_EVENT_ON_DATA: // This event is triggered when the client receives data from the server if (!esp_http_client_is_chunked_response(evt->client)) { // Print the incoming data payload to the terminal printf("Received Data: %.*s\n", evt->data_len, (char*)evt->data); } break; case HTTP_EVENT_ON_FINISH: printf("HTTP Request completed successfully.\n"); break; default: break; } return ESP_OK; } |
HTTP-клиент использует систему обратных вызовов, управляемую событиями, для асинхронной обработки ответа сервера.
Всякий раз, когда во время соединения происходит что-то важное (получение данных, завершение запроса, ошибки и т. д.), HTTP-клиент ESP-IDF автоматически вызывает зарегистрированную функцию обработчика событий.
HTTP_EVENT_ON_DATA- срабатывает всякий раз, когда ESP32 получает ответные данные от сервера.evt->dataуказывает на полученные байты полезной нагрузки.evt->data_len- это показывает, сколько байтов поступило.esp_http_client_is_chunked_response()- проверяет, отправляет ли сервер ответ порциями. Внутри этого события приложения обычно:- Анализ ответов в формате JSON или XML.
- Извлечение значений API.
- Сохранение данных в буферы.
- Запуск действий на основе полученной информации.
HTTP_EVENT_ON_FINISH: срабатывает после полного получения и обработки HTTP-ответа.
Например, если сервер возвращает данные о погоде, такие как:
|
1 |
{ "temperature": 28, "humidity": 65} |
В разделе HTTP_EVENT_ON_DATA ESP32 будет анализировать JSON-ответ и извлекать такие значения, как температура и влажность, для дальнейшей обработки.
Далее мы пишем функцию, которая фактически инициализирует HTTP-клиент, открывает соединение и выполняет запрос:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
void fetch_weather_data(void) { // 1. Configure the HTTP Client esp_http_client_config_t config = { .url = "https://power.larc.nasa.gov/api/temporal/daily/point?parameters=T2M&community=RE&longitude=3.0588&latitude=36.7538&start=20260510&end=20260511&format=JSON", .event_handler = client_event_handler, // Attach our handler .crt_bundle_attach = esp_crt_bundle_attach, }; esp_http_client_handle_t client = esp_http_client_init(&config); // 2. Specify the Request Method (GET is default, but we can explicitly set it) esp_http_client_set_method(client, HTTP_METHOD_GET); // 3. Perform the request esp_err_t err = esp_http_client_perform(client); if (err == ESP_OK) { printf("HTTP GET Status = %d, content_length = %lld\n", esp_http_client_get_status_code(client), esp_http_client_get_content_length(client)); } else { printf("HTTP GET request failed: %s\n", esp_err_to_name(err)); } // 4. Cleanup and free memory esp_http_client_cleanup(client); } |
Перед отправкой сетевого запроса выполняется настройка и инициализация HTTP-клиента:
esp_http_client_config_t config- эта структура хранит конфигурацию HTTP-клиента..urlуказывает точный адрес сервера, к которому будет подключаться ESP32..event_handler = client_event_handler- регистрирует функцию обратного вызова, отвечающую за обработку входящих событий и данных ответа.
esp_http_client_init(&config)- создает и инициализирует экземпляр HTTP-клиента. Внутри эта функция:- Выделяет память для клиента.
- Разбирает URL-адрес на компоненты хоста, порта и пути.
- Подготавливает сетевой уровень TCP/IP.
- Настраивает внутренние структуры соединений.
После инициализации настраивается метод запроса:
esp_http_client_set_method(client, HTTP_METHOD_GET): устанавливает тип HTTP-запроса на GET, что означает, что ESP32 хочет получить данные с сервера, не загружая новую информацию.
Далее выполняется фактическая сетевая транзакция:
esp_http_client_perform(client)- это блокирующая функция, которая выполняет всю HTTP-транзакцию. Внутри она:- Разрешает доменное имя с помощью DNS.
- Открывает TCP-соединение с удалённым сервером.
- Отправляет заголовки HTTP-запроса.
- Получает HTTP-ответ
- Запускает функции обратного вызова событий, такие как:
HTTP_EVENT_ON_DATA - Ожидает полного завершения транзакции.
После завершения запроса:
esp_http_client_get_status_code(client)- получает код состояния HTTP-ответа (например200 OK, или404 Not Found).esp_http_client_get_content_length(client)- возвращает размер полученной полезной нагрузки.
Окончательно:
esp_http_client_cleanup(client)- закрывает TCP-соединение и освобождает всю динамически выделенную память, используемую HTTP-клиентом, что помогает предотвратить утечки памяти во встроенных системах.
Одним из главных преимуществ режима станции (STA) является то, что ESP32-S3 может продолжать запускать HTTP-сервер, будучи подключенным к маршрутизатору.
Это означает, что устройства в одной сети могут взаимодействовать с ESP32-S3, не подключаясь к нему напрямую. Любой телефон, ноутбук или компьютер, подключенный к тому же маршрутизатору, может получить доступ к ESP32-S3, используя его локальный IP-адрес.
|
1 |
http://192.168.100.17 |
Еще одно важное преимущество заключается в том, что HTTP-сервер может быть доступен из интернета. Настроив переадресацию портов или используя доменное имя и DNS-сервис, ESP32-S3 может отправлять и получать данные из любой точки мира. Это позволяет осуществлять удаленное управление, интеграцию с облачными сервисами и мониторинг в реальном времени через интернет.
В этой конфигурации ESP32-S3 выполняет обе функции:
- Wi-Fi-клиент, подключенный к роутеру.
- Веб-сервер, обрабатывающий HTTP-запросы к другим устройствам или пользователям интернета.



