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

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

Melandr

Member
И если Вы говорите что разобрались с WiFiMode_t, но у Вас не получается. Это значит что Вы не разобрались
Ну в принципе уже выводится режим, но скорее всего, неправильно переключаюсь между режимами, поэтому ESP находится в режиме WIFI_AP_STA = 3
 

Melandr

Member
Спасибо за помощь, запустил код, переключается между STA и AP. Правда непонятно, почему режим показывает 3. Но это уже мелочи.
#include "include_define.h"

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;
WiFiEventHandler onProbeRequestEventHandler;

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();
}
}
}

String macToString(const unsigned char* mac) {
char buf[20];
snprintf(buf, sizeof(buf), "%02x:%02x:%02x:%02x:%02x:%02x",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
return String(buf);
}

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);
WiFi.reconnect();
if (--countDS) {
Serial.printf("CONNECTING...TRY:%i\n", countDS);
} else {
WiFi_initAP();
countDS = recTime;
}
});

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

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

onProbeRequestEventHandler = WiFi.onSoftAPModeProbeRequestReceived([](const WiFiEventSoftAPModeProbeRequestReceived & event)
{
Serial.print("Probe request from: ");
Serial.print(macToString(event.mac));
Serial.print(" RSSI: ");
Serial.println(event.rssi);
WiFi.scanNetworksAsync(printScanResult);
});

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
Спасибо за помощь, запустил код, переключается между STA и AP. Правда непонятно, почему режим показывает 3. Но это уже мелочи.
#include "include_define.h"

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;
WiFiEventHandler onProbeRequestEventHandler;

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();
}
}
}

String macToString(const unsigned char* mac) {
char buf[20];
snprintf(buf, sizeof(buf), "%02x:%02x:%02x:%02x:%02x:%02x",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
return String(buf);
}

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);
WiFi.reconnect();
if (--countDS) {
Serial.printf("CONNECTING...TRY:%i\n", countDS);
} else {
WiFi_initAP();
countDS = recTime;
}
});

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

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

onProbeRequestEventHandler = WiFi.onSoftAPModeProbeRequestReceived([](const WiFiEventSoftAPModeProbeRequestReceived & event)
{
Serial.print("Probe request from: ");
Serial.print(macToString(event.mac));
Serial.print(" RSSI: ");
Serial.println(event.rssi);
WiFi.scanNetworksAsync(printScanResult);
});

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);
}
Здесь принято благодарить плюсом в карму
 

Melandr

Member
запустил код из 38 поста, действительно режим -2, но не происходит переключение обратно на роутер
 

Melandr

Member
а в моем коде при отключении от роутера, переходит в режим SotAP , но при срабатывании события onProbeRequestEventHandler переключается в режим WIFI_AP_STA = 3 и пытается подключиться к роутеру и потом переключается.
Режим 2 сохраняется пока телефон не пробует подключиться к ESP а далее переходит в 3
 

Ildarmustafin86

Active member
Кстати, почему работает в режиме AP_STA. Я думаю это из-за того что при работе в АР, есп еще сканирует сеть на наличие точки доступа, а это он делает в режиме STA. Поэтому при выполнении scanNetworkAsync контроллер переходит в AP_STA. Более знающие люди поправят меня, если это не так. На этом мои познания заканчиваются. Чем мог, тем помог
 

Melandr

Member
Как Вам карму повысить? за помощь. Не нашел. Я кстати тоже подумал, что находясь в режиме AP и сканируя доступные сети, необходимо перевести ESP в режим AP_STA
PS: спасибки за код для аквариума. Интересно посмотреть, как другие делают. А у Вас там работа и с FS и с EEPROM. Легче разбираться.
 

Ildarmustafin86

Active member
Если напишете WiFi.mode(WIFI_AP); в void WiFi_initAP(), то в логах видно что сперва включается в режим АР, потом переключается в режим АР+СТА

C++:
===================================
WIFI INIT AP
===================================
del if0
usl
mode : null
mode : softAP(82:7d:3a:7f:dc:7e)
add if1
dhcp server start:(ip:192.168.4.1,mask:255.255.255.0,gw:192.168.4.1)
bcn 100
[APConfig] local_ip: 192.168.4.1 gateway: 192.168.4.1 subnet: 255.255.255.0
[APConfig] DHCP IP start: 192.168.4.100
[APConfig] DHCP IP end: 192.168.4.200
bcn 0
del if1
usl
add if1
dhcp server start:(ip:192.168.4.1,mask:255.255.255.0,gw:192.168.4.1)
bcn 100
wifi evt: 8
wifi evt: 8
wifi evt: 7
mode : sta(80:7d:3a:7f:dc:7e) + softAP(82:7d:3a:7f:dc:7e)
add if0
wifi evt: 8
wifi evt: 7
wifi evt: 7
wifi evt: 7

А если сразу напишете
WiFi.mode(WIFI_AP_STA);
C++:
===================================
WIFI INIT AP
===================================
del if0
usl
mode : null
mode : sta(80:7d:3a:7f:dc:7e) + softAP(82:7d:3a:7f:dc:7e)
add if0
add if1
dhcp server start:(ip:192.168.4.1,mask:255.255.255.0,gw:192.168.4.1)
bcn 100
[APConfig] local_ip: 192.168.4.1 gateway: 192.168.4.1 subnet: 255.255.255.0
[APConfig] DHCP IP start: 192.168.4.100
[APConfig] DHCP IP end: 192.168.4.200
bcn 0
del if1
add if1
dhcp server start:(ip:192.168.4.1,mask:255.255.255.0,gw:192.168.4.1)
bcn 100
wifi evt: 8
wifi evt: 8
wifi evt: 7
 

Melandr

Member
да замечал, сначала включался режим AP, а позже переключалось в режим AP_STA
 

Melandr

Member
Ildarmustafin86, а не подскажите, какая разница в использовании обычного или асинхронного сервера на ESP. в плане преимуществ или недостатков.
 

Melandr

Member
Добрый вечер!
Не подскажите, в чем может быть проблема.
Использую в коде библиотеку WiFiMulti и и эвенты WiFi для переключения между режимом STA и AP при пропадании WiFi соединения с роутером. В принципе после отключения поднимается программная точка доступа и программа работает, но при восстановлении WiFi соединения роутера ESP к нему подключается но происходит Exception 9

Есть подозрение, что использую неправильный алгоритм для восстановления связи с роутером.
Ниже код
main.ino
Код:
#include "include_define.h"

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

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

  int count_try = 0;

  WiFi.persistent(false);

  pinMode(LED_BUILTIN, OUTPUT);

  gotIpEventHandler = WiFi.onStationModeGotIP(&onStationGotIP);
  disconnectedEventHandler = WiFi.onStationModeDisconnected(&onDisconnected);
  clientConnectedEventHandler = WiFi.onSoftAPModeStationConnected(&onStationConnected);
  clientDisconnectedEventHandler = WiFi.onSoftAPModeStationDisconnected(&onStationDisconnected);
  onProbeRequestEventHandler = WiFi.onSoftAPModeProbeRequestReceived(&onProbeRequestPrint);

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

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

  modeWiFi = WiFi.getMode();
  Serial.print("Режим WiFi: ");
  Serial.print(modeWiFi);
  Serial.print(". SSID: ");
  Serial.println(WiFi.SSID());
}
include_define.h
Код:
#include <Arduino.h>
//#include <ESPAsyncTCP.h>         // https://github.com/me-no-dev/ESPAsyncTCP
//#include <ESPAsyncWebServer.h>   // https://github.com/me-no-dev/ESPAsyncWebServer
#include <ESP8266WiFi.h>         // Standart ESP8266 2.7.3, NOT 2.7.4
#include <ESP8266WiFiMulti.h>
#include <stdio.h>
#include "user_interface.h"

ESP8266WiFiMulti wifiMulti;

#define wifi_max_try  10 // Число попыток подключения к WiFi
#define recTime 5
byte countDS = recTime;
byte tryConnect = 0;

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

const char* ssid = "LORD";
const char* password = "41xxx";
const char* ssid_1 = "SamsungS9+";
const char* password_1 = "qxxx";
const char* ssid_2 = "ASUS_";
const char* password_2 = "gxxx";
const char* ssid_3 = "TP-LINK_F54920";
const char* password_3 = "54xxxx";
const char* ssid_4 = "DD-WRT_";
const char* password_4 = "gCxxx";
const char* ssidAP     = "ESP8266";
const char* ssidApPass = "";
String ssidST, passwordST;

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

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

bool ledState;
WiFi.ino
Код:
void WiFi_initAP() {
  WiFi.disconnect(true);
  WiFi.mode(WIFI_OFF);

  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.mode(WIFI_OFF);
  WiFi.mode(WIFI_STA);
  //  WiFi.config(stIP, gateIP, subnetIP);
  //  WiFi.begin(ssid, ssidPass);
  wifiMulti.addAP(ssid, password);
  wifiMulti.addAP(ssid_1, password_1);
  wifiMulti.addAP(ssid_2, password_2);
  wifiMulti.addAP(ssid_3, password_3);
  wifiMulti.addAP(ssid_4, password_4);

  Serial.println("Connecting Wifi...");
  while (wifiMulti.run() != WL_CONNECTED && tryConnect++ < wifi_max_try) { // Wait for the Wi-Fi to connect: scan for Wi-Fi networks, and connect to the strongest of the networks above
    delay(500);
    Serial.println(F("."));
    Serial.print(F("Попытка подключения - "));
    Serial.println(tryConnect);
  }
  if (WiFi.status() == WL_CONNECTED) {
    Serial.println('\n');
    Serial.print(F("Connected to "));
    Serial.println(WiFi.SSID());              // Tell us what network we're connected to
    Serial.print(F("IP address:\t"));
    Serial.println(WiFi.localIP());           // Send the IP address of the ESP8266 to the computer
    ssidST = WiFi.SSID();
  }
  else {
    Serial.println(F("No wifi connection! Starting SoftAP!"));
    WiFi_initAP();
  }
}

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

String macToString(const unsigned char* mac) {
  char buf[20];
  snprintf(buf, sizeof(buf), "%02x:%02x:%02x:%02x:%02x:%02x",
           mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
  return String(buf);
}

void onStationGotIP(const WiFiEventStationModeGotIP & event)
{
  Serial.print("Station connected, IP: ");
  Serial.println(WiFi.localIP());
}

void onDisconnected(const WiFiEventStationModeDisconnected & event)
{
  Serial.println("Station disconnected");
  modeWiFi = WiFi.getMode();
  Serial.println(modeWiFi);
  WiFi.reconnect();
  if (--countDS) {
    Serial.printf("CONNECTING...TRY:%i\n", countDS);
  } else {
    WiFi_initAP();
    countDS = recTime;
  }
}

void onStationConnected(const WiFiEventSoftAPModeStationConnected & event)
{
  Serial.println("Client connected");
}

void onStationDisconnected(const WiFiEventSoftAPModeStationDisconnected & event)
{
  Serial.println("Client disconnected");
}

void onProbeRequestPrint(const WiFiEventSoftAPModeProbeRequestReceived & event)
{
  Serial.print("Probe request from: ");
  Serial.print(macToString(event.mac));
  Serial.print(" RSSI: ");
  Serial.println(event.rssi);
  //  WiFi.scanNetworksAsync(printScanResult);
  wifiMulti.run();
}
 

Вложения

Melandr

Member
Добрый день!
Вывел в последовательный порт значение кучи
Свободная память: 48976 кБ
Режим WiFi: 3. SSID:
Свободная память: 48976 кБ
wifi evt: 7
Probe request from: da:a1:19:f7:ab:a7 RSSI: -76
[WIFI] scan done
[WIFI] no networks found


[WIFI] start scan
Режим WiFi: 3. SSID:
Свободная память: 48744 кБ
wifi evt: 7
Probe request from: da:a1:19:f7:ab:a7 RSSI: -74
wifi evt: 7
Probe request from: da:a1:19:60:dd:d9 RSSI: -76
wifi evt: 7
Probe request from: da:a1:19:60:dd:d9 RSSI: -72
wifi evt: 7
Probe request from: da:a1:19:9c:50:4c RSSI: -75
wifi evt: 7
Probe request from: da:a1:19:a8:ee:ea RSSI: -75
wifi evt: 7
Probe request from: da:a1:19:60:a6:a2 RSSI: -72
Режим WiFi: 3. SSID:
Свободная память: 48880 кБ
Режим WiFi: 3. SSID:
Свободная память: 48880 кБ
scandone
Режим WiFi: 3. SSID:
Свободная память: 48880 кБ
wifi evt: 7
Probe request from: 02:dc:cc:48:e5:e0 RSSI: -76
[WIFI] scan done
[WIFI] 1 networks found
---> 0: [6][6E:C7:EC:C3:98:2C] SamsungS9+ (-36) *


[WIFI] Connecting BSSID: 6E:C7:EC:C3:98:2C SSID: SamsungS9+ Channel: 6 (-36)
Fatal exception 9(LoadStoreAlignmentCause):
epc1=0x4010537c, epc2=0x00000000, epc3=0x00000000, excvaddr=0x00000003, depc=0x00000000

--------------- CUT HERE FOR EXCEPTION DECODER ---------------

Exception (9):
epc1=0x4010537c epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000003 depc=0x00000000

>>>stack>>>

ctx: sys
sp: 3fffec50 end: 3fffffb0 offset: 0190
3fffede0: 00000000 00000000 4bc6a7f0 00000000
.........
3fffff90: 3fffdad0 00000000 3ffee7b8 4010019d
3fffffa0: 3fffdad0 00000000 3ffee7b8 4020508c
<<<stack<<<

--------------- CUT HERE FOR EXCEPTION DECODER ---------------

ets Jan 8 2013,rst cause:2, boot mode:(3,6)

load 0x4010f000, len 3584, room 16
tail 0
chksum 0xb0
csum 0xb0
v2843a5ac
~ld

SDK:2.2.2-dev(38a443e)/Core:2.7.3-3-g2843a5ac=20703003/lwIP:STABLE-2_1_2_RELEASE/glue:1.2-30-g92add50/BearSSL:5c771be

scandone
del if0
usl
mode : null
modewifi evt: 8
: sta(84:0d:8e:86:db:47)
add if0
[WIFI][APlistAdd] add SSID: LORD
[WIFI][APlistAdd] add SSID: SamsungS9+
[WIFI][APlistAdd] add SSID: ASUS
[WIFI][APlistAdd] add SSID: TP-LINK_F54920
[WIFI][APlistAdd] add SSID: DD-WRT
Connecting Wifi...
[WIFI] delete old wifi config...
[WIFI] start scan
wifi evt: 8
Где-то попадалась на форуме тема с правильным переподключением между STA и AP. Попробую сделать как там советуют и отпишусь.
Перезагрузка произошла после того как ESP работала как softAP и я включил мобильную точку доступа на телефоне, которая прописана в списке точек доступа.
 
Сверху Снизу