- ESP32: Wi-Fi
- Базовый минимальный пример
- Получить IP-адреса
- Узнать настройки Wi-Fi модуля
- WiFiScan
- Сканируем WiFi-сеть. Расширенный вариант
- Точка доступа
- Отслеживаем момент подключения и отключения устройства к точке доступа
- Mac-адрес для точки доступа
- Включаем поддержку IPv6
- Сколько устройств подключено к точке доступа
- Piranha ESP32 как точка доступа WiFi
- Видео:
- Нам понадобится:
- Подключение:
- Скетч проекта:
- Нажмите " "сюда " "для включения светодиода." ); client.print( "Нажмите " "сюда " "для выключения светодиода." ); client.print("
- Нажмите " "сюда " "для выключения светодиода." ); client.print("
- Ссылки
- Как настроить точку доступа на ESP32 для веб-сервера
- Установка ESP32 в Arduino IDE
- Код для создания точки доступа на ESP32
ESP32: Wi-Fi
Для работы с Wi-Fi понадобится встроенная библиотека WiFi.h (исходники). В большинстве примеров вам надо знать имя сети и пароль от него. После окончания работы желательно вызывать метод WiFi.disconnect(true);.
Базовый минимальный пример
Сначала рассмотрим базовый пример для общего понимания. Все пояснения в комментариях.
// Подключаем библиотеку #include "WiFi.h" // Указываем идентификатор и пароль от своей WiFi-сети const char* ssid = "yourNetworkName"; const char* password = "yourNetworkPassword"; void setup() < Serial.begin(115200); // Начинаем подключение к сети WiFi.begin(ssid, password); // Проверяем статус. Если нет соединения, то выводим сообщение о подключении while (WiFi.status() != WL_CONNECTED) < delay(1000); Serial.println("Соединяемся к WiFi-сети. "); >Serial.println("Есть подключение к WiFi-сети"); > void loop() <>
В нашем примере соединение с сетью WiFi происходит лишь в функции setup(), которая активируется только один раз при включении платы. Соответственно, при перезагрузке маршрутизатора или потере WiFi-сигнала соединение не будет восстановлено. Чтобы этого избежать, нужно добавить в функцию loop() проверку на необходимость восстановления соединения.
while (WiFi.status() != WL_CONNECTED)
Для простых примеров это не требуется, но в реально действующем коде такая проверка желательна.
Теперь можно писать более сложные примеры.
Получить IP-адреса
В пассивном режиме без входа в сеть вы получите IP-адрес, равный 0.0.0.0. Если нужно получить реальный адрес, то скетч нужно переписать. Добавим возможность входа в сеть, используя учётные данные.
#include "WiFi.h" const char* ssid = "yourNetworkName"; const char* password = "yourNetworkPassword"; void setup() < Serial.begin(115200); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) < delay(1000); Serial.println("Connecting to WiFi.."); >Serial.print("IP address: "); Serial.println(WiFi.localIP()); Serial.print("Hostname: "); Serial.println(WiFi.getHostname()); Serial.print("ESP Mac Address: "); Serial.println(WiFi.macAddress()); Serial.print("Subnet Mask: "); Serial.println(WiFi.subnetMask()); Serial.print("Gateway IP: "); Serial.println(WiFi.gatewayIP()); Serial.print("DNS: "); Serial.println(WiFi.dnsIP()); > void loop() <>
Теперь вы получите реальный IP-адрес. Узнав адрес через WiFi.localIP(), вы можете в командной строке ввести команду ping ESP_ADDRESS (подставьте ваш адрес), чтобы убедиться, что устройство находится в сети. Пригодится для отладки примеров.
Метод WiFi.getHostname() возвращает имя платы espressif. По идее по этому имени тоже можно обращаться через команду ping espressif, но у меня этот вариант не заработал.
Также привёл другие вызовы функций, которые встречаются в библиотеке.
Другой вариант получения IP-адреса через лямбда-функции.
#include "WiFi.h" const char* ssid = "yourNetworkName"; const char* password = "yourNetworkPassword"; void setup() < Serial.begin(115200); WiFi.onEvent([](WiFiEvent_t event, WiFiEventInfo_t info) < Serial.println(WiFi.localIP()); Serial.println(WiFi.getHostname()); >, SYSTEM_EVENT_STA_GOT_IP); WiFi.begin(ssid, password); > void loop() <>
Ещё один пример получения IP-адреса разными способами. На этот раз обойдёмся без лямбда-функции. Как и в предыдущем примере мы отслеживаем событие SYSTEM_EVENT_STA_GOT_IP и при его наступлении вычисляем адрес.
Адрес вычисляем тремя способами. Первый способ самый простой, вызываем функцию localIP() и получаем готовый результат. Второй способ — получаем информацию из WiFiEventInfo_t через его поле got_ip. Третий способ — используем класс IPAddress. Два последних способа даны для общего развития, пользуйтесь первым.
#include "WiFi.h" const char* ssid = "yourNetworkName"; const char* password = "yourNetworkPassword"; void WiFiStationGotIP(WiFiEvent_t event, WiFiEventInfo_t info) < Serial.println(WiFi.localIP()); // первый способ // второй способ Serial.print(ip4_addr1(&(info.got_ip.ip_info.ip))); Serial.print("."); Serial.print(ip4_addr2(&(info.got_ip.ip_info.ip))); Serial.print("."); Serial.print(ip4_addr3(&(info.got_ip.ip_info.ip))); Serial.print("."); Serial.print(ip4_addr4(&(info.got_ip.ip_info.ip))); Serial.println(); // третий способ Serial.println(IPAddress(info.got_ip.ip_info.ip.addr)); >void setup() < Serial.begin(115200); WiFi.onEvent(WiFiStationGotIP, SYSTEM_EVENT_STA_GOT_IP); WiFi.begin(ssid, password); >void loop() <>
Узнать настройки Wi-Fi модуля
Для скетча нам не понадобится вводить пароль от Wi-Fi, достаточно просто включить сам Wi-Fi на плате и узнать его Mac-адрес, запустить диагностику, узнать локальный адрес.
/* ESP-32 Example, start WiFi (without ssid and password) and print the MAC address to Serial. */ #include byte mac[6]; void setup() < Serial.begin(115200); delay(1000); Serial.print("\nRun diagnostic. \n"); WiFi.printDiag(Serial); Serial.println(); Serial.print("Program Start. "); WiFi.enableSTA(true); WiFi.begin(); Serial.println("WiFi began"); WiFi.macAddress(mac); Serial.print("MAC: "); Serial.print(mac[0], HEX); Serial.print(":"); Serial.print(mac[1], HEX); Serial.print(":"); Serial.print(mac[2], HEX); Serial.print(":"); Serial.print(mac[3], HEX); Serial.print(":"); Serial.print(mac[4], HEX); Serial.print(":"); Serial.println(mac[5], HEX); Serial.print("IP address: "); Serial.println(WiFi.localIP()); Serial.print("Hostname: "); Serial.println(WiFi.getHostname()); >void loop() <>
WiFiScan
Встроенный пример Examples/WiFi/WiFiScan служит для сканирования WiFi-сети. Выводит число найденных точек и их названия.
В скетче используются следующие функции:
- WiFi.mode(WIFI_STA) — устанавливает нужный режим
- WiFi.disconnect() — завершает соединение
- WiFi.scanNetworks() — сканирует сети и возвращает число найденных точек доступа
- WiFi.RSSI(i) — возвращает уровень сигнала по индексу
- WiFi.SSID(i) — возвращает имя точки доступа по индексу
#include "WiFi.h" void setup() < Serial.begin(115200); // Set WiFi to station mode and disconnect from an AP if it was previously connected WiFi.mode(WIFI_STA); WiFi.disconnect(); delay(100); Serial.println("Setup done"); >void loop() < Serial.println("scan start"); // WiFi.scanNetworks will return the number of networks found int n = WiFi.scanNetworks(); Serial.println("scan done"); if (n == 0) < Serial.println("no networks found"); >else < Serial.print(n); Serial.println(" networks found"); for (int i = 0; i < n; ++i) < // Print SSID and RSSI for each network found Serial.print(i + 1); Serial.print(": "); Serial.print(WiFi.SSID(i)); Serial.print(" ("); Serial.print(WiFi.RSSI(i)); Serial.print(")"); Serial.println((WiFi.encryptionType(i) == WIFI_AUTH_OPEN)?" ":"*"); delay(10); >> Serial.println(""); // Wait a bit before scanning again delay(5000); >
Сканируем WiFi-сеть. Расширенный вариант
Чтобы просканировать текущую WiFi-сеть, нам понадобятся учётная запись для входа в неё (идентификатор и пароль). После успешного входа запускаем сканирование через функцию WiFi.scanNetworks(), которая вернёт информацию о всех точках доступа с сопутствующими свойствами.
Для удобства часть кода поместим в отдельные функции: scanNetworks() и connectToNetwork() (её можно использовать при использовании контроллера в качестве веб-клиента.
#include const char* ssid = "yourNetworkName"; const char* password = "yourNetworkPassword"; String translateEncryptionType(wifi_auth_mode_t encryptionType) < switch (encryptionType) < case (WIFI_AUTH_OPEN): return "Open"; case (WIFI_AUTH_WEP): return "WEP"; case (WIFI_AUTH_WPA_PSK): return "WPA_PSK"; case (WIFI_AUTH_WPA2_PSK): return "WPA2_PSK"; case (WIFI_AUTH_WPA_WPA2_PSK): return "WPA_WPA2_PSK"; case (WIFI_AUTH_WPA2_ENTERPRISE): return "WPA2_ENTERPRISE"; >> void scanNetworks() < int numberOfNetworks = WiFi.scanNetworks(); Serial.print("Number of networks found: "); Serial.println(numberOfNetworks); for (int i = 0; i < numberOfNetworks; i++) < Serial.print("Network name: "); Serial.println(WiFi.SSID(i)); Serial.print("Signal strength: "); Serial.println(WiFi.RSSI(i)); Serial.print("MAC address: "); Serial.println(WiFi.BSSIDstr(i)); Serial.print("Encryption type: "); String encryptionTypeDescription = translateEncryptionType(WiFi.encryptionType(i)); Serial.println(encryptionTypeDescription); Serial.println("-----------------------"); >> void connectToNetwork() < WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) < delay(1000); Serial.println("Соединяемся с Wi-Fi.."); >Serial.println("Соединение с Wi-Fi установлено"); > void setup() < Serial.begin(115200); scanNetworks(); connectToNetwork(); Serial.println(WiFi.macAddress()); Serial.println(WiFi.localIP()); WiFi.disconnect(true); Serial.println(WiFi.localIP()); >void loop() <>
Обратите внимание, что мы получаем IP-адрес два раза. Первый раз при выходе в интернет, а второй раз — когда закрываем WiFi-соединение. Во втором случае IP-адрес будет равен 0.0.0.0
В мониторе порта выводится следующая информация (часть данных я убрал в целях безопасности).
Network name: Keenetic-7247 Signal strength: -79 MAC address: *:*:*:*:*:0A Encryption type: WPA2_PSK ----------------------- Network name: how2make 2.3 Signal strength: -91 MAC address: *:*:*:*:*:90 Encryption type: WPA_WPA2_PSK ----------------------- Network name: TP-Link_4A15 Signal strength: -91 MAC address: *:*:*:*:*:84 Encryption type: WPA_WPA2_PSK ----------------------- Соединяемся с Wi-Fi.. Соединяемся с Wi-Fi.. Соединение с Wi-Fi установлено *:*:*:*:*:20 192.163.2.21 0.0.0.0
Точка доступа
Плата ESP32 может работать как точка доступа. Для первого знакомства получим базовую информацию о точке доступа через доступные функции. Мы можем установить собственные значения для SSID и пароля (пароль можно даже не указывать, чтобы сеть была открытой).
#include "WiFi.h" const char* ssid = "ESP32Cat"; const char* password = "meow"; void setup() < Serial.begin(115200); // WiFi.softAP(ssid, password); WiFi.softAP(ssid); // без пароля Serial.println(); Serial.print("IP address: "); Serial.println(WiFi.softAPIP()); >void loop() <>
После загрузки скетча мы получим IP-адрес платы. В настройках компьютера или смартфона должна появиться созданная точка доступа.
Кстати, когда пробовал вариант с паролем, то точка доступа не создалась почему-то. Upd: читатель сайта прислал комментарий по этому поводу: Дело в том, что любая точка доступа в пароле должна иметь минимум 8 символов, если я правильно помню, а в примере всего 4, поэтому скетч ведёт себя некорректно. В этом вся проблема, указываете от 8 символов — код работает стабильно.
Отслеживаем момент подключения и отключения устройства к точке доступа
За соответствующие события отвечают SYSTEM_EVENT_AP_STACONNECTED и SYSTEM_EVENT_AP_STADISCONNECTED.
После загрузки скетчка в настройках телефона найдите созданную точку доступа и присоединитесь к ней. Момент подключения будет обнаружен и в мониторе порта появится сообщение о соединении.
#include "WiFi.h" void WiFiStationConnected(WiFiEvent_t event, WiFiEventInfo_t info) < Serial.println("Соединение установлено"); // что-то делаем, например, вычисляем mac-адрес for (int i = 0; i < 6; i++) < Serial.printf("%02X", info.sta_connected.mac[i]); if (i < 5)Serial.print(":"); >Serial.println("\n------------"); > void WiFiStationDisconnected(WiFiEvent_t event, WiFiEventInfo_t info) < Serial.println("Соединение разорвано"); // что-то делаем, например, снова вычисляем mac-адрес for (int i = 0; i < 6; i++) < Serial.printf("%02X", info.sta_disconnected.mac[i]); if (i < 5)Serial.print(":"); >Serial.println("\n------------"); > void setup() < Serial.begin(115200); WiFi.softAP("ESP32Cat"); WiFi.onEvent(WiFiStationConnected, SYSTEM_EVENT_AP_STACONNECTED); WiFi.onEvent(WiFiStationDisconnected, SYSTEM_EVENT_AP_STADISCONNECTED); >void loop() <>
Mac-адрес для точки доступа
В первом примере с получением настроек модуля мы вычисляли Mac-адрес через функцию WiFi.macAddress. Существует также функция WiFi.softAPmacAddress(), когда плата работает в режиме точки доступа.
#include "WiFi.h" void setup() < Serial.begin(115200); WiFi.mode(WIFI_MODE_AP); Serial.println(WiFi.softAPmacAddress()); >void loop() <>
Включаем поддержку IPv6
Мы можем включить поддержку IPv6 и получить адрес в этом формате. Включение поддержки IPv6 происходит при помощи функции softAPenableIpV6(). Вызовем функцию при событии SYSTEM_EVENT_AP_START, когда активируется точка доступа.
После включения поддержки в событии SYSTEM_EVENT_AP_STA_GOT_IP6 (получение адреса) узнаём IPv6-адрес.
#include "WiFi.h" void WiFiApStarted(WiFiEvent_t event, WiFiEventInfo_t info) < WiFi.softAPenableIpV6(); >void WiFiGotIp(WiFiEvent_t event, WiFiEventInfo_t info) < Serial.println(WiFi.softAPIPv6()); >void setup() < Serial.begin(115200); WiFi.onEvent(WiFiApStarted, SYSTEM_EVENT_AP_START); WiFi.onEvent(WiFiGotIp, SYSTEM_EVENT_AP_STA_GOT_IP6); WiFi.softAP("ESP32Cat"); >void loop() <>
Сколько устройств подключено к точке доступа
Узнать число устройств, которые в данный момент подключены к точке доступа, можно через функцию softAPgetStationNum(). После запуска скетча подключите телефон и другие устройства к точке доступа, чтобы увидеть изменения.
#include "WiFi.h" void setup() < Serial.begin(115200); WiFi.softAP("ESP32Cat"); >void loop()
Piranha ESP32 как точка доступа WiFi
В этом проекте мы настроим Piranha ESP32 на работу в качестве точки доступа WiFi и будем управлять встроенным светодиодом через веб-сайт, размещённый на веб-сервере внутри ESP32. При подключении к серверу (через браузер с телефона или ПК), который запущен на Piranha ESP32, в браузере будет отображена страница с ссылками для управления встроенным в плату светодиодом.
Помимо библиотек WiFi и WiFiClient нам понадобиться библиотека WiFiAP для создания точки доступа.
Для управления встроенным в плату светодиодом необходимо подключиться с телефона, планшета или любого другого устройства с технологией WiFi и браузером к точке доступа esp32asAP с паролем password12345 , затем в адресной строке браузера ввести адрес точки доступа (по умолчанию 192.168.4.1 ).
Видео:
Нам понадобится:
Подключение:
Скетч проекта:
// Подключаем библиотеки #include #include #include // Определяем название и пароль точки доступа const char *ssid = "esp32asAP"; const char *password = "password12345"; // Создаём объект Веб-сервера WiFiServer server(80); void setup() < // Устанавливаем режим работы вывода светодиода pinMode(LED_BUILTIN, OUTPUT); Serial.begin(115200); Serial.println(); Serial.println("Инициируем точку доступа WiFi"); // Инициируем точку доступа WiFi WiFi.softAP(ssid, password); IPAddress myIP = WiFi.softAPIP(); // Выводим IP-адрес Веб-сервера Serial.print("IP-адрес точки доступа: "); Serial.println(myIP); // Инициируем сервер server.begin(); Serial.println("Сервер запущен."); >// Функция ответа клиенту inline bool respToClient(WiFiClient& client, String& currentLine) < // Читаем байт и выводим его в последовательный порт char c = client.read(); Serial.write(c); // Если байт - символ новой строки if (c == '\n') < // Если текущая строка пуста, значит был получен // символ новой строки два раза подряд // Это означает конец клиентского HTTP-запроса. if (currentLine.length() == 0) < // Посылаем HTTP заголовок client.println("HTTP/1.1 200 OK"); client.println("Content-type:text/html"); client.println(); // Посылаем текст страницы client.print(""); client.print( "Нажмите " "сюда " "для включения светодиода." ); client.print( "
Нажмите " "сюда " "для выключения светодиода." ); client.print(""); // посылаем пустую строку client.println(); // необходимые данные клиенту переданы - // выходим из функции с флагом true return true; > // иначе (строка не пуста) else < // стираем текущую строку currentLine = ""; >> // иначе (байт не символ новой строки), // если байт - не символ возврата каретки else if (c != '\r') < // добавляем его в текущую строку currentLine += c; >// Проверяем какой запрос сделал клиент. // Если GET /H if (currentLine.endsWith("GET /H")) < // Включаем светодиод digitalWrite(LED_BUILTIN, HIGH); >// Если GET /L if (currentLine.endsWith("GET /L")) < // Выключаем светодиод digitalWrite(LED_BUILTIN, LOW); >return false; > // Функция обработки клиента inline void handleClient(WiFiClient& client) < // выводим сообщение в последовательный порт Serial.println("Новый клиент."); //Создаём строковый объект для хранения входных данных String currentLine = ""; // Входим в цикл пока клиент подсоединён while (client.connected()) < // Если есть данные для чтения if (client.available()) < // Вызываем функцию ответа клиенту bool resp = respToClient(client, currentLine); // Если функция передала все данные клиенту if (resp == true) // прерываем цикл break; >> // Закрываем соединение client.stop(); Serial.println("Клиент отключён."); > void loop() < // Создаём объект клиента и проверяем, есть ли подключённые клиенты WiFiClient client = server.available(); // Если клиенты есть if (client) < // Вызываем функцию обработки клиента handleClient(client); >>
Ссылки
Как настроить точку доступа на ESP32 для веб-сервера
В сетях Wi-Fi микроконтроллер ESP32 может работать и как станция, и как точка доступа, и в обоих режимах одновременно. В этом руководстве мы покажем, как настроить ESP32 в качестве точки доступа с использованием среды программирования Arduino IDE.
В большинстве проектов мы подключали микроконтроллер ESP32 к беспроводному маршрутизатору. При этом появляется доступ к ESP32 через локальную сеть. Тогда маршрутизатор служил точкой доступа, а ESP32 был настроен как станция. А для управления микроконтроллером ESP32 необходимо было подключиться к маршрутизатору (локальной сети).
Но если вы настроите микроконтроллер ESP32 как точку доступа (как в местах общественного беспроводного доступа), вы сможете подключиться к ESP32 с помощью любого устройства с интерфейсом Wi-Fi без необходимости соединения с маршрутизатором.
Простыми словами, когда вы настраиваете ESP32 как точку доступа, вы создаёте свою собственную сеть Wi-Fi, а находящиеся поблизости устройства с интерфейсом Wi-Fi (станции) могут подсоединяться к микроконтроллеру (например, смартфон или компьютер).
Здесь мы покажем, как настроить ESP32 как точку доступа для своего проекта с веб-сервером. В этом случае вам не понадобится подключаться к маршрутизатору для управления микроконтроллером ESP32. Так как ESP32 не подключается далее к более широкой сети (в отличие от маршрутизатора), она называется мягкая точка доступа (soft Access Point).
Установка ESP32 в Arduino IDE
Для среды Arduino IDE существует дополнение, которое позволяет программировать микросхему ESP32 посредством этой среды и её языка программирования.
Код для создания точки доступа на ESP32
В этом примере мы модифицируем веб-сервер на микроконтроллере ESP32 из прошлого руководства, чтобы добавить возможность работы в качестве точки доступа. То, что мы здесь представим, должно отлично работать с любым примером, представляющим собой веб-сервер на ESP32.
Загрузите приведённый ниже код, чтобы настроить микроконтроллер ESP32 как точку доступа.