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

Нужна помощь Неправильный статус после автоматического переподключения к Wi-Fi точке доступа

RAlexeev

New member
ESP8266 возвращает неправильный статус после автоматического переподключения к Wi-Fi точке доступа в WIFI_STA и WIFI_AP_STA режимах. Как я ожидаю, функци WiFi.isConnected() должна вернуть true, а WiFi.status() код WL_CONNECTED после автоматического переподключения к точке доступа, однако по каким-то причинам эти функции возвращают false и WL_DISCONNECTED соответственно. Хотя в действительности ESP8266 успешно переподключается к Wi-Fi точке доступа, но возвращает неправильный статус. Может быть кто-нибудь может подсказать, что я делаю неправильно, из-за чего получаю не те статусы?

Мой скетч, который компилировался в Arduino IDE v. 1.8.5:

Код:
#include <ESP8266WiFi.h>
#include <ArduinoJson.h>


const char* ssid = "MYWIFISSID";
const char* password = "MYWIFIPSK";


void setup()
{
  Serial.begin(115200);
  delay(1000);

  WiFi.mode(WIFI_AP_STA);
  WiFi.softAP("my_esp");
  delay(1000);
 
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
}


void loop()
{
  delay(5000);

  DynamicJsonDocument doc;
  JsonObject& obj = doc.to<JsonObject>();

  obj["chip_id"] = String(ESP.getChipId(), HEX);

  JsonObject& wifi = obj.createNestedObject("wifi");
  switch (WiFi.getMode()) {
    case WIFI_OFF:
      wifi["mode"] = "WIFI_OFF";
      break;
    case WIFI_STA:
      wifi["mode"] = "WIFI_STA";
      break;
    case WIFI_AP:
      wifi["mode"] = "SWIFI_AP";
      break;
    case WIFI_AP_STA:
      wifi["mode"] = "WIFI_AP_STA";
      break;
    default:
      wifi["mode"] = "UNKNOWN";
  }
 
  JsonObject& ap = wifi.createNestedObject("ap");
  ap["ssid"] = WiFi.softAPSSID();
  ap["psk"] = WiFi.softAPPSK();
  ap["ip"] = WiFi.softAPIP().toString();
  ap["mac"] = WiFi.softAPmacAddress();
  ap["station_num"] = (uint8_t) WiFi.softAPgetStationNum();
 
  JsonObject& station = wifi.createNestedObject("station");
  station["ssid"] = WiFi.SSID();
  station["psk"] = WiFi.psk();
  station["ip"] = WiFi.localIP().toString();
  station["hostname"] = WiFi.hostname();
  station["mac"] = WiFi.macAddress();
  station["subnet"] = WiFi.subnetMask().toString();
  station["gateway"] = WiFi.gatewayIP().toString();
 
  JsonObject& dns = station.createNestedObject("dns");
  dns["0"] = WiFi.dnsIP(0).toString();
  dns["1"] = WiFi.dnsIP(1).toString();

  JsonObject& states = obj.createNestedObject("state");
  states["AutoConnect"] = WiFi.getAutoConnect();
  states["AutoReconnect"] = WiFi.getAutoReconnect();
  states["Persistent"] = WiFi.getPersistent();
  states["isConnected"] = WiFi.isConnected();

  switch (WiFi.status()) {
    case WL_CONNECTED:
      states["status"] = "WL_CONNECTED";
      break;
    case WL_NO_SHIELD:
      states["status"] = "WL_NO_SHIELD";
      break;
    case WL_IDLE_STATUS:
      states["status"] = "WL_IDLE_STATUS";
      break;
    case WL_NO_SSID_AVAIL:
      states["status"] = "WL_NO_SSID_AVAIL";
      break;
    case WL_SCAN_COMPLETED:
      states["status"] = "WL_SCAN_COMPLETED";
      break;
    case WL_CONNECT_FAILED:
      states["status"] = "WL_CONNECT_FAILED";
      break;
    case WL_CONNECTION_LOST:
      states["status"] = "WL_CONNECTION_LOST";
      break;
    case WL_DISCONNECTED:
      states["status"] = "  ";
      break;
  }

  Serial.println("========================================");
  serializeJsonPretty(obj, Serial);
  Serial.println("========================================");
}
Вывод монитора последовательного порта можно найти в прикреплённом файле serial_monitor_output.txt.

Заранее благодарю за любую помощь.
 

Вложения

Последнее редактирование:

Алексей.

Active member
RAlexeev, По каким признакам вы определяете что выполнено автоматическое переподключение к точке доступа?
По логам у вас только в начале событие EVENT_STAMODE_GOT_IP срабатывает

connected with MYWIFISSID, channel 8
dhcp client start...
wifi evt: 0
ip:192.168.1.37,mask:255.255.255.0,gw:192.168.1.1
wifi evt: 3
.wifi evt: 7

И статус должен возвращать WL_CONNECTED только после этого события.
Код:
wl_status_t ESP8266WiFiSTAClass::status() {
    station_status_t status = wifi_station_get_connect_status();
    switch(status) {
        case STATION_GOT_IP:
            return WL_CONNECTED;
        case STATION_NO_AP_FOUND:
            return WL_NO_SSID_AVAIL;
        case STATION_CONNECT_FAIL:
        case STATION_WRONG_PASSWORD:
            return WL_CONNECT_FAILED;
        case STATION_IDLE:
            return WL_IDLE_STATUS;
        default:
            return WL_DISCONNECTED;
    }
}
И совсем не понятно для чего запрашивать и статус и isConnected
states["isConnected"] = WiFi.isConnected();
switch (WiFi.status()) {
Код:
bool ESP8266WiFiSTAClass::isConnected() {
    return (status() == WL_CONNECTED);
}
 
Последнее редактирование:

RAlexeev

New member
Алексей., спасибо Вам за ответ! По логам второе подключение происходит на строчке "connected with MYWIFISSID, channel 6". Факт подключения я определил, посмотрев клиентов Wi-Fi роутера и пропинговав esp8266. Видимо, это был баг, который как раз исправили. Если скачать мастер ветку библиотеки esp8266/Arduino, то подобной ошибки нет. Об этом я узнал как раз отсюда WIFI.isconnected stil false after router reboot but ping requests reponse etc works · Issue #4210 · esp8266/Arduino. Завтра посмотрю, есть ли там в логах "wifi evt: 3" во время второго подключения. Но скорей всего да, раз проблемы больше нет.
 

Алексей.

Active member
По логам второе подключение происходит на строчке "connected with MYWIFISSID, channel 6".
Это говорит о том что выполнено подключение и только, об этом и говорит событие wifi evt: 0 (EVENT_STAMODE_CONNECTED) через одну строчку лога, ip адрес в аренду еще не выдан (или выдан но почему то dhcp клиент об этом забыл сказать), событие EVENT_STAMODE_GOT_IP так и не наступило, поэтому и статус по прежнему WL_DISCONNECTED.
Порой есп ведет себя не предсказуемо, иногда у меня оставались не закрытые сокеты, fin с удаленной стороны отправляется, а на есп теряется, приходится отслеживать таймауты и прибивать вялые сокеты.
 

RAlexeev

New member
Алексей., с последней версией библиотеки, действительно, происходит событие "wifi evt: 3" в логах во время подключения. Но теперь я наткнулся на другую ошибку при работе с устройством:
Fatal exception 0(IllegalInstructionCause). Ошибка возникает в режиме отладки и только с одним роутером Zyxel Keenetic LTE, когда сеть закрытая. Можно отключить режим отладки и ошибки не будет, а также можно оставить режим отладки и убрать одну из функций [inline]WiFi.persistent(false);[/inline], [inline]wifiDisconnect(true);[/inline] или [inline]MDNS.begin("my_esp_hostname");[/inline], тогда тоже ошибки не будет. Очень напрягает такой хрупкий код, который может сломаться не пойми от чего.

Код:
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>


void wifiDisconnect(bool wifioff) {
  switch (WiFi.getMode()) {
    case WIFI_STA:
      delay(100);
      WiFi.disconnect(wifioff);
      delay(100);
      break;
    case WIFI_AP:
      delay(100);
      WiFi.softAPdisconnect(wifioff);
      delay(100);
      break;
    case WIFI_AP_STA:
      delay(100);
      WiFi.disconnect(wifioff);
      delay(100);
      WiFi.softAPdisconnect(wifioff);
      delay(100);
      break;
  }
}


void setup(){
  Serial.begin(115200);
  delay(1000);

  WiFi.persistent(false);

  wifiDisconnect(true);

  WiFi.mode(WIFI_STA);
  WiFi.hostname("my_esp_hostname");
  WiFi.begin("MYWIFISSID", "MYWIFIPSK");
  for (uint8_t tries = 0; tries < 30; tries++) {
    if (WiFi.isConnected()) {
      break;
    }
    else {
      delay(500);
    }
  }

  MDNS.begin("my_esp_hostname");
}


void loop() { }
Вывод последновательного порта:
Код:
SDK:2.2.1(cfd48f3)/Core:2.4.1-102-g74819a76/lwIP:2.0.3(STABLE-2_0_3_RELEASE/glue:arduino-2.4.1-13-g163bb82)/BearSSL:94e9704
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
bcn 0
del if1
usl
mode : null
wifi evt: 8
mode : sta(dc:4f:22:18:14:58)
add if0
wifi evt: 8
wifi evt: 2
scandone
state: 0 -> 2 (b0)
state: 2 -> 3 (0)
state: 3 -> 5 (10)
add 0
aid 2
cnt

connected with MYWIFISSID, channel 6
dhcp client start...
wifi evt: 0
ip:192.168.1.33,mask:255.255.255.0,gw:192.168.1.1
wifi evt: 3
Fatal exception 0(IllegalInstructionCause):
epc1=0xa8c05814, epc2=0x00000000, epc3=0x00000000, excvaddr=0x00000000, depc=0x00000000

Exception (0):
epc1=0xa8c05814 epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000000 depc=0x00000000

ctx: cont
sp: 3ffffbb0 end: 3fffffd0 offset: 01a0

>>>stack>>>
3ffffd50:  00000000 00000000 00000020 4010122e
3ffffd60:  3ffe9410 4022436b 3ffef514 3fff03f4
3ffffd70:  00000000 4021822f 3ffed7ec 401009e4
3ffffd80:  3ffe8ffc 3ffffe60 3ffffe60 3ffef87d
3ffffd90:  3ffef5b0 3fff0144 0000000a 3ffedf3c
3ffffda0:  3ffe8ffc 3ffe8ffc 3ffefa67 4021a057
3ffffdb0:  3ffefcda 0000002e 0000001f 40104f09
3ffffdc0:  4000050c 0006688e 3ffee020 3ffef2f5
3ffffdd0:  3ffef2c0 3ffef2c0 3ffefc94 4020bed2
3ffffde0:  4020c26b 3ffefc94 3ffefcda 4020c274
3ffffdf0:  00000008 3ffffe20 00000000 000000a5
3ffffe00:  000000a5 3ffefb28 00000001 3ffefce8
3ffffe10:  3ffefc94 3ffefab0 3ffef2c0 40211ded
3ffffe20:  005e0001 4010fb00 00000012 4022d8ae
3ffffe30:  00000018 3ffefab0 3ffefc94 40212874
3ffffe40:  00000080 401022f4 3ffeed68 00000000
3ffffe50:  3ffef2c4 00000001 00000000 00000002
3ffffe60:  3ffef220 00000004 3ffefaac 40212ee4
3ffffe70:  00000001 00000001 402391a0 3ffefaac
3ffffe80:  00000000 3ffefc94 3ffefd00 402128b4
3ffffe90:  3ffef2c0 3ffffec0 00000004 3ffefaac
3ffffea0:  00000016 3ffef2c0 3ffefaac 40212045
3ffffeb0:  3ffef2c0 3ffffec0 00000004 4020c2c8
3ffffec0:  00000494 00000000 3ffef454 4020c304
3ffffed0:  3ffefab0 3ffef2c0 3ffeed68 40212116
3ffffee0:  3ffef50c 402052f8 0000001c 00000020
3ffffef0:  3fffff5c 3ffef2c0 3ffefaac 402122ef
3fffff00:  3fffff5c 3ffe9138 3ffef2c0 4021237b
3fffff10:  4957594d 00000001 3fffff90 00000001
3fffff20:  3ffeecd4 3ffeeca8 3ffeecd4 4020359a
3fffff30:  00000000 3ffeeca8 3ffefaa4 401009e4
3fffff40:  3ffeed68 000000e4 3fffff80 40205350
3fffff50:  00000000 402052f8 3ffeed00 fb0000e0
3fffff60:  00000000 3ffeeca8 3ffeecd4 3ffeee54
3fffff70:  00000000 3ffeeca8 3ffeecd4 40204892
3fffff80:  3ffefaac 40202f28 40203250 402036bc
3fffff90:  00000000 00000000 000001f4 402030e4
3fffffa0:  3ffe8950 00000017 3ffeeca8 40202771
3fffffb0:  3fffdad0 00000000 3ffeee4c 402054a0
3fffffc0:  feefeffe feefeffe 3ffe85dc 40100a45
<<<stack<<<

ets Jan  8 2013,rst cause:1, boot mode:(3,0)

load 0x4010f000, len 1384, room 16
tail 8
chksum 0x2d
csum 0x2d
v74819a76
~ld
Расшифровка исключения:
Код:
Exception 0: Illegal instruction
PC: 0xa8c05814
EXCVADDR: 0x00000000

Decoding stack results
0x401009e4: free at /opt/arduino-1.8.5/hardware/esp8266com/esp8266/cores/esp8266/umm_malloc/umm_malloc.c line 1755
0x4020bed2: new_linkoutput at glue-lwip/lwip-git.c line 259
0x4020c26b: ethernet_output at netif/ethernet.c line 305
0x4020c274: ethernet_output at netif/ethernet.c line 305
0x40211ded: etharp_output_LWIP2 at core/ipv4/etharp.c line 893
0x40212874: ip4_output_if_opt_src at core/ipv4/ip4.c line 962
0x40212ee4: mem_malloc at core/mem.c line 136
0x402128b4: ip4_output_if_opt at core/ipv4/ip4.c line 788
0x40212045: igmp_send at core/ipv4/igmp.c line 793
0x4020c2c8: do_memp_malloc_pool at core/memp.c line 301
0x4020c304: memp_malloc at core/memp.c line 404
0x40212116: igmp_lookup_group at core/ipv4/igmp.c line 258
0x402052f8: operator new(unsigned int) at /opt/arduino-1.8.5/hardware/esp8266com/esp8266/cores/esp8266/abi.cpp line 34
0x402122ef: igmp_joingroup_netif at core/ipv4/igmp.c line 694
0x4021237b: igmp_joingroup at core/ipv4/igmp.c line 464
0x4020359a: MDNSResponder::_listen() at /opt/arduino-1.8.5/hardware/esp8266com/esp8266/libraries/ESP8266mDNS/ESP8266mDNS.cpp line 198
0x401009e4: free at /opt/arduino-1.8.5/hardware/esp8266com/esp8266/cores/esp8266/umm_malloc/umm_malloc.c line 1755
0x40205350: operator delete(void*) at /opt/arduino-1.8.5/hardware/esp8266com/esp8266/cores/esp8266/abi.cpp line 54
0x402052f8: operator new(unsigned int) at /opt/arduino-1.8.5/hardware/esp8266com/esp8266/cores/esp8266/abi.cpp line 34
0x40204892: MDNSResponder::begin(char const*) at /opt/arduino-1.8.5/hardware/esp8266com/esp8266/libraries/ESP8266mDNS/ESP8266mDNS.cpp line 174
0x40202f28: ESP8266WiFiSTAClass::status() at /opt/arduino-1.8.5/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp line 498
0x40203250: std::_Function_base::_Base_manager ::_M_manager(std::_Any_data &, const std::_Any_data &, std::_Manager_operation) at /opt/arduino-1.8.5/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/xtensa-lx106-elf/include/c++/4.8.2/functional line 1931
0x402036bc: std::_Function_handler ::_M_invoke(const std::_Any_data &, const WiFiEventStationModeDisconnected &) at /opt/arduino-1.8.5/hardware/esp8266com/esp8266/libraries/ESP8266mDNS/ESP8266mDNS.cpp line 171
0x402030e4: ESP8266WiFiSTAClass::isConnected() at /opt/arduino-1.8.5/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp line 324
0x40202771: setup() at /home/roman/Arduino/sketch_mdns_fatal_exception/sketch_mdns_fatal_exception.ino line 48
0x402054a0: loop_wrapper() at /opt/arduino-1.8.5/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_main.cpp line 122
 

Алексей.

Active member
Можно отключить режим отладки и ошибки не будет
Память свободную не пытались контролировать?
Может из за включенного режима отладки не осталось памяти совсем.
WiFi.persistent - вообще ничего не делает, просто устанавливает статическую переменную и только, никаких дополнительных вызовов не делает и не должен крашить ни разу.
По логу крашится на выходе из umm_free, такое впечатление что стек пробили попали в небытие поэтому и сработало исключение Illegal instruction
 
Сверху Снизу