• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе 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 и я включил мобильную точку доступа на телефоне, которая прописана в списке точек доступа.
 
Сверху Снизу