• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Определение факта пропадания соединения с роутером и переключение в режим АР

ikari81

New member
Я читал, что вроде есть режим одновременной работы station+AP, но обяснений и примера не нашел.
Поэтому написал свой велосипед из костылей:
#include <ESP8266WiFi.h>
void setup() {
Serial.begin(9600);
int count = 0;
Serial.print("\n");
WiFi.mode(WIFI_STA);
WiFi.begin("111", "2222");
while (WiFi.status() != WL_CONNECTED && count++ < 20) {
delay(500);
Serial.print(".");
}
Serial.print("\n");
if (WiFi.status() == WL_CONNECTED) {
Serial.println(WiFi.localIP());
Serial.println("Connected to router!");
}
}
uint32_t WiFiDisappiarTime = 0;
bool APEnabled = false;

void loop() {
if (WiFi.status() != WL_CONNECTED && !APEnabled) {
Serial.println("No wifi connection! Starting SoftAP!");
IPAddress Ip(192, 168, 1, 1);
IPAddress NMask(255, 255, 255, 0);
WiFi.softAPConfig(Ip, Ip, NMask);
String AP = "AP_" + String(system_get_chip_id());
WiFi.softAP(AP, "222");
IPAddress myIP = WiFi.softAPIP();
WiFiDisappiarTime = millis();
APEnabled = true;
Serial.print("\nAP enabled, IP: ");
Serial.println(myIP);
}
delay(1000);
if (APEnabled && millis() - WiFiDisappiarTime > 60 * 1000) {
int count = 0;
WiFi.mode(WIFI_STA);
WiFi.begin("111", "2222");
Serial.print("\n");
while (WiFi.status() != WL_CONNECTED && count++ < 20) {
delay(500);
Serial.print(".");
}
Serial.print("\n");
if (WiFi.status() == WL_CONNECTED) {
Serial.println(WiFi.localIP());
Serial.println("Connected to router!");
APEnabled = false;
WiFiDisappiarTime = 0;
}
}
}

Может быть есть более изящное решение?
 

tretyakov_sa

Moderator
Команда форума
Зачем переключаться в режим AP если роутер пропал? В каком случае это нужно?
Я сделал так:
Включаем устройство и ищем сеть к которой нужно подключиться.
Если сети нет сразу в точку доступа.
Через определенное время проверяем наличие роутера к которому нужно подключиться.
Если сеть найдена подключаемся к роутеру.
Если роутер пропал не переходим в точку доступа, а просто пытаемся вернуть соединение с роутером.
 

ikari81

New member
Ну например sonoff глубоко в подрозетнике, роутер сдох, дальше объяснять?
Если внимательно посмотреть первое сообщение, то там все написанное есть. Я же спрашивал об аппаратном решении.
 

tretyakov_sa

Moderator
Команда форума
Ну например sonoff глубоко в подрозетнике, роутер сдох, дальше объяснять?
Если внимательно посмотреть первое сообщение, то там все написанное есть. Я же спрашивал об аппаратном решении.
Что значит об аппаратном решении.
Вот сдох у вас роутер и что должен делать ваш sonoff? А если их много, что делать?
Каждый sonoff свою точку будет делать? Если сдох роутер, то почему его не наладить?
На крайний случай на телефоне поднимите точку доступа с именем сети и паролем от вашего сдохшего роутера.
В крайнем случае быстренько роутер на ESP создайте за 5 минут.
Ну или опишите точный алгоритм, как должны вести себя устройства всегда wifi точки создавать или временно? Если временно, то какой критерий для включения точки доступа?
 

ikari81

New member
Сдох роутер, соноф включает точку доступа чтобы предоставить доступ к его веб-морде и включить-выключить.
Временно, как только роутер оживает, то подключаются к роутеру.
Аппаратное решение, режим одновременного station + Ap. Только примеров, кроме константы режима я не нашел.
 

tretyakov_sa

Moderator
Команда форума
Сдох роутер, соноф включает точку доступа чтобы предоставить доступ к его веб-морде и включить-выключить.
Временно, как только роутер оживает, то подключаются к роутеру.
Аппаратное решение, режим одновременного station + Ap. Только примеров, кроме константы режима я не нашел.
Я же спрашиваю, режим station + Ap всегда у вас будет или вы хотите переключаться в него только тогда, когда пропал роутер?
 

tretyakov_sa

Moderator
Команда форума
Я спрашивал, может ли есп так аппаратно, без велосипедов.
ESP может работать в четырех режимах:
1. Станция
2. Точка доступа
3. Станция и Точка доступа одновременно
4. Как микроконтроллер без WIFI.
Если вы включите режим станции, а после пропадания роуера переключитесь в смешанный режим, что совершенно не нужно так как роутера уже нет. А когда роутер появится, вы опять будите переключаться в режим станции. Это и есть огород.
Если вы сразу включите режим Станция и Точка доступа и не будите его переключать, тогда у вас будет все время в сети будет висеть новая сеть. Такой режим нужен только в весьма специфических случаях.
Самый подходящий вариант я вам описал ранние:
Пропал роутер перешли в точку доступа. Появился роутер подключились к нему!
 

EvgeniyS

Member
Набросал код для примера (у меня работает), руководствовался этим
C++:
#include <ESP8266WiFi.h>

bool isConnected = false;
uint32_t timePoint = 0;
const uint16_t interval = 3000; // (ms.) интервал проверки соединения
const char ssidSTA[] = ""; // your ssid
const char passSTA[] = ""; // your password
const char ssidAP[] = "ESP_AP";
const char passAP[] = "";
IPAddress apIP(192, 168, 1, 1);

void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_AP_STA);
WiFi.setAutoReconnect(true);
WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0));
WiFi.softAP(ssidAP, passAP);
WiFi.begin(ssidSTA,passSTA);
if(WiFi.waitForConnectResult() == WL_CONNECTED){
  IPAddress staIp = WiFi.localIP();
  WiFi.softAPdisconnect();
  isConnected = true;
  Serial.printf("\nDevice connected to router, ip: %u.%u.%u.%u\n",staIp[0],staIp[1],staIp[2],staIp[3]);
}else{
  Serial.printf("\nCan`t connect to router, enable AP, ssid: %s, ip: %u.%u.%u.%u\n",ssidAP,apIP[0],apIP[1],apIP[2],apIP[3]);
}}

void loop() {
  if(millis()>timePoint+interval){
    timePoint = millis();
    if(WiFi.isConnected() != isConnected){
      if(WiFi.isConnected()){
        WiFi.softAPdisconnect();
        isConnected = true;
        IPAddress staIp = WiFi.localIP();
        Serial.printf("connection restored, ip: %u.%u.%u.%u\n",staIp[0],staIp[1],staIp[2],staIp[3]);
      }else{
        WiFi.softAP(ssidAP, passAP);
        WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0));
        isConnected = false;
        Serial.printf("Connection lost, enable AP, ssid: %s, ip: %u.%u.%u.%u\n",ssidAP,apIP[0],apIP[1],apIP[2],apIP[3]);
      }
    }
  }
  delay(1);
}
 

EvgeniyS

Member
И все же я согласен с tretyakov_sa, лучше отслеживать соединение и переключать в нужный режим. Можно в режиме AP с каким-то интервалом сканировать сети, и если нужная сеть найдена (роутера), переключиться в STA и подключаться. Для сканирования сетей см. scanNetworkAsync
 

EvgeniyS

Member
Если вы сразу включите режим Станция и Точка доступа и не будите его переключать, тогда у вас будет все время в сети будет висеть новая сеть. Такой режим нужен только в весьма специфических случаях.
Если после подключения к роутеру в коде вставить:
WiFi.softAPdisconnect();
то будет висеть скрытая пустая сеть без названия
 

tretyakov_sa

Moderator
Команда форума
Если после подключения к роутеру в коде вставить:
WiFi.softAPdisconnect();
то будет висеть скрытая пустая сеть без названия
В вашем случае нет в этом режиме смысла. Я вам на библиотеку ссылку давал.
Вот пример:

C++:
#include <wificonnect.h> // https://github.com/tretyakovsa/wificonnect
WIFICONNECT MyWiFi;
const String ssid       = "home";
const String ssidPass   = "i12345678";
const String ssidAP     = "WiFi-Start";
const String ssidApPass = "";

void setup() {
  Serial.begin(115200);
  Serial.println();
  MyWiFi.init(ssid, ssidPass, ssidAP, ssidApPass); // Основные данные для wifi
  MyWiFi.start();        // Запустим WiFi
  if (MyWiFi.modeSTA()) { // Если подключились
    Serial.println("Connect " + ssid);
    MyWiFi.onEvent(WiFiEvent); // Подключим обработчик событий WIFI
  } else  Serial.println("AP =" + ssidAP);

}

void loop() {
  MyWiFi.loop(); // DNS в режиме AP
}

void WiFiEvent(WiFiEvent_t event) {
  switch (event) {
    case WIFI_EVENT_STAMODE_DISCONNECTED: //Если роутер пропал
      Serial.println("WIFI_EVENT_STAMODE_DISCONNECTED");
      Serial.println("ESP restart");
      ESP.restart(); // Если хотите перезагрузить модуль
      break;
    case WIFI_EVENT_STAMODE_CONNECTED:
      Serial.println("WIFI_EVENT_STAMODE_CONNECTED");
      break;
  }
}
 
Последнее редактирование:

EvgeniyS

Member
В вашем случае нет в этом режиме смысла. Я вам на библиотеку ссылку давал.
Я знаю что нет смысла, человек поднявший тему хотел реализацию AP+STA, я набросал пример. Что касается библиотеки, спасибо, конечно, но я принципиально не использую класс String, а в вашей библиотеке он активно используется, к тому же для меня не проблема написать собственную реализацию кода по данной теме.
 

Melandr

Member
В вашем случае нет в этом режиме смысла. Я вам на библиотеку ссылку давал.
Добрый вечер!
Не могу понять, как работает
MyWiFi.onEvent(WiFiEvent); // Подключим обработчик событий WIFI
Метод onEvent(event) в классе WIFICONNECT я не нашел. И если не трудно, как добавить обработчик событий, который при отключении роутера создавал точку доступа SoftAP, и периодически чекал подъем роутера, и при появлении WiFi подключения роутера, подключался бы.
 

Ildarmustafin86

Active member
Отслеживает 10-11 событий WiFi.onEvent(WiFiEvent).

C++:
EVENT_STAMODE_CONNECTED,              0
EVENT_STAMODE_DISCONNECTED,           1
EVENT_STAMODE_AUTHMODE_CHANGE,        2
EVENT_STAMODE_GOT_IP,                 3
EVENT_STAMODE_DHCP_TIMEOUT,           4
EVENT_SOFTAPMODE_STACONNECTED,        5
EVENT_SOFTAPMODE_STADISCONNECTED,     6
EVENT_SOFTAPMODE_PROBEREQRECVED,      7
EVENT_OPMODE_CHANGED,                 8
EVENT_SOFTAPMODE_DISTRIBUTE_STA_IP,   9
EVENT_MAX,                            10
EVENT_ANY = EVENT_MAX,                11
Обработка происходит в
C++:
void WiFiEvent(WiFiEvent_t event) {
  Serial.printf("event: %i\n", event);
}
Считается рабочим вариантом, но устаревшим ссылка. На замену рекомендуют WiFiEventHandler.
C++:
WiFiEventHandler  onStationModeConnected (std::function< void(const WiFiEventStationModeConnected &)>)
WiFiEventHandler  onStationModeDisconnected (std::function< void(const WiFiEventStationModeDisconnected &)>)
WiFiEventHandler  onStationModeAuthModeChanged (std::function< void(const WiFiEventStationModeAuthModeChanged &)>)
WiFiEventHandler  onStationModeGotIP (std::function< void(const WiFiEventStationModeGotIP &)>)
WiFiEventHandler  onStationModeDHCPTimeout (std::function< void(void)>)
WiFiEventHandler  onSoftAPModeStationConnected (std::function< void(const WiFiEventSoftAPModeStationConnected &)>)
WiFiEventHandler  onSoftAPModeStationDisconnected (std::function< void(const WiFiEventSoftAPModeStationDisconnected &)>)
 
Сверху Снизу