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