• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

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

Ildarmustafin86

Active member
Раньше я делал так:
C++:
void WiFiEvent(WiFiEvent_t event) {
  wifi.working = event;
}

void wifi_connect(byte e) {
  switch (e) {
    case 0: // WIFI_EVENT_STAMODE_CONNECTED
      DEBUG_PRINT("WIFI_EVENT_STAMODE_CONNECTED\n");
      break;
    case 1: // WIFI_EVENT_STAMODE_DISCONNECTED
      WiFi.reconnect();
      if (--wifi.countDS) {
        DEBUG_PRINT("CONNECTING...TRY:%i\n", wifi.countDS);
      } else {
        wifi.working = 7;
        WiFi_initAP();
        wifi.countDS = recTime;
      }
      break;
    case 3: // WIFI_EVENT_STAMODE_GOT_IP
      DEBUG_PRINT("WIFI_EVENT_STAMODE_GOT_IP\n");
      break;
    case 5: // WIFI_EVENT_SOFTAPMODE_STACONNECTED
      DEBUG_PRINT("USER CONNECTED\n");
      break;
    case 6: // WIFI_EVENT_SOFTAPMODE_STADISCONNECTED
      DEBUG_PRINT("USER DISCONNECTED\n");
      break;
    case 7: // WIFI_EVENT_SOFTAPMODE_PROBEREQRECVED
      DEBUG_PRINT("WIFI_EVENT_SOFTAPMODE_PROBEREQRECVED\n");
      WiFi.scanNetworksAsync(printScanResult);
      break;
  }
}

//Где-то в коде===================
  wifi_connect(wifi.working);
//================================
 

Melandr

Member
Спасибо за ответ. А хотел уточнить пару моментов.
В основном цикле Вы вызываете функцию wifi_connect(wifi.working);
Ее нужно вызывать с какой-то периодичностью, или просто в loop() ?
Что делает функция WiFiEvent? просто в параметр wifi.working помещает событие WiFi? Когда ее нужно вызывать?
И в примере Вашего кода вижу, что при пропадании WiFi от роутера создается точка доступа. Но не могу понять, как следует правильно сделать, чтобы при восстановлении связи переподключиться обратно
 

Melandr

Member
Где-то попадался код, в котором проверялось наличие точки доступа с определенным именем, и если она находилась, происходило подключение. В обработчике событий WiFi такое можно сделать?
 

Melandr

Member
Вот нашел пример
Получается необходимо объявить переменные типа WiFiEventHandler и определить обработчики, результат которых помещается в эти переменные. И далее все уже делает API ESP? Но непонятно, как вернуться к старому подключению, при его восстановлении. Я так понимаю необходимо сканировать с определённой периодичностью доступные WiFi сети, делать перебор по именам и при наличии нужной осуществлять подключении. Или есть более простой способ, используя API класса ESP8266WiFi
 

Ildarmustafin86

Active member
У меня wifi_connect делает проверку каждую секунду
Где-то попадался код, в котором проверялось наличие точки доступа с определенным именем, и если она находилась, происходило подключение. В обработчике событий WiFi такое можно сделать?
В обработчике событий же есть WiFi.scanNetworksAsync(printScanResult);. Эта функция и выполняет подключение при появлении сети
C++:
void printScanResult(int networksFound) {
  //DEBUG_PRINT("\nSEARCHING \n");
  for (int i = 0; i < networksFound; i++) {
    if (WiFi.SSID(i) == wifi.ssid) {
      DEBUG_PRINT("\nFOUND \"%s\"\nCONNECTING...PLEASE WAIT...\n", wifi.ssid);
      WiFi_initSTA();
    }
  }
}
 

Melandr

Member
У меня wifi_connect делает проверку каждую секунду
То есть Вы вызов этой функции завязали на таймер или millis()? А как много времени забирает вызов wifi_connect ?
Также если не сложно, подскажите. Начал разбираться с событиями WiFi в новой нотации, с WiFiEventHandler. Там тоже есть обработчик WiFiEventHandler onSoftAPModeProbeRequestReceived, который я так понял возвращает TRUE, когда ESP находится в режиме SoftAP, но не понятен момент. Как часто будет возвращаться данное событие? Так как все обработчики описываются в секции setup(), и в loop() ничего не вызывается, как происходит обработка этого события?
По примеру
#include <ESP8266WiFi.h>

const char* ssid = "SamsungS9+";
const char* password = "qwert789";

WiFiEventHandler gotIpEventHandler, disconnectedEventHandler;

bool ledState;

void setup()
{
Serial.begin(115200);
Serial.println();

pinMode(LED_BUILTIN, OUTPUT);

gotIpEventHandler = WiFi.onStationModeGotIP([](const WiFiEventStationModeGotIP& event)
{
Serial.print("Station connected, IP: ");
Serial.println(WiFi.localIP());
});

disconnectedEventHandler = WiFi.onStationModeDisconnected([](const WiFiEventStationModeDisconnected& event)
{
Serial.println("Station disconnected");
});

Serial.printf("Connecting to %s ...\n", ssid);
// "Подключение к %s ... "
WiFi.begin(ssid, password);
}

void loop()
{
digitalWrite(LED_BUILTIN, ledState);
ledState = !ledState;
delay(250);
}
Все работает.
Для отслеживания событий WiFi мне нужно описать действия, которые необходимо произвести, при наступлении какого-либо события WiFi. С onStationModeDisconnected,все более менее ясно, при возникновении этого события пробуем переподключить несколько раз, если не получилось, то переводим ESP в режим AP. А вот, и в принципе при восстановлении без перевода в режим AP ESP подключается к роутеру. Но если ее перевести в режим AP,как вернуть в режим STA при восстановлении связи.
ЗЫ: По Вашему примеру понятно, но хочется разобраться с новым кодом. Спасибо за помощь.
 

Ildarmustafin86

Active member
Внимательней посмотрите в коде есть WIFI_initSTA() и WIFI_iniAP();
Сами функции

C++:
void WiFi_initAP() {
  WiFi.mode(WIFI_OFF);
  WiFi.mode(WIFI_AP);
  IPAddress apIP(192, 168, 4, 1);
  WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0));
  WiFi.softAP(wifi.ssidAP, wifi.passwordAP);
}
void WiFi_initSTA() {
  WiFi.mode(WIFI_OFF);
  WiFi.mode(WIFI_STA);
  if (strcmp(wifi.ip_str, "") && strcmp(wifi.ip_gw_str, "")) {
    bitSet(aux_bf, 7);
    IPAddress ip_subnet(255, 255, 255, 0);
    WiFi.config(wifi.ip, wifi.ip_gw, ip_subnet, wifi.ip_gw);
  } else {
    bitClear(aux_bf, 7);
  }
  if (strcmp(wifi.ssid, "") && strcmp(wifi.password, "")) {
    WiFi.begin(wifi.ssid, wifi.password);
  } else {
    WiFi_initAP();
  }
}
 

Melandr

Member
А вот есть еще объект
wifi (маленькие буквы, в отличие от WiFi)
и его свойства
countDS
working
и другие.
Где этот объект создается? В Вашем примере не увидел.
ЗЫ: 'wifi' was not declared in this scope
 

Melandr

Member
Спасибо, интересно посмотреть. С wifi уже понятней, это объект типа wifi_t , в котором хранятся текущие параметры wifi.
Это Вы делали контроллер для аквариума?
Посмотрел на Ваш код, подкупает конечно ESP8266 своими возможностями, но я тут в другой теме пытаюсь реализовать диммер переменного напряжения, то конечно в приложениях, критичных к выполнению кода, ESP проигрывает AVR.
 

Melandr

Member
Ildarmustafin86, доброй ночи!
Наваял по Вашему исходнику небольшой пример, используя WiFiEventHandler, но не могу понять, почему функция WiFi.getMode(); возвращает 1 независимо от режима.
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <stdio.h>

extern "C" {
#include "user_interface.h"
}

#define recTime 5
byte countDS = recTime;

const char* ssid = "LORD";
const char* ssidPass = "4182H{v7";
const char* ssidAP = "ESP8266";
const char* ssidApPass = "";

IPAddress apIP(192, 168, 4, 1);
IPAddress gateway(192, 168, 4, 1);
IPAddress subnet(255, 255, 255, 0);

IPAddress stIP(192, 168, 1, 120);
IPAddress gateIP(192, 168, 1, 1);
IPAddress subnetIP(255, 255, 255, 0);

WiFiEventHandler gotIpEventHandler;
WiFiEventHandler disconnectedEventHandler;
WiFiEventHandler clientConnectedEventHandler;
WiFiEventHandler clientDisconnectedEventHandler;

bool ledState;
bool modeWiFi; //0 - WIFI_AP, 1 - WIFI_STA, 2 - WIFI_AP_STA, 3 - WIFI_OFF

void WiFi_initAP() {
// WiFi.disconnect(true);
// WiFi.mode(WIFI_OFF);
// delay(1000);
WiFi.mode(WIFI_AP);
modeWiFi = WiFi.getMode();
WiFi.softAPConfig(apIP, gateway, subnet);
WiFi.softAP(ssidAP, ssidApPass);

Serial.print("SoftAP, IP: ");
Serial.println(WiFi.softAPIP());
}

void WiFi_initSTA() {
// WiFi.softAPdisconnect(true);
// WiFi.disconnect(true);
WiFi.mode(WIFI_OFF);
WiFi.mode(WIFI_STA);
WiFi.config(stIP, gateIP, subnetIP);
WiFi.begin(ssid, ssidPass);
}

void printScanResult(int networksFound) {
//DEBUG_PRINT("\nSEARCHING \n");
for (int i = 0; i < networksFound; i++) {
if (WiFi.SSID(i) == ssid) {
Serial.printf("\nFOUND \"%s\"\nCONNECTING...PLEASE WAIT...\n", ssid);
WiFi_initSTA();
}
}
}

void setup()
{
Serial.begin(115200);
Serial.println();

pinMode(LED_BUILTIN, OUTPUT);

gotIpEventHandler = WiFi.onStationModeGotIP([](const WiFiEventStationModeGotIP & event)
{
Serial.print("Station connected, IP: ");
Serial.println(WiFi.localIP());
});

disconnectedEventHandler = WiFi.onStationModeDisconnected([](const WiFiEventStationModeDisconnected & event)
{
Serial.println("Station disconnected");
modeWiFi = WiFi.getMode();
Serial.println(modeWiFi);
if (modeWiFi == WIFI_STA)
{
WiFi.reconnect();
if (--countDS) {
Serial.printf("CONNECTING...TRY:%i\n", countDS);
} else {
WiFi_initAP();
countDS = recTime;
}
}
if (modeWiFi == WIFI_AP)
{
WiFi.scanNetworksAsync(printScanResult);
}
});

clientConnectedEventHandler = WiFi.onSoftAPModeStationConnected([](const WiFiEventSoftAPModeStationConnected & event)
{
Serial.println("Client connected");
});

clientDisconnectedEventHandler = WiFi.onSoftAPModeStationDisconnected([](const WiFiEventSoftAPModeStationDisconnected & event)
{
Serial.println("Client disconnected");
});

Serial.printf("Connecting to %s ...\n", ssid);
// "Подключение к %s ... "
WiFi_initSTA();
}

void loop()
{
digitalWrite(LED_BUILTIN, ledState);
ledState = !ledState;
delay(250);

modeWiFi = WiFi.getMode();
Serial.println(modeWiFi);
}
А в новой нотации нет события, соответствующего WIFI_EVENT_SOFTAPMODE_PROBEREQRECVED
 

Melandr

Member
А не подскажите еще , разобрался с WiFiMode_t modeWiFi; //WIFI_OFF = 0, WIFI_STA = 1, WIFI_AP = 2, WIFI_AP_STA = 3
но почему-то постоянно возвращает 3, если перевожу в режим WIFI_AP
#include <Arduino.h>
#include <ESP8266WiFi.h> // Standart ESP8266 2.7.3, NOT 2.7.4
#include <stdio.h>

extern "C" {
#include "user_interface.h"
}

#define recTime 5
byte countDS = recTime;

const char* ssid = "LORD";
const char* ssidPass = "4182H{v7";
const char* ssidAP = "ESP8266";
const char* ssidApPass = "";

IPAddress apIP(192, 168, 4, 1);
IPAddress gateway(192, 168, 4, 1);
IPAddress subnet(255, 255, 255, 0);

IPAddress stIP(192, 168, 1, 120);
IPAddress gateIP(192, 168, 1, 1);
IPAddress subnetIP(255, 255, 255, 0);

WiFiEventHandler gotIpEventHandler;
WiFiEventHandler disconnectedEventHandler;
WiFiEventHandler clientConnectedEventHandler;
WiFiEventHandler clientDisconnectedEventHandler;

bool ledState;
WiFiMode_t modeWiFi; //WIFI_OFF = 0, WIFI_STA = 1, WIFI_AP = 2, WIFI_AP_STA = 3

void WiFi_initAP() {
// WiFi.disconnect(true);
WiFi.mode(WIFI_OFF);
// delay(1000);
WiFi.mode(WIFI_AP);
modeWiFi = WiFi.getMode();
WiFi.softAPConfig(apIP, gateway, subnet);
WiFi.softAP(ssidAP, ssidApPass);

Serial.print("SoftAP, IP: ");
Serial.println(WiFi.softAPIP());
}

void WiFi_initSTA() {
// WiFi.softAPdisconnect(true);
// WiFi.disconnect(true);
WiFi.mode(WIFI_OFF);
WiFi.mode(WIFI_STA);
WiFi.config(stIP, gateIP, subnetIP);
WiFi.begin(ssid, ssidPass);
}

void printScanResult(int networksFound) {
//DEBUG_PRINT("\nSEARCHING \n");
for (int i = 0; i < networksFound; i++) {
if (WiFi.SSID(i) == ssid) {
Serial.printf("\nFOUND \"%s\"\nCONNECTING...PLEASE WAIT...\n", ssid);
WiFi_initSTA();
}
}
}

void setup()
{
Serial.begin(115200);
Serial.println();

WiFi.persistent(false);

pinMode(LED_BUILTIN, OUTPUT);

gotIpEventHandler = WiFi.onStationModeGotIP([](const WiFiEventStationModeGotIP & event)
{
Serial.print("Station connected, IP: ");
Serial.println(WiFi.localIP());
});

disconnectedEventHandler = WiFi.onStationModeDisconnected([](const WiFiEventStationModeDisconnected & event)
{
Serial.println("Station disconnected");
modeWiFi = WiFi.getMode();
Serial.println(modeWiFi);
if (modeWiFi == WIFI_STA)
{
WiFi.reconnect();
if (--countDS) {
Serial.printf("CONNECTING...TRY:%i\n", countDS);
} else {
WiFi_initAP();
countDS = recTime;
}
}
if (modeWiFi == WIFI_AP)
{
WiFi.scanNetworksAsync(printScanResult);
}
});

clientConnectedEventHandler = WiFi.onSoftAPModeStationConnected([](const WiFiEventSoftAPModeStationConnected & event)
{
Serial.println("Client connected");
});

clientDisconnectedEventHandler = WiFi.onSoftAPModeStationDisconnected([](const WiFiEventSoftAPModeStationDisconnected & event)
{
Serial.println("Client disconnected");
});

Serial.printf("Connecting to %s ...\n", ssid);
// "Подключение к %s ... "
WiFi_initSTA();
}

void loop()
{
digitalWrite(LED_BUILTIN, ledState);
ledState = !ledState;
delay(250);

modeWiFi = WiFi.getMode();
Serial.println(modeWiFi);
}
 

Ildarmustafin86

Active member
C++:
#include <Arduino.h>
#include <ESP8266WiFi.h> // Standart ESP8266 2.7.3, NOT 2.7.4
#include <stdio.h>

extern "C" {
#include "user_interface.h"
}

#define recTime 5
byte countDS = recTime;

const char* ssid = "ччччччччччч";
const char* ssidPass = "пппппппппп";
const char* ssidAP = "ESP8266";
const char* ssidApPass = "";

IPAddress apIP(192, 168, 4, 1);
IPAddress gateway(192, 168, 4, 1);
IPAddress subnet(255, 255, 255, 0);

IPAddress stIP(192, 168, 1, 120);
IPAddress gateIP(192, 168, 1, 1);
IPAddress subnetIP(255, 255, 255, 0);

WiFiEventHandler gotIpEventHandler;
WiFiEventHandler disconnectedEventHandler;
WiFiEventHandler clientConnectedEventHandler;
WiFiEventHandler clientDisconnectedEventHandler;

bool ledState;
WiFiMode_t modeWiFi; //WIFI_OFF = 0, WIFI_STA = 1, WIFI_AP = 2, WIFI_AP_STA = 3

void WiFi_initAP() {
  WiFi.disconnect(true);
  WiFi.mode(WIFI_OFF);
  // delay(1000);
  WiFi.mode(WIFI_AP);
  WiFi.softAPConfig(apIP, gateway, subnet);
  WiFi.softAP(ssidAP, ssidApPass);

  Serial.print("SoftAP, IP: ");
  Serial.println(WiFi.softAPIP());
}

void WiFi_initSTA() {
  // WiFi.softAPdisconnect(true);
  // WiFi.disconnect(true);
  WiFi.mode(WIFI_OFF);
  WiFi.mode(WIFI_STA);
  WiFi.config(stIP, gateIP, subnetIP);
  WiFi.begin(ssid, ssidPass);
}

void printScanResult(int networksFound) {
  //DEBUG_PRINT("\nSEARCHING \n");
  for (int i = 0; i < networksFound; i++) {
    if (WiFi.SSID(i) == ssid) {
      Serial.printf("\nFOUND \"%s\"\nCONNECTING...PLEASE WAIT...\n", ssid);
      WiFi_initSTA();
    }
  }
}

void setup()
{
  Serial.begin(115200);
  Serial.println();

  WiFi.persistent(false);

  pinMode(LED_BUILTIN, OUTPUT);

  gotIpEventHandler = WiFi.onStationModeGotIP([](const WiFiEventStationModeGotIP & event)
  {
    Serial.print("Station connected, IP: ");
    Serial.println(WiFi.localIP());
  });

  disconnectedEventHandler = WiFi.onStationModeDisconnected([](const WiFiEventStationModeDisconnected & event)
  {
    Serial.println("Station disconnected");
    if (modeWiFi == WIFI_STA)
    {
      WiFi.reconnect();
      if (--countDS) {
        Serial.printf("CONNECTING...TRY:%i\n", countDS);
      } else {
        WiFi_initAP();
        countDS = recTime;
      }
    }
    if (modeWiFi == WIFI_AP)
    {
      WiFi.scanNetworksAsync(printScanResult);
    }
  });

  clientConnectedEventHandler = WiFi.onSoftAPModeStationConnected([](const WiFiEventSoftAPModeStationConnected & event)
  {
    Serial.println("Client connected");
  });

  clientDisconnectedEventHandler = WiFi.onSoftAPModeStationDisconnected([](const WiFiEventSoftAPModeStationDisconnected & event)
  {
    Serial.println("Client disconnected");
  });

  Serial.printf("Connecting to %s ...\n", ssid);
  // "Подключение к %s ... "
  WiFi_initSTA();
}

void loop()
{
  digitalWrite(LED_BUILTIN, ledState);
  ledState = !ledState;
  delay(250);

  modeWiFi = WiFi.getMode();
  Serial.println(modeWiFi);
}
 

Ildarmustafin86

Active member
А не подскажите еще , разобрался с WiFiMode_t modeWiFi; //WIFI_OFF = 0, WIFI_STA = 1, WIFI_AP = 2, WIFI_AP_STA = 3
но почему-то постоянно возвращает 3, если перевожу в режим WIFI_AP
И если Вы говорите что разобрались с WiFiMode_t, но у Вас не получается. Это значит что Вы не разобрались
 

Melandr

Member
А зачем ты делаешь проверку события в событии?
Не могли бы пояснить?
Также не определяется событие:
onProbeRequestEventHandler = WiFi.onProbeRequestReceive([](const WiFiEventSoftAPModeProbeRequestReceived & event)
{
Serial.println("onProbeRequestReceive");
});


class ESP8266WiFiClass' has no member named 'onProbeRequestReceive
 
Сверху Снизу