ESP32 Урок 22. Wi-Fi. Режим STA (Станция). Smart

 

 

 

В уроке 19 мы написали проект, который обеспечивает соединение с точкой доступа. То есть мы настроили наш модуль для работы по беспроводной сети в режиме станции. Только при условии исчезновения соединения с точкой доступа вследствие временного отключения последней или из-за каких-то других причин нам пришлось столкнуться с рядом трудностей, хотя с помощью неких костылей они всё же были преодолены, но это не совсем так, как хотелось бы. Поэтому на данном уроке мы постараемся немного усовершенствовать наш проект, так сказать, заставить нашу станцию быть немного умнее.

Схема остаётся такая же — отладочная плата, подключенная к USB компьютера

 

 

И проект мы также сделаем из проекта того же урока с именем WIFI_STA и назовём его WIFI_STA_SMART.

Откроем наш проект в Espressif IDE и в функции app_main файла main.c удалим бесконечный цикл совсем вместе с телом.

Вот эта переменная нам также не потребуется

 

wifi_ap_record_t info;

 

Создадим цикл событий по умолчанию

 

 

Перейдём в файл wifi.c и в объявлении функции инициализации wifi_init_sta добавим возвращаемый параметр

 

esp_err_t wifi_init_sta(void)

 

Поправим также и прототип в заголовочном файле.

В теле данной функции объявим переменную такого же типа

 

 

Дальнейший код в теле удалим совсем, так как изменений будет очень много и легче его заново написать.

Функцию event_handler удалим вместе с телом.

Вот эти глобальные вещи также удалим

 

static int s_retry_num = 0;
static EventGroupHandle_t s_wifi_event_group;
#define WIFI_CONNECTED_BIT BIT0
#define WIFI_FAIL_BIT BIT1

 

Сегодня мы будем работать с семафором, а не с событиями.

Объявим глобальный семафор, назначение которого мы узнаем позже

 

 

В функции wifi_init_sta проверим существование нашего семафора

 

 

А если мы не выйдем из-за какой-нибудь ошибки, то вернём успешный статус

 

 

Выше добавим функцию, которая будет запускать нашу сеть

 

 

Вызовем её в функции wifi_init_sta

 

 

Объявим глобальную переменную, которая будет считать количество сетевых интерфейсов

 

 

Выше добавим функцию, останавливающую соединение, в которой пока только уменьшим на 1 количество сетевых интерфейсов

 

 

В функции wifi_init_sta зарегистрируем данную функцию в качестве обработчика событий

 

 

Выше функции net_start добавим функцию в форме указателя, которая будет запускать беспроводной модуль

 

 

Объявим и проинициализируем переменную типа структуры управления настройками WiFi, такими так буфер RX/TX, структура WiFi NVS и т. д, после чего инициализируем WiFi данными настройками

 

 

Объявим глобальный указатель на контейнер с информацией об интерфейсе

 

 

В функции net_start вызовем функцию wifi_start присвоив указатель на контейнер нашему указателю

 

 

В функции wifi_start объявим указатель на символьный массив для хранения текстового описания сетевого интерфейса

 

 

Объявим переменную типа структуры для хранения свойств интерфейса и проинициализируем её параметрами по умолчанию с помощью специального макроса, а затем текстовое описание дескриптора дополним именем нашего модуля, взятого из массива TAG и присвоим полю обратно

 

 

Назначим интерфейсу приоритет

 

 

Инициализируем интерфейс WiFi

 

 

Освободим память, зарезервированную под символьный массив

 

 

Установим обработчики по умолчанию

 

 

У нас будет отдельный обработчик для завершения соединения.

Поэтому выше добавим функцию для данного обработчика, а также функцию для обработчика событий получения адреса

 

 

Вернемся в функцию wifi_start и зарегистрируем наши обработчики

 

 

В качестве хранилища установим память

 

 

В файле Kconfig.projbuild внизу добавим пункт для выбора способа сканирования сети

 

 

Также добавим пункты для выбора методов сортировки имён точек доступа, установки порога мощности, режима порога и выбора метода шифрования

 

 

В конфигураторе выберем тип шифрования

 

 

Пункт ESP_MAXIMUM_RETRY можно удалить.

Сохраним конфигурацию и пересоберём проект.

 

 

Теперь в файле wifi.c добавим макросы, которые будут зависеть от настроек в конфигураторе

 

 

В функции wifi_start объявим и проинициализируем переменную типа структуры для свойств станции

 

 

Отобразим попытку подключения в терминале, взяв имя точки доступа из поля структуры

 

 

Установим режим станции, нормальный режим работы WiFI без энергосбережения и применим конфигурационные установки для нашей станции

 

 

Запустим станцию, попытаемся соединиться с точкой доступа и возвратим интерфейс

 

 

В функции-обработчике on_got_ip получим указатель на структуру события

 

 

Выше добавим функцию, которая будет узнавать тип интерфейса

 

 

Вернемся в функцию on_got_ip и отобразим в терминале имя интерфейса, и, если это интерфейс типа IPV4, то отобразим и адрес

 

 

Объявим глобальный указатель на сетевой адрес

 

 

Вернемся в функцию on_got_ip, скопируем информацию в нашу переменную из поля структуры, зажжем светодиод и отдадим семафор

 

 

В функции-обработчике on_wifi_disconnect погасим светодиод и выведем о попытке разрыва соединения соответствующее сообщение в терминал

 

 

Попытаемся заново соединиться с точкой доступа, если невозможно, то выйдем из функции, в другом случае отобразим код ошибки, вдруг у нас какая-то другая ошибка

 

 

В функции net_start увеличим количество интерфейсов на 1

 

 

И здесь же мы создаём счётный семафор с количеством элементов, равным количеству интерфейсов

 

 

Теперь займёмся остановкой интерфейса, для чего выше добавим ещё одну функцию

 

 

Также ещё выше добавим функцию, которая будет вычислять интерфейс по имени

 

 

Здесь всё просто и объяснений, я думаю, никаких не требуется.

Вернёмся в функцию wifi_stop и получим наш интерфейс

 

 

Разрегистрируем обработчики событий

 

 

Попытаемся остановить WiFi

 

 

Деинициализируем WiFi

 

 

Очистим обработчики по умолчанию и уничтожим соответствующие объекты

 

 

Уничтожим объект esp_netif

 

 

Очистим ссылку на интерфейс

 

 

Перейдём в функцию net_stop и вызовем только что написанную нами функцию

 

 

Осталось нам только завершить кое-какие процедуры в функции инициализации wifi_init_sta. Сначала попытаемся забрать наши семафоры

 

 

В данном цикле мы будем находиться до тех пор, пока не заберём все семафоры, то есть пока все наши интерфейсы не соединятся.

Зажжем светодиод и объявим указатель на интерфейс

 

 

Объявим переменную типа структуры для сетевого адреса нашей станции

 

 

Добавим цикл с количеством итераций, равных количеству интерфейсов, в котором получим дескриптор очередного интерфейса

 

 

Отобразим в терминале информацию о соединении

 

 

В функции app_main файла main.c добавим возврат параметра в вызов функции инициализации wifi

 

ret = wifi_init_sta();

 

Ниже выведем в терминал код ошибки

 

 

Также произведём инициализацию сетевого интерфейса немного выше

 

 

Ну и наконец-то пришло время нам всё это проверить.

Прошьём контроллер и посмотрим информацию в терминале

 

 

Отлично! Вроде везде нолики, значит ошибок возвращённых нет.

Проверим пинг

 

 

Теперь попробуем отключить точку доступа на какое-то время.

Попытки соединиться с точкой доступа теперь происходят постоянно

 

 

Включим точку доступа и увидим, что соединение снова удачно установилось

 

 

Итак, на данном уроке нам удалось усовершенствовать нашу WiFi-станцию, в результате чего мы добились того, что нам уже не нужно в бесконечном цикле постоянно вызывать функцию инициализации, если превышено количество попыток соединения.

Всем спасибо за внимание!

 

Данная статья в Дзен.

 

Предыдущий урок Программирование МК ESP32 Следующий урок

 

Исходный код

 

 

Недорогие отладочные платы ESP32 можно купить здесь:
На AliExpress Недорогие отладочные платы ESP32
На Яндекс.Маркет Недорогие отладочные платы ESP32

 

 

Смотреть ВИДЕОУРОК в YouTube (нажмите на картинку)

ESP32 Wi-Fi. Режим STA (Станция). Smart

 

Смотреть ВИДЕОУРОК в Дзен (нажмите на картинку)

ESP32 Wi-Fi. Режим STA (Станция). Smart

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*