Esp32 переподключение к wifi

Вопрос Переподключение к wifi

Этот код у меня работает, правда всего пару дней. Пока траблов не заметил. Ранее постоянно «терялись» ЕСП.
Интересна оптимизация кода.
Стоит ли заново инициализировать соединение с указанием ip, удалять информацию о сетях?
Этот код не лишний?

// Удаляем предыдущие конфигурации WIFI сети WiFi.disconnect(); // обрываем WIFI соединения WiFi.softAPdisconnect(); // отключаем отчку доступа(если она была WiFi.mode(WIFI_OFF); // отключаем WIFI delay(500); // присваиваем статичесий IP адрес WiFi.mode(WIFI_STA); // режим клиента WiFi.config(IPAddress(192, 168, 1, 73), IPAddress(192, 168, 1, 1), IPAddress(255, 255, 255, 0), IPAddress(192, 168, 1, 1));

enjoynering

Well-known member

зачем изобретать велосипед. все уже есть в arduino core

if (WiFi.getAutoConnect() != true) WiFi.setAutoConnect(true); //on power-on automatically connects to last used hwAP WiFi.setAutoReconnect(true); //automatically reconnects to hwAP in case it is disconnected

enjoynering

Well-known member
WiFi.softAPdisconnect(); // отключаем отчку доступа(если она была WiFi.mode(WIFI_OFF); // отключаем WIFI

WiFi.softAPdisconnect(false) — не выключает передатчик, тупо обрывает связь c клиентами путем установления пароля и юзера в NULL. а вот WiFi.softAPdisconnect(true) вызывает WiFi.enableAP(false) которая красиво вызывает WiFi.mode() и отключает AP на совсем.

WiFi.softAPdisconnect(false) достаточно для безглючной смены паролей, ip и тд. То есть не надо дополнительно выключать передатчик командой WiFi.mode(WIFI_OFF).

Уж если хотите временно выключить wifi то делайте так:

if (WiFi.getPersistent() == true) WiFi.persistent(false); //disable saving wifi config into SDK flash area WiFi.mode(WIFI_OFF); // отключаем WIFI WiFi.persistent(true); //enable saving wifi config into SDK flash area
if (WiFi.getPersistent() == true) WiFi.persistent(false); //disable saving wifi config into SDK flash area WiFi.softAPdisconnect(false); //setting ssid/pass to null WiFi.persistent(true); //enable saving wifi config into SDK flash area

YDen

Member

зачем изобретать велосипед. все уже есть в arduino core

if (WiFi.getAutoConnect() != true) WiFi.setAutoConnect(true); //on power-on automatically connects to last used hwAP WiFi.setAutoReconnect(true); //automatically reconnects to hwAP in case it is disconnected

enjoynering

Well-known member

вас в гугле забанили? один из первых запросов поиске выдал это

* @brief Set whether the ESP8266 station will connect to the recorded AP
* automatically when the power is on. It will do so by default.
*
* @attention 1. If this API is called in user_init, it is effective immediately
* after the power is on. If it is called in other places, it will
* be effective the next time when the power is on.
* @attention 2. This configuration will be saved in Flash system parameter area if changed.

*
* @param bool set : If it will automatically connect to the AP when the power is on
* — true : it will connect automatically
* — false: it will not connect automatically

ну и так как происходит постоянная запись этих параметров во flash при их вызове, то лучше вызывать так

if (WiFi.getAutoConnect() != true) //configuration will be saved into SDK flash area < WiFi.setAutoConnect(true); //on power-on automatically connects to last used hwAP WiFi.setAutoReconnect(true); //automatically reconnects to hwAP in case it's disconnected >

enjoynering

Well-known member

ну и еще не надо вызывать WiFi.mode(WIFI_STA) перед WiFi.begin(ssid, password).

Читайте также:  Yota wi fi ноутбук

WiFi.begin(ssid, password) в своем теле вызывает WiFi.enableSTA(true) которая красиво вызывает WiFi.mode(WIFI_STA).

тоже самое с точкой доступа — не надо вызывать WiFi.WiFi.enableAP(true) перед WiFi.softAP(ssid, password).

в WiFi.softAP(ssid, password) все уже есть.

YDen

Member

вас в гугле забанили? один из первых запросов поиске выдал это

ну и так как происходит постоянная запись этих параметров во flash при их вызове, то лучше вызывать так

if (WiFi.getAutoConnect() != true) //configuration will be saved into SDK flash area < WiFi.setAutoConnect(true); //on power-on automatically connects to last used hwAP WiFi.setAutoReconnect(true); //automatically reconnects to hwAP in case it's disconnected >

pvvx

Активный участник сообщества

ну и так как происходит постоянная запись этих параметров во flash при их вызове, то лучше вызывать так

Интересно, а почему происходит постоянная запись параметров, когда это дополнительное действие и любой стандартный пример Arduino начинается с установок режимов WiFi?
Т.е. функции по настройке WiFi у ESP8266 не соответствует базовым стандартам Arduino?
Каков смысл этой встроенной функциональности по сохранению настроек, если она нигде не используется и её надо отлючать?
В чем красота когда существуют параметры по умолчанию, которых вы не знаете, т.к. они берутся из ранее сохраненных от какой-то сессии работы с WiFi?
Всё это похоже введено для усложнения, а не красоты.
Причина разнообразия примеров по настройке WiFi строиться из описанного выше и последующих исправлений в SDK Espressif, с попыткой оставить совместимость с более старыми вариантами кода. Т.е. теперь, в текущей версии, требуются дополнительные костыли для привода кода к базовому варианту функционирования в среде Arduino. В следующей версии это может быть заменено и удалено.
Викопедия и Гугл этого не описывает и посылка туда не даст правильных ответов.

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

enjoynering

Well-known member

вы скорее всего правы. весь этот зоопарк из вызова одной функциии через другую с дублированием самих себя очень похоже на костыль-совместимости с предудущими версиями arduino esp8266 core. Надо отдать должное, они вняли вашей критике и теперь перед сохранием пароля и ssid проверяют его с сохраненным на флешке и не перезаписывают зря. ну и для самых продвинутых внедрили запрет на запись путем вызова функции WiFi.persistent(false). вот пример WiFi.begin(ssid, password) для запуска клиента:

wl_status_t ESP8266WiFiSTAClass::begin(const char* ssid, const char *passphrase, int32_t channel, const uint8_t* bssid, bool connect) < if(!WiFi.enableSTA(true)) < // enable STA failed return WL_CONNECT_FAILED; >if(!ssid || *ssid == 0x00 || strlen(ssid) > 31) < // fail SSID too long or missing! return WL_CONNECT_FAILED; >if(passphrase && strlen(passphrase) > 64) < // fail passphrase too long! return WL_CONNECT_FAILED; >struct station_config conf; strcpy(reinterpret_cast(conf.ssid), ssid); if(passphrase) < if (strlen(passphrase) == 64) // it's not a passphrase, is the PSK, which is copied into conf.password without null term memcpy(reinterpret_cast(conf.password), passphrase, 64); else strcpy(reinterpret_cast(conf.password), passphrase); > else < *conf.password = 0; >if(bssid) < conf.bssid_set = 1; memcpy((void *) &conf.bssid[0], (void *) bssid, 6); >else < conf.bssid_set = 0; >struct station_config current_conf; wifi_station_get_config(¤t_conf); if(sta_config_equal(current_conf, conf)) < DEBUGV("sta config unchanged"); >else < ETS_UART_INTR_DISABLE(); if(WiFi._persistent) < // workaround for #1997: make sure the value of ap_number is updated and written to flash // to be removed after SDK update wifi_station_ap_number_set(2); wifi_station_ap_number_set(1); wifi_station_set_config(&conf); >else < wifi_station_set_config_current(&conf); >ETS_UART_INTR_ENABLE(); > ETS_UART_INTR_DISABLE(); if(connect) < wifi_station_connect(); >ETS_UART_INTR_ENABLE(); if(channel > 0 && channel if(!_useStaticIp) < wifi_station_dhcpc_start(); >return status(); >

pvvx

Активный участник сообщества

вы скорее всего правы. весь этот зоопарк из вызова одной функциии через другую с дублированием самих себя очень похоже на костыль-совместимости с предудущими версиями arduino esp8266 core.

Читайте также:  Антенна вай фай магнитолы

Причину зоопарка я не разглашал
Она повязана на начальной реализации deep_sleep — чтобы ускорить подключение после просыпания.
В SDK ещё много чего зависит от начальных принятых алгоритмов, написанных кое-как и без обдумывания. Теперь исправляют, что для совместимости требует дополнительных ресурсов (страдает размер кода и скорость исполнения).
Отдельные дублирующие функции установок WiFi без записи в SDK появились вроде с 1.2 версии. До «Arduino» это дошло только в последних редакциях.
С версиями SDK, включая 2.0, с которыми пытался что-то слепить так не нашлось вариантов для установки всех необходимых параметров к WiFi не использующих функцию сохранения параметров во Flash, на что уходит много время — стирание сектора + запись его с невозможностью в это время работы кода из Flash.
SDK для ESP8266 составлено безграмотно, что накладывает многие ограничения. В ESP-32, уже год исправляют эту ситуацию в ESP-IDF.
Основа всего этого – закрытый код SDK без отделения драйвера WiFi. Только на него пока не принято давать исходники в общий доступ, и то это действие вызвано “другие не дают, и мы не будем” и никакими более вариантами.

enjoynering

Well-known member

теперь понятно, спасибо. для мня очень странно почему при вызове функции WiFi.mode() они не делают проверку конфига на флешке? тут спасение только в вызове WiFi.persistent(false) иначе после каждого изменения будет перезаписываться конфиг и лет через 5 флешке настанет каюк. спасибо хоть проверку на совпадение с текущим знвчением сделали.

bool ESP8266WiFiGenericClass::mode(WiFiMode_t m) < if(wifi_get_opmode() == (uint8) m) < return true; >bool ret = false; ETS_UART_INTR_DISABLE(); if(_persistent) < ret = wifi_set_opmode(m); >else < ret = wifi_set_opmode_current(m); >ETS_UART_INTR_ENABLE(); return ret; >

pvvx

Активный участник сообщества

теперь понятно, спасибо. для мня очень странно почему при вызове функции WiFi.mode() они не делают проверку конфига на флешке? тут спасение только в вызове WiFi.persistent(false) иначе после каждого изменения будет перезаписываться конфиг и лет через 5 флешке настанет каюк. спасибо хоть проверку на совпадение с текущим знвчением сделали.

bool ESP8266WiFiGenericClass::mode(WiFiMode_t m) < if(wifi_get_opmode() == (uint8) m) < return true; >bool ret = false; ETS_UART_INTR_DISABLE(); if(_persistent) < ret = wifi_set_opmode(m); >else < ret = wifi_set_opmode_current(m); >ETS_UART_INTR_ENABLE(); return ret; >

wifi_get_opmode() — это функция, вызывающая другую функцию (назовем _get_opmode) с параметром _get_opmode(1)
wifi_get_opmode_default() — это функция, вызывающая другую функцию с параметром _get_opmode(0)
_get_opmode() в зависимости от параметра:
0) выделяет в heap 1172 байта (размер блока параметров WiFi для SDK2.0), и вызывает считывание в полученный блок памяти (system_param_load()) области сохранения во Flash, считывает из полученного блока один байт, освобождает блок в heap.
1) обращается к структуре wifi_store, считывает и выдает из неё байт номера режима.

Читайте также:  Подключение регистратора через wifi

Драйвер WiFi, обычно, может может работать в разных режимах. Т.к. у нас два основных типа — AP и STA, то драйвер WiFi делиться на два типа работы. Т.е. фактически при AP+STA загружены и включены два драйвера. Проверить какой драйвер и в каком режиме сейчас активен по данным из flash не выйдет, если установка его произошла без сохранения параметров во flash.

wifi_set_opmode(x) — это тоже функция, с вызывающая другую _set_opmode(x, 1)
wifi_set_opmode_current(x) — это тоже функция, с вызывающая другую _set_opmode(x, 0)

_set_opmode(x, flag) примерно то-же самое — в зависимости от flag вызывает считывание из flash (system_param_load(. ), system_param_save_with_protect(. ) ) структуры wifi_store[1172] с запросом размещения в heap pvPortMalloc(1172, id функции для отладки).
Миллион ненужных действий и диких китайских алгоритмов. Описывать даже не охота.

Что примечательного в этом всём:
system_param_save_with_protect() вызывает wifi_param_save_protect_with_check() в которой
pvPortZalloc(), (#) spi_flash_erase_sector(), spi_flash_write(), spi_flash_read(), ets_memcmp() и если не равно — возврат к началу стирания и записи (#) без какого либо счета неудач, в конце — vPortFree().

Если у вас упало или плавает питание, то процесс стирания и записи происходит до победного конца — дыры в Flash.
Первые варианты SDK у Espressif писал какой-то школьник, не проходивший программ обучения программированию (наверно денег у Espressif не было нанять проф.программиста). К версии SDK2.0 осталось 40% его алгоритмов. Остальные, более ужасные, были исправлены. Но множество «фич» так и осталось. К примеру SDK собирается только с выключенными всеми wraning у компилятора. Иначе образуется большой список ошибок по поводу не проинициализированных переменных, неверных вызовов пр параметрам функций и т.д. По этому от версии к версии разные баги в SDK и потом выдают новые патчи (назвав это оптимаза ). Так-же был прикол — на вопрос что была за ошибка и почему патч, программист ответил — пересобрал заново либы и оно исправилось.
На таком материале и сделана Arduino на ESP8266 другими, в основном энтузиастами. Ну и никогда не получите исходников SDK — это будет шоу.
По этому когда указываете какой код — надо приводить номер версии SDK и патчей.

Источник

Оцените статью
Adblock
detector