Arduino-esp32: WiFi自动重新连接仍然不起作用-是否有最佳实践来保证连接?

创建于 2017-09-21  ·  150评论  ·  资料来源: espressif/arduino-esp32

板载:ModeMCU ESP32 Dev模块
核心安装/更新日期:2017年9月15日
IDE名称:Arduino IDE

似乎没有自动重新连接逻辑可让ESP32在连接断开或连接不正常时重新连接。 我的ESP32开发板获得了完全随机的结果,有时只有30分钟,最多18至20小时。 WiFi正在下降,并且不想重新连接。

我用于WiFi的库正在观看WiFi事件,并在断开连接时尝试重新连接,这很有帮助,但有时重新连接失败,仅此而已...我必须重新启动。 根本不涉及睡眠/低功耗模式,并且该设备始终以3.3v in的功率供电。为此打开了一个案例, https://github.com/espressif/arduino-esp32/issues/353 ,但是它的关闭,没有任何实际答案(说自动连接是实现的...不确定是什么意思)。

我想这个问题归结为可靠地在代码本身中实现了自动重新连接,如果不是,那么确保其连接的最佳Arduino代码方法是什么?

-艾伦

最有用的评论

更新; 我看到使用了很多WiFiEvent并用于调试它的功能,但是每次仅能可靠地检测wifi断开并重新连接下面的IF / ELSE即可。

之所以可行,是因为从下到报告WL_CONNECTED更改大约需要18秒钟,这使DHCP服务器有时间释放IP,以便以后进行可靠的重新连接。

它已经工作了6年以上,并且还在不断增加。

loop()
{
  if ( WiFi.status() ==  WL_CONNECTED ) 
  {
    // WiFi is UP,  do what ever
  } else
  {
    // wifi down, reconnect here
   WiFi.begin(  );
    int WLcount = 0;
    while (WiFi.status() != WL_CONNECTED && WLcount < 200 ) 
    {
      delay( 100 );
         Serial.printf(".");
         if (UpCount >= 60)  // just keep terminal from scrolling sideways
         {
            UpCount = 0;
               Serial.printf("\n");
         }
         ++UpCount;
      ++WLcount;
    }
  }
} // END loop()

看看我在https://github.com/espressif/arduino-esp32/issues/1100上发布的框架代码

尽管它是使用SmartConfig进行设置的,但它确实可以工作。

所有150条评论

您能否在面板菜单中启用调试功能,并查看为什么不告诉您重新连接的原因?

我今晚可以尝试。 Arduino代码非常基本,可以观看WiFi事件,然后执行以下操作:

case SYSTEM_EVENT_STA_DISCONNECTED:
    Serial.println("WiFi lost connection.  Attempting to reconnect...");
    WiFi.reconnect();
    break;

但是,难道不应该有什么可以使之单独发生的东西吗?

只是为了快速解决:
在SYSTEM_EVENT_STA_DISCONNECTED中启动一个调用WiFi.reconnect();的计时器。 功能并在SYSTEM_EVENT_STA_CONNECTED中将其停止。 主要问题是您的想法是,如果设备无法连接,而不是未调用SYSTEM_EVENT_STA_DISCONNECTED事件,则设备将不再尝试重新连接。

不幸的是,我正在改用其他人的库,并且我对C ++不太熟悉,但是我将看到我可以添加计时器的方法(我知道VB.net ...我至少可以弄清楚逻辑部分,并希望适应)。

但是我认为您是正确的,它不会重新连接或更好,而只是尝试断开连接,如果断开连接一旦失败,它就会失败。 启用调试可能会告诉我,因此我将从此处开始。

但是回到原来的问题和先前已解决的问题:此功能不是内置的吗? 如果不是,为什么以前的问题由于“有点”起作用而结束? 如果不是这样的话吗?

我将调试级别切换为调试并打开了串行监视器,然后反复进行以下操作:

[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...

我检查了它最后一次将数据发送到另一个控制器的时间,并且是在24小时前,所以我假设它停留在这种模式下。 因此,我关闭了电源并重新启动,它可以正常连接到WiFi,并在大约2个小时的时间内传输了数据。 然后没有任何其他消息,它断开连接,并一遍又一遍地发出完全相同的消息。 我放了一个小时,重新启动了控制器,并再次连接了它,但是我确定它只是重新开始之前的时间问题。

所以第一个问题是我该如何解决。 其次,这仍然使我想到了以前有关自动重新连接的问题

伙计们请启用调试,以便您可以看到更多详细的WiFi状态输出:
screen shot 2017-09-22 at 13 48 16

我使用以下代码检查我的设备是否仍连接到STA(从loop()调用此函数)。 你有主意吗? wifi_is_connected是在wifi事件回调中设置和重置的全局变量。

static void poll_watchdog_sta(void) {
  static uint32_t ms = millis();
  static uint8_t watchdog = 0;

  // watch out for STA disconnects and reboot if
  // connection cannot be reestablished after
  // X minutes

  // this watchdog MUST NOT reboot the device if
  // wifi is not enabled or never was connected
  // since last reboot

  if (wifi_is_enabled && watchdog_enabled && ((millis() - ms) > 1000 * 6)) {
    ms = millis();

    if (!wifi_is_connected) {
      if (++watchdog < watchdog_timeout * 10) { // timeout in minutes ( * 10 )
        if (watchdog == 1) {
          log_print(F("WIFI: arming network watchdog (reboot in %i min.)"),
            watchdog_timeout
          );
        }
      } else {
        log_print(F("WIFI: still not connected, triggering reboot ..."));
        system_reboot();
      }
    } else {
      if (watchdog) {
        log_print(F("WIFI: network is back, disarming watchdog"));
        watchdog = 0;
      }
    }
  }
}

是的,我没有在用于WiFi(同样是第三方)的库中看到Loop(),但我了解您在做什么并且可以运行它。

将打开详细的日志记录,看看在更改任何内容之前我是否首先得到更多信息。

另外,正在检查和执行的WiFi事件是SYSTEM_EVENT_STA_GOT_IP,SYSTEM_EVENT_STA_DISCONNECTED,SYSTEM_EVENT_STA_START和SYSTEM_EVENT_STA_CONNECTED。 但是在https://github.com/espressif/esp-idf/blob/master/components/esp32/include/esp_event.h上还有更多内容,所以我添加了默认值:到应该打印事件以查看是否图书馆正在得到一些东西,但没有采取任何行动。

我在库中看到我正在使用//WiFi.setAutoReconnect(true); 因此,我假设原始作者尝试使用自动重新连接,但无法正常工作,因此将其注释掉了吗?

@ me-no-dev-详细给出了更好的解释。 好吧...也许对你来说:

一切都很好,然后反复进行了150次:

[E][WiFiClient.cpp:97] connect(): lwip_connect_r: 113

其次是:

[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:187] _eventCallback(): Reason: 7 - NOT_ASSOCED
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:187] _eventCallback(): Reason: 202 - ASSOC_FAIL
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:187] _eventCallback(): Reason: 2 - AUTH_EXPIRE
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:187] _eventCallback(): Reason: 2 - AUTH_EXPIRE
[WiFi-event] event: 5

最后一部分(重新连接,事件5,原因2)仅每4-5秒重复一次。

基于反复出现的第一个错误,我发现了这一点: https :

//**************************************************************************************
/// Event Handler for ESP32 WiFi Events (needed to implement reconnect logic for now...)
//**************************************************************************************
    void MyESP32WiFi::WiFiEvent(WiFiEvent_t event)
    {
        Serial.printf("[WiFi-event] event: %d\n", event);

        switch (event) {
        case SYSTEM_EVENT_STA_GOT_IP:
            Serial.println("WiFi connected");
            Serial.println("IP address: ");
            Serial.println(WiFi.localIP());
            break;
        case SYSTEM_EVENT_STA_DISCONNECTED:
            Serial.println("WiFi lost connection.  Attempting to reconnect...");
            WiFi.reconnect();
            break;
        case SYSTEM_EVENT_STA_START:
            Serial.println("ESP32 station start");
            break;
        case SYSTEM_EVENT_STA_CONNECTED:
            Serial.println("ESP32 station connected to AP");
            break;
        default:            
            Serial.println("Unhandled WiFi Event raised.");
            break;
        }

    }

基于前一篇文章中的错误,我得到了“ 5”,它转换为WiFi连接丢失,然后代码尝试执行“ WiFi.reconnect();”。 但是它显然不起作用。 我还应该在那里吗? 也许计数器有点像@everslick示例,但是更简单(只是ai = i + 1),并且如果它在20次尝试后重新启动就位于同一位置? 还是应该首先避免/避免这种情况?

尝试致电WiFi.begin()而不是重新连接并报告:)

@ me-no-dev-我将其更改为WiFi.begin()而不是WiFi.reconnect(),但没有帮助。 工作大约一个小时,然后得到lwip_connect_r:113行,每行相距大约一分钟左右,然后每5秒钟断开一次连接:

[E][WiFiClient.cpp:97] connect(): lwip_connect_r: 113
[E][WiFiClient.cpp:97] connect(): lwip_connect_r: 113
[E][WiFiClient.cpp:97] connect(): lwip_connect_r: 113
[E][WiFiClient.cpp:97] connect(): lwip_connect_r: 113
[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:187] _eventCallback(): Reason: 7 - NOT_ASSOCED
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:187] _eventCallback(): Reason: 2 - AUTH_EXPIRE
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:187] _eventCallback(): Reason: 2 - AUTH_EXPIRE

然后,这4行会无限重复,直到重新启动控件为止。 我还能尝试什么? @everslick在处于相同的断开状态时令人担忧的是正在重新启动控制器....我认为重新启动是最后的选择,可以采取一些措施使它保持在线状态。

附带说明一下,连接到同一路由器(Netgear R8000)的两个ESP8266没有问题,并且已经稳定了一个月以上而没有断开连接。

嗯...。这似乎是较低堆栈或路由器中的问题。
您可以看到第一个原因为NOT_ASSOCED,然后得到AUTH_EXPIRE。
您能否关闭STA然后再重新打开? 断开连接的原因使我认为重新关联请求中的某些内容未更改,或者您的路由器不接受,因此它拒绝您重新连接。 我将看看是否可以提出与此有关的内部问题。 您使用的路由器固件版本是什么?

它是Netgear Nighthawk R8000。 当前在最新的固件V1.0.3.54_1.1.37上,尽管它也在最新版本上进行过。 我可以在任何给定时间连接20-25个设备,而不会出现问题,包括前面提到的两个ESP8266。

我将尝试关闭STA并重新打开Wi-Fi的开始/重新连接线路,然后看看会发生什么。

编辑:对此了解不多,并使用其他人的库....我如何“关闭STA,然后再将其重新打开”?

第二编辑:不能与https://github.com/espressif/esp-idf/issues/499#issuecomment -314262611相关吗? 我使用相同的NOT_ASSOCED和AUTH_EXPIRE看到的仅有的东西之一。 我不会这么认为是因为我自己编译时没有BLE东西,但从来不知道。

我还提醒了wifi团队:)我们将看看是否有任何结果

谢谢。 我是否应该尝试开通STA? 如果可以的话,您可以指导我如何进行操作或为我指明正确的方向吗?

我也看到了这个: https : @rojer

所以我又买了第二个ESP32,以确保它不是硬件问题。 昨天晚上,我从github(https://nodemcu.readthedocs.io/en/dev-esp32/en/build/)那里重新下载了固件,并刷新了新芯片和旧芯片。 我也用完全相同的草图闪烁了一下。 原始文件位于我的车库中,距路由器仅几步之遥,另一个测试文件位于我的起居室中,那里的WiFi强度更高。 两者都具有在详细设置的已连接PC上运行的串行监视器。 我会把发现的一切都报告给我。

上面说的还有什么我可以尝试的吗? 如何开通STA? 可以在WiFi.reconnect所在的STA_Disconnect部分中完成此操作吗?

嗯,这并没有持续很长时间。...我在新版本上遇到了同样的问题。 首先,原始文件开始时出现相同的“ [E] [WiFiClient。cpp :97 ] connect():lwip_connect_r:113”错误,并且在线仅30分钟后未发送数据。 通常一次两次出现该错误,然后在下一组之间间隔45到50秒之间大约5或6秒,但又有点随机。 这样做了大约10分钟,然后进入了相同的断开模式:


[E][WiFiClient.cpp:97] connect(): lwip_connect_r: 113
[E][WiFiClient.cpp:97] connect(): lwip_connect_r: 113
Data: Sending: temperature1 -49.02
[E][WiFiClient.cpp:97] connect(): lwip_connect_r: 113
[E][WiFiClient.cpp:97] connect(): lwip_connect_r: 113
Data: Sending: humidity1 -5.02
[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:187] _eventCallback(): Reason: 7 - NOT_ASSOCED
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:187] _eventCallback(): Reason: 202 - ASSOC_FAIL
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:187] _eventCallback(): Reason: 2 - AUTH_EXPIRE
[WiFi-event] event: 5

并一遍又一遍地重复最后4行。 一方面它确实做了一些不同的事情...错误消息略有变化:

[E][WiFiClient.cpp:97] connect(): lwip_connect_r: 113
[E][WiFiClient.cpp:97] connect(): lwip_connect_r: 118
Data: Sending: temperature2 -1.00
[E][WiFiClient.cpp:97] connect(): lwip_connect_r: 118
[E][WiFiClient.cpp:97] connect(): lwip_connect_r: 118
Data: Sending: humidity2 -1.00
[E][WiFiClient.cpp:97] connect(): lwip_connect_r: 118
[E][WiFiClient.cpp:97] connect(): lwip_connect_r: 118
[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:187] _eventCallback(): Reason: 2 - AUTH_EXPIRE
[WiFi-event] event: 5

请注意,错误切换到以118而不是113结束。但是从那一点开始,它只是随机地反复重复118错误以及STA_DISCONNECTED和AUTH_EXPIRED。

然后新的ESP32开始做完全相同的事情。 通常是113错误,然后是NOT_ASSOCED,ASSOC_FAIL和AUTH_EXPIRE的相同模式,然后是断开连接和AUTH_EXPIRE一遍又一遍。

它们在完全相同的时间启动时,在不同的时间(相隔25分钟)失败。 WiFi信号似乎不是一个因素,也不是任何确定的时间。

编辑:只是要在重新启动时清楚,它每次在第一次尝试时都会立即连接:

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
flash read err, 1000
ets_main.c 371 
ets Jun  8 2016 00:22:57

rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0010,len:4
load:0x3fff0014,len:708
load:0x40078000,len:0
load:0x40078000,len:11460
entry 0x400789f4
Everything: init started
Everything: Free RAM = -1
Disabling ESP32 WiFi Access Point
[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 2 - STA_START
[WiFi-event] event: 2
Initializing ESP32 WiFi network.  Please be patient...
ESP32 station start
Attempting to connect to WPA SSID: (SSIDRemoved)
..[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 4 - STA_CONNECTED
[WiFi-event] event: 4
ESP32 station connected to AP
[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 7 - STA_GOT_IP
[WiFi-event] event: 7
WiFi connected
IP address: 
192.168.xx.xx

仍在等待WiFi小组的回应。 还会发出更多噪音,因为这也使我感到烦恼。 问题在Arduino以下和封闭源代码wifi lib中的某个地方。

谢谢。 我将尝试向不断获取的STA_DISCONNECTED事件切换语句添加一个计数器,并在5次尝试重新初始化wifi并在10次重新启动控制器并在连接后将计数器重置为0,看看计数器是否为0。至少可以保持控制器正常运行。

如果还有其他问题,我可以为您提供帮助以解决此问题或尝试代码,请告诉我。 如果很重要,我正在使用的ESP32用于两个电压输入,一个二进制输入和一个DTH22(温度+湿度),那么该数据将通过HTTP发送到控制器。

@vseven ,您好,我自己无法重现此问题,您能告诉我WiFi的固件版本吗? 您可以从启动日志中获得“ I(588)wifi:wifi固件版本:2cd69aa”,然后我可以为您提供调试版本wifi lib来调试此问题。

@vseven您能让我知道WiFi重新连接逻辑吗? 我的意思是什么时候调用esp_wifi_connect()? 如果您可以粘贴实现逻辑,将很有帮助。

@liuzfesp wifi日志记录在Arduino中已禁用。
@vseven评论此行以显示它

好的,我注释掉该行并重新编译。 我会报告。 附带说明一下,我试图通过调用init()来添加一个重新连接的计数器,但是它没有做任何事情....就像从未调用过init()一样。 我可能做错了。 但是当计数器达到10时,ESP.restartly异常地被调用并正确地重新启动,之后它重新连接:

    void SmartThingsESP32WiFi::WiFiEvent(WiFiEvent_t event)
    {
        Serial.printf("[WiFi-event] event: %d\n", event);
        switch (event) {
        case SYSTEM_EVENT_STA_GOT_IP:
            Serial.println("WiFi connected");
            Serial.println("IP address: ");
            Serial.println(WiFi.localIP());
            break;
        case SYSTEM_EVENT_STA_DISCONNECTED:
            Serial.println("WiFi lost connection.  Attempting to reconnect...");
            WiFi.reconnect();
            disconnectCounter++;
            if (disconnectCounter > 5) {
                Serial.println("We have recieved the STA_DISCONNECTED event 5 times now.  Re-init...");
                void init();
            }
            if (disconnectCounter > 10) {
                Serial.println("We have recieved the STA_DISCONNECTED event 10 times now.  Reboot...");
                ESP.restart();
            }
            break;
        case SYSTEM_EVENT_STA_START:
            Serial.println("ESP32 station start");
            break;
        case SYSTEM_EVENT_STA_CONNECTED:
            Serial.println("ESP32 station connected to AP");
            disconnectCounter = 0;
            break;
        }
    }

@liuzfesp-这是该行被注释掉的额外信息:

I (243) wifi: wifi firmware version: c1b8a2f
I (243) wifi: config NVS flash: enabled
I (243) wifi: config nano formating: disabled
I (257) wifi: Init dynamic tx buffer num: 32
I (257) wifi: Init data frame dynamic rx buffer num: 64
I (257) wifi: Init management frame dynamic rx buffer num: 64
I (261) wifi: wifi driver task: 3ffd0d8c, prio:23, stack:4096
I (267) wifi: Init static rx buffer num: 10
I (270) wifi: Init dynamic rx buffer num: 0
I (274) wifi: Init rx ampdu len mblock:7
I (278) wifi: Init lldesc rx ampdu entry mblock:4
I (282) wifi: wifi power manager task: 0x3ffd60f0 prio: 21 stack: 2560
I (290) wifi: wifi timer task: 3ffd7148, prio:22, stack:3584
I (314) wifi: mode : null
Disabling ESP32 WiFi Access Point

I (815) wifi: Init Ampdu: 1 tx baw=6 rx baw=6
I (815) wifi: mode : sta (30:ae:a4:25:78:64)
[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 2 - STA_START

Initializing ESP32 WiFi network.  Please be patient...
[WiFi-event] event: 2
ESP32 station start
Attempting to connect to WPA SSID: (SSIDREMOVED)
.I (1946) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
.I (2603) wifi: state: init -> auth (b0)
I (2605) wifi: state: auth -> assoc (0)
I (2612) wifi: state: assoc -> run (10)
I (2670) wifi: connected with (SSIDREMOVED), channel 1
[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 4 - STA_CONNECTED
[WiFi-event] event: 4
ESP32 station connected to AP
[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 7 - STA_GOT_IP
[WiFi-event] event: 7
WiFi connected

和我正在使用的文件(在添加断开连接计数器之前):

SmartThingsESP32WiFi.h.txt
SmartThingsESP32WiFi.cpp.txt

@liuzfesp-因此,启用了调试功能后,它执行的操作相同,希望此处的内容可以告诉您一些信息。 它运行了一个小时左右,然后开始随机抛出113错误。 在实际数据发送例程之间随机出现约15分钟的113错误之后,它执行了以下操作:

I (5427111) wifi: state: run -> auth (7c0)
I (5427111) wifi: pm stop, total sleep time: 0/1119534452

I (5427111) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:187] _eventCallback(): Reason: 7 - NOT_ASSOCED
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
I (5427133) wifi: state: auth -> init (0)
[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:187] _eventCallback(): Reason: 202 - ASSOC_FAIL
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
I (5427276) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
I (5427276) wifi: state: init -> auth (b0)
I (5428276) wifi: state: auth -> init (2)
I (5428277) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:187] _eventCallback(): Reason: 2 - AUTH_EXPIRE
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
I (5428413) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
I (5428414) wifi: state: init -> auth (b0)
I (5429414) wifi: state: auth -> init (2)
I (5429414) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:187] _eventCallback(): Reason: 2 - AUTH_EXPIRE
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
I (5429551) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
I (5429551) wifi: state: init -> auth (b0)
I (5430551) wifi: state: auth -> init (2)
I (5430551) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:187] _eventCallback(): Reason: 2 - AUTH_EXPIRE
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
I (5430688) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
I (5430688) wifi: state: init -> auth (b0)
I (5431689) wifi: state: auth -> init (2)
I (5431689) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:187] _eventCallback(): Reason: 2 - AUTH_EXPIRE
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
We have recieved the STA_DISCONNECTED event 5 times now.  Re-init...
I (5431826) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
I (5431826) wifi: state: init -> auth (b0)
I (5432826) wifi: state: auth -> init (2)
I (5432826) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:187] _eventCallback(): Reason: 2 - AUTH_EXPIRE
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
We have recieved the STA_DISCONNECTED event 5 times now.  Re-init...
I (5432963) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
I (5432963) wifi: state: init -> auth (b0)
I (5433964) wifi: state: auth -> init (2)
I (5433964) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:187] _eventCallback(): Reason: 2 - AUTH_EXPIRE
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
We have recieved the STA_DISCONNECTED event 5 times now.  Re-init...
I (5434100) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
I (5434101) wifi: state: init -> auth (b0)
I (5435101) wifi: state: auth -> init (2)
I (5435101) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:187] _eventCallback(): Reason: 2 - AUTH_EXPIRE
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
We have recieved the STA_DISCONNECTED event 5 times now.  Re-init...
I (5435238) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
I (5435238) wifi: state: init -> auth (b0)
I (5436238) wifi: state: auth -> init (2)
I (5436239) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:187] _eventCallback(): Reason: 2 - AUTH_EXPIRE
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
We have recieved the STA_DISCONNECTED event 5 times now.  Re-init...
I (5436375) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
I (5436376) wifi: state: init -> auth (b0)
I (5437376) wifi: state: auth -> init (2)
I (5437376) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:187] _eventCallback(): Reason: 2 - AUTH_EXPIRE
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
We have recieved the STA_DISCONNECTED event 5 times now.  Re-init...
We have recieved the STA_DISCONNECTED event 10 times now.  Reboot...
I (5437405) wifi: flush txq
I (5437407) wifi: stop sw txq
I (5437410) wifi: lmac stop hw txq
ets Jun  8 2016 00:22:57

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)

因此,对于每个STA_DISCONNECT,它尝试调用WiFi.reconnect都没有明显的成功,然后在5次以上的断开连接后尝试运行init(),这也无济于事,一旦断开10次,它便重新启动,并重新启动并重新连接。

我整个周末都在ESP32上运行串行监视器,它在星期五晚上6点至星期日晚上9点之间重新启动了约10次。 每次都与上面的日志完全一样。

@ me-no-dev-您能以某种方式指导我关闭并重新打开STA,以查看是否也可以重新连接吗,但我可以尝试5次失败尝试一下? 10点后重新启动可以工作,但是我计划使用它来控制RGB照明,我真的不想关闭和打开照明。

@liuzfesp-我还能为您提供调试服务吗? 还是任何我可以尝试的突出之处?

任何更新? 这两个设备仍然不断断开连接。

@liuzfesp这里有什么新闻吗?

我看到蓝牙和WiFi进行了一些代码更改。 不知道这是否对我有帮助。 我仍然仍然遇到相同的问题,重新启动正在努力保持数据传递,但是由于重新启动后灯一直关闭,因此我无法将其用于RGB灯带控制。

@liuzfesp-日志中是否有任何可以帮助的东西,或者我可以提供或尝试的其他东西?

我整理了一些东西,确保代码中没有延迟或阻塞,并且现在我的错误更少(看不到113和118错误),但是仍然存在相同的断开连接问题,并且看起来与WiFi尝试进行身份验证(续订?)并失败。 这是本周末的最新记录,我在24小时内重新启动了大约5次。 再次,在两个不同的ESP32上做同样的事情,我寻找断开连接(事件5),并尝试重新连接WiFi.reconnect和WiFi.begin都没有运气,因此在10次尝试后重新启动并随后正常连接:

I (1903652) wifi: active cnt: 5
I (1913652) wifi: active cnt: 5
I (1923652) wifi: send null to keep active
I (1933652) wifi: send null to keep active
I (1943653) wifi: active cnt: 1
I (1953653) wifi: active cnt: 2
I (1963653) wifi: send null to keep active
I (1973653) wifi: send null to keep active
I (1983653) wifi: send null to keep active
I (1993653) wifi: active cnt: 1
I (2003654) wifi: send null to keep active
I (2013654) wifi: send null to keep active
I (2023654) wifi: send null to keep active
I (2033654) wifi: send null to keep active
I (2043654) wifi: send null to keep active
I (2053654) wifi: send null to keep active
I (2063654) wifi: send null to keep active
I (2073655) wifi: send null to keep active
I (2083655) wifi: active cnt: 1
I (2093655) wifi: send null to keep active
I (2103655) wifi: send null to keep active
I (2113655) wifi: send null to keep active
I (2123655) wifi: send null to keep active
I (2133655) wifi: send null to keep active
I (2143656) wifi: send null to keep active
I (2153656) wifi: send null to keep active
I (2163656) wifi: send null to keep active
I (2173656) wifi: send null to keep active
I (2183656) wifi: send null to keep active
I (2193656) wifi: send null to keep active
I (2203657) wifi: send null to keep active
I (2213657) wifi: send null to keep active
I (2223657) wifi: send null to keep active
I (2233657) wifi: send null to keep active
I (2243657) wifi: send null to keep active
I (2253657) wifi: send null to keep active
I (2263657) wifi: send null to keep active
I (2273658) wifi: active cnt: 2
I (2283658) wifi: send null to keep active
I (2293658) wifi: send null to keep active
I (2303658) wifi: send null to keep active
I (2313658) wifi: send null to keep active
I (2323658) wifi: send null to keep active
I (2333658) wifi: send null to keep active
I (2343659) wifi: send null to keep active
I (2353659) wifi: send null to keep active
I (2363659) wifi: send null to keep active
I (2373659) wifi: send null to keep active
I (2383659) wifi: send null to keep active
I (2393659) wifi: send null to keep active
I (2403660) wifi: send null to keep active
I (2413660) wifi: send null to keep active
I (2423660) wifi: send null to keep active
I (2433660) wifi: send null to keep active
I (2443660) wifi: send null to keep active
I (2453660) wifi: send null to keep active
I (2463660) wifi: send null to keep active
I (2473661) wifi: send null to keep active
I (2483661) wifi: send null to keep active
I (2483663) wifi: state: run -> auth (7c0)
I (2483663) wifi: pm stop, total sleep time: 0/-1824912959

I (2483663) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
I (2483674) wifi: state: auth -> init (0)
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
I (2483805) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
I (2483805) wifi: state: init -> auth (b0)
I (2484805) wifi: state: auth -> init (2)
I (2484806) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
I (2484930) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
I (2484931) wifi: state: init -> auth (b0)
I (2485931) wifi: state: auth -> init (2)
I (2485931) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
I (2486056) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
I (2486056) wifi: state: init -> auth (b0)
I (2487056) wifi: state: auth -> init (2)
I (2487056) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
I (2487181) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
I (2487181) wifi: state: init -> auth (b0)
I (2488182) wifi: state: auth -> init (2)
I (2488182) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
I (2488306) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
I (2488307) wifi: state: init -> auth (b0)
I (2489307) wifi: state: auth -> init (2)
I (2489307) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
I (2489432) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
I (2489432) wifi: state: init -> auth (b0)
I (2490432) wifi: state: auth -> init (2)
I (2490432) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
I (2490557) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
I (2490557) wifi: state: init -> auth (b0)
I (2491558) wifi: state: auth -> init (2)
I (2491558) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
I (2491682) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
I (2491683) wifi: state: init -> auth (b0)
I (2492683) wifi: state: auth -> init (2)
I (2492683) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
I (2492808) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
I (2492808) wifi: state: init -> auth (b0)
I (2493808) wifi: state: auth -> init (2)
I (2493808) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
We have recieved the STA_DISCONNECTED event over 10 times now.  Reboot...
I (2493819) wifi: flush txq
I (2493822) wifi: stop sw txq
I (2493824) wifi: lmac stop hw txq
ets Jun  8 2016 00:22:57

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0010,len:4
load:0x3fff0014,len:708
load:0x40078000,len:0
load:0x40078000,len:11460
entry 0x400789f4
Everything: init started
Everything: Free RAM = -1
I (749) wifi: wifi firmware version: c1b8a2f
I (749) wifi: config NVS flash: enabled
I (749) wifi: config nano formating: disabled
I (758) wifi: Init dynamic tx buffer num: 32
I (758) wifi: Init data frame dynamic rx buffer num: 64
I (758) wifi: Init management frame dynamic rx buffer num: 64
I (762) wifi: wifi driver task: 3ffca34c, prio:23, stack:4096
I (768) wifi: Init static rx buffer num: 10
I (771) wifi: Init dynamic rx buffer num: 0
I (775) wifi: Init rx ampdu len mblock:7
I (779) wifi: Init lldesc rx ampdu entry mblock:4
I (783) wifi: wifi power manager task: 0x3ffd6004 prio: 21 stack: 2560
I (791) wifi: wifi timer task: 3ffd705c, prio:22, stack:3584
I (815) wifi: mode : null
Disabling ESP32 WiFi Access Point

I (1816) wifi: Init Ampdu: 1 tx baw=6 rx baw=6
I (1816) wifi: mode : sta (30:ae:a4:07:f1:98)
[WiFi-event] event: 2

Initializing ESP32 WiFi network.  Please be patient...
ESP32 station start
Attempting to connect to WPA SSID: (SSIDREMOVED)
.I (2943) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
.I (3600) wifi: state: init -> auth (b0)
I (3602) wifi: state: auth -> assoc (0)
I (3606) wifi: state: assoc -> run (10)
I (3635) wifi: connected with (SSIDREMOVED), channel 1
[WiFi-event] event: 4
ESP32 station connected to AP
[WiFi-event] event: 7
WiFi connected
IP address: 
192.168.1.142

@liuzfesp / @ me-no-

-艾伦

我的WROOM-32模块具有完全相同的行为。
每次第3或第4次重新引导时,它都会挂在STA_DISCONNECTED-> AUTH_EXPIRED循环中。
检查了另一个相同类型的模块,显示了相同的行为。
我的路由器是TL-WR841(TPLINK),但在华硕RT-AC87U中也是如此。

什么时候有解决方案,如果在这种情况下需要重新启动,它将无用...

编辑:对我来说,这个问题也会在启动后发生,即WiFi.begin()根本不会建立连接,但是会在STA_DISCONNECTED-> AUTH_EXPIRED中循环

我一个月都没有得到回应,尽管没有冒犯,但我很高兴这件事正在别人身上发生,所以我知道我并不孤单。

@liuzfesp / @ me-no-

再次戳@liuzfesp ...这是我真正能做的。 我无权访问WiFi库源

@igrr

@copercini为什么?

由于我被标记在这里... @vseven ,您是否有可能在监控模式下使用Wireshark和WiFi适配器执行数据包捕获? 特别有趣的是重新连接过程开始失败的时间。 由于我们不知道这里发生了什么,也无法在CI环境中重现类似的问题,因此数据包捕获可能会揭示一些异常情况,从而为您所面临的情况提供线索。

还有一种想法(只是为了减少变量的数量),如果您连接到开放的WiFi网络,是否还会发生此问题?

当前,所有重新连接都失败,并带有以下调试输出的WROOM32:

[D] [WiFiGeneric。 cpp:265 ] _eventCallback():事件:2-STA_START
.... [D] [WiFiGeneric。 cpp:265 ] _eventCallback():事件:4-STA_CONNECTED
.. [D] [WiFiGeneric。 cpp:265 ] _eventCallback():事件:7-STA_GOT_IP
WiFi已连接
...然后我阻止天线接收或按我的AP上的RESET,以强制断开连接...
[D] [WiFiGeneric。 cpp:265 ] _eventCallback():事件:5-STA_DISCONNECTED
[W] [WiFiGeneric。 cpp:270 ] _eventCallback():原因:200-NO_AP_FOUND
...当应该再次接收正常时,大约需要2分钟,直到显示:

[D] [WiFiGeneric。 cpp:265 ] _eventCallback():事件:8-STA_WPS_ER_SUCCESS

但是,在该状态下,它始终与网络断开连接。
我的AP的WPS已关闭。 不知道调试消息是什么意思。
使用wificlient示例草图,在两个不同的AP和两个不同的WROOM32模块上具有相同的行为。 无论使用WPA2还是开放网络。
如果需要,可以在监视方式下发送Wireshark日志。

首先,感谢大家对SDK的辛勤工作。 我在开发过程中获得了很多乐趣,对于所做的所有努力,我深表感谢。

我也看到了这个问题。 我想我可能已经设法缩小了一点。 我正在使用这个非常小的草图,该草图应该在ESP8266和ESP32上都可以使用:

https://github.com/sidoh/esp32_reconnect_demo

我关闭了自动重新连接,以便可以更好地控制变量。

设定

  1. 在ESP8266和ESP32上进行测试
  2. 使用移动热点网络。 尝试了WPA2 PSK和开放式网络
  3. 允许MCU连接到网络并运行几秒钟。 我添加了一个NTP客户端来验证连接性。

然后我尝试了两种不同的方法:

(一)拆网,立即重建

在这种情况下,通常会在MCU注意到断开连接时重新创建网络。

(B)拆除网络,等待MCU注意到它已断开连接,然后重新创建网络

观察结果

  1. WPA2和开放网络的行为都相同。
  2. ESP8266已成功与(A)和(B)重新连接。
  3. ESP32在实验(A)中重新连接,但卡在(B)中。
  4. 如果满足以下条件,ESP32在(A)和(B)WiFi.disconnect(true); _and_ WiFi.begin(WIFI_SSID, WIFI_PASSWD); 。 似乎两者都是必要的。
    \
    布尔wifioff参数disconnect被设置为true似乎也是必要的。 由于WiFi.disconnect(true);似乎清除了WiFi设置,因此有必要在对begin的呼叫中重新指定ssid和密码。

日志

所有这些都具有开放的网络。 由于行为符合预期,因此我省略了ESP8266日志,但可以提供它们是否有用。

ESP32,实验(A)

I (25) wifi: wifi firmware version: 708a055
I (26) wifi: config NVS flash: enabled
I (26) wifi: config nano formating: disabled
I (31) wifi: Init dynamic tx buffer num: 32
I (32) wifi: Init data frame dynamic rx buffer num: 64
I (32) wifi: Init management frame dynamic rx buffer num: 64
I (35) wifi: wifi driver task: 3ffd46dc, prio:23, stack:4096
I (40) wifi: Init static rx buffer num: 10
I (44) wifi: Init dynamic rx buffer num: 0
I (48) wifi: wifi power manager task: 0x3ffd9418 prio: 21 stack: 2560
I (425) wifi: mode : sta (30:ae:a4:04:42:c8)
[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 2 - STA_START
I (2836) wifi: n:6 0, o:1 0, ap:255 255, sta:6 0, prof:1
I (2836) wifi: state: init -> auth (b0)
I (2853) wifi: state: auth -> assoc (0)
I (2872) wifi: state: assoc -> run (10)
I (2872) wifi: connected with glowyrectangle, channel 6
[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 4 - STA_CONNECTED
[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 7 - STA_GOT_IP
Setup completed
[4] ssid=glowyrectangle
[5] ssid=glowyrectangle
I (5872) wifi: pm start, type:0

[6] ssid=glowyrectangle
[7] ssid=glowyrectangle
[8] ssid=glowyrectangle
[9] ssid=glowyrectangle
[10] ssid=glowyrectangle
I (10388) wifi: state: run -> auth (7c0)
I (10389) wifi: pm stop, total sleep time: 0/4516399

I (10389) wifi: n:6 0, o:6 0, ap:255 255, sta:6 0, prof:1
[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:270] _eventCallback(): Reason: 7 - NOT_ASSOCED
W (11413) wifi: Haven't to connect to a suitable AP now!
[11] ssid=
Attempting to reconnect...
I (13822) wifi: n:6 0, o:6 0, ap:255 255, sta:6 0, prof:1
I (13823) wifi: state: auth -> auth (b0)
I (13826) wifi: state: auth -> assoc (0)
I (13839) wifi: state: assoc -> run (10)
I (13839) wifi: connected with glowyrectangle, channel 6
[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 4 - STA_CONNECTED
[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 7 - STA_GOT_IP
Connection result: 3
[1513219385] ssid=glowyrectangle
[1513219386] ssid=glowyrectangle
[1513219387] ssid=glowyrectangle
[1513219388] ssid=glowyrectangle
I (16839) wifi: pm start, type:0

ESP32,实验(B)

rst:0x10 (RTCWDT_RTC_RESET),boot:0x17 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0018,len:4
load:0x3fff001c,len:812
load:0x40078000,len:0
load:0x40078000,len:11404
entry 0x40078aa0
I (25) wifi: wifi firmware version: 708a055
I (26) wifi: config NVS flash: enabled
I (26) wifi: config nano formating: disabled
I (35) wifi: Init dynamic tx buffer num: 32
I (36) wifi: Init data frame dynamic rx buffer num: 64
I (36) wifi: Init management frame dynamic rx buffer num: 64
I (39) wifi: wifi driver task: 3ffd46d0, prio:23, stack:4096
I (44) wifi: Init static rx buffer num: 10
I (48) wifi: Init dynamic rx buffer num: 0
I (52) wifi: wifi power manager task: 0x3ffd940c prio: 21 stack: 2560
I (431) wifi: mode : sta (30:ae:a4:04:42:c8)
[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 2 - STA_START
I (2842) wifi: n:6 0, o:1 0, ap:255 255, sta:6 0, prof:1
I (2843) wifi: state: init -> auth (b0)
I (2846) wifi: state: auth -> assoc (0)
I (2863) wifi: state: assoc -> run (10)
I (2863) wifi: connected with glowyrectangle, channel 6
[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 4 - STA_CONNECTED
[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 7 - STA_GOT_IP
Setup completed
[3] ssid=glowyrectangle
[4] ssid=glowyrectangle
I (5863) wifi: pm start, type:0

[5] ssid=glowyrectangle
[1513219573] ssid=glowyrectangle
[1513219574] ssid=glowyrectangle
[1513219575] ssid=glowyrectangle
[1513219576] ssid=glowyrectangle
[1513219577] ssid=glowyrectangle
[1513219578] ssid=glowyrectangle
[1513219579] ssid=glowyrectangle
I (13174) wifi: bcn_timout,ap_probe_send_start
[1513219580] ssid=glowyrectangle
[1513219581] ssid=glowyrectangle
[1513219582] ssid=glowyrectangle
I (15676) wifi: ap_probe_send over, resett wifi status to disassoc
I (15677) wifi: state: run -> init (1)
I (15678) wifi: pm stop, total sleep time: 0/9813809

I (15678) wifi: n:6 0, o:6 0, ap:255 255, sta:6 0, prof:1
[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:270] _eventCallback(): Reason: 200 - NO_AP_FOUND
W (16387) wifi: Haven't to connect to a suitable AP now!
[1513219583] ssid=
Attempting to reconnect...
Connection result: 5
[E][WiFiUdp.cpp:183] endPacket(): could not send data: 118
W (17412) wifi: Haven't to connect to a suitable AP now!
[1513219584] ssid=
Attempting to reconnect...
Connection result: 5
[E][WiFiUdp.cpp:183] endPacket(): could not send data: 118
W (18437) wifi: Haven't to connect to a suitable AP now!
[1513219585] ssid=
Attempting to reconnect...
Connection result: 5
[E][WiFiUdp.cpp:183] endPacket(): could not send data: 118
W (19462) wifi: Haven't to connect to a suitable AP now!
[1513219586] ssid=
Attempting to reconnect...
Connection result: 5

... ( loops like this indefinitely ) ...

ESP32,实验(B)具有断开连接(true)+ begin(ssid,passwd)

rst:0x10 (RTCWDT_RTC_RESET),boot:0x17 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0018,len:4
load:0x3fff001c,len:812
load:0x40078000,len:0
load:0x40078000,len:11404
entry 0x40078aa0
I (27) wifi: wifi firmware version: 708a055
I (28) wifi: config NVS flash: enabled
I (28) wifi: config nano formating: disabled
I (36) wifi: Init dynamic tx buffer num: 32
I (36) wifi: Init data frame dynamic rx buffer num: 64
I (36) wifi: Init management frame dynamic rx buffer num: 64
I (39) wifi: wifi driver task: 3ffd46d0, prio:23, stack:4096
I (45) wifi: Init static rx buffer num: 10
I (48) wifi: Init dynamic rx buffer num: 0
I (52) wifi: wifi power manager task: 0x3ffd940c prio: 21 stack: 2560
I (431) wifi: mode : sta (30:ae:a4:04:42:c8)
[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 2 - STA_START
I (2842) wifi: n:6 0, o:1 0, ap:255 255, sta:6 0, prof:1
I (2843) wifi: state: init -> auth (b0)
I (2847) wifi: state: auth -> assoc (0)
I (2863) wifi: state: assoc -> run (10)
I (2863) wifi: connected with glowyrectangle, channel 6
[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 4 - STA_CONNECTED
[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 7 - STA_GOT_IP
Setup completed
[1513219802] ssid=glowyrectangle
[1513219803] ssid=glowyrectangle
[1513219804] ssid=glowyrectangle
I (5863) wifi: pm start, type:0

[1513219805] ssid=glowyrectangle
[1513219806] ssid=glowyrectangle
[1513219807] ssid=glowyrectangle
[1513219808] ssid=glowyrectangle
[1513219809] ssid=glowyrectangle
[1513219810] ssid=glowyrectangle
[1513219811] ssid=glowyrectangle
[1513219812] ssid=glowyrectangle
[1513219813] ssid=glowyrectangle
[1513219814] ssid=glowyrectangle
[1513219815] ssid=glowyrectangle
[1513219816] ssid=glowyrectangle
I (17282) wifi: bcn_timout,ap_probe_send_start
[1513219817] ssid=glowyrectangle
[1513219818] ssid=glowyrectangle
[1513219819] ssid=glowyrectangle
I (19785) wifi: ap_probe_send over, resett wifi status to disassoc
I (19785) wifi: state: run -> init (1)
I (19786) wifi: pm stop, total sleep time: 0/13922305

I (19786) wifi: n:6 0, o:6 0, ap:255 255, sta:6 0, prof:1
[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:270] _eventCallback(): Reason: 200 - NO_AP_FOUND
W (20616) wifi: Haven't to connect to a suitable AP now!
[1513219820] ssid=
Attempting to reconnect...
I (20632) wifi: mode : null
I (20634) wifi: flush txq
I (20634) wifi: stop sw txq
I (20635) wifi: lmac stop hw txq
[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 3 - STA_STOP
I (20644) wifi: mode : sta (30:ae:a4:04:42:c8)
[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 2 - STA_START
[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 2 - STA_START
[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:270] _eventCallback(): Reason: 201 - AUTH_FAIL
Connection result: 1
[E][WiFiUdp.cpp:183] endPacket(): could not send data: 118
W (24182) wifi: Haven't to connect to a suitable AP now!
[1513219823] ssid=
Attempting to reconnect...
I (24254) wifi: mode : null
I (24256) wifi: flush txq
I (24257) wifi: stop sw txq
I (24257) wifi: lmac stop hw txq
I (24266) wifi: mode : sta (30:ae:a4:04:42:c8)
[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 3 - STA_STOP
[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 2 - STA_START
[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 2 - STA_START
[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:270] _eventCallback(): Reason: 201 - AUTH_FAIL
Connection result: 1
[E][WiFiUdp.cpp:183] endPacket(): could not send data: 118
W (27804) wifi: Haven't to connect to a suitable AP now!
[1513219827] ssid=
Attempting to reconnect...
I (27820) wifi: mode : null
I (27822) wifi: flush txq
I (27822) wifi: stop sw txq
I (27822) wifi: lmac stop hw txq
[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 3 - STA_STOP
I (27832) wifi: mode : sta (30:ae:a4:04:42:c8)
[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 2 - STA_START
[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 2 - STA_START
I (30311) wifi: n:6 0, o:1 0, ap:255 255, sta:6 0, prof:1
I (30312) wifi: state: init -> auth (b0)
I (30318) wifi: state: auth -> assoc (0)
I (30339) wifi: state: assoc -> run (10)
I (30340) wifi: connected with glowyrectangle, channel 6
[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 4 - STA_CONNECTED
[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 7 - STA_GOT_IP
Connection result: 3
[1513219831] ssid=glowyrectangle
[1513219832] ssid=glowyrectangle
I (33340) wifi: pm start, type:0

[1513219833] ssid=glowyrectangle
[1513219834] ssid=glowyrectangle
[1513219835] ssid=glowyrectangle
[1513219835] ssid=glowyrectangle
[1513219836] ssid=glowyrectangle

包起来

我已经在SDK中进行了一些挖掘,但是看不到任何明显的东西。 我可能会说一点儿,但希望以上信息对您有所帮助。 如果还有其他我可以提供的信息,请告诉我; 我很乐意履行义务。

我尝试在监视模式下获取一些pcap,但是它们并不是很有趣。 似乎断开连接后,ESP32没有发送任何内容。

我很高兴至少找到了一种解决方法(disconnect(true)+ begin(ssid,passwd))。

@vseven @Markusenz @sidoh
抱歉稍后回复,感谢您在SDK上的辛勤工作。
附件是wifi lib的调试版本,您可以使用它进行测试,然后我们可以分析您的日志以解决问题。
wifi_lib.tar.gz

@igrr-我尝试过以相同的结果进行开放和安全。 我可以尝试为您捕获数据包,但是问题是非常随机的,它可以在一小时内进行4次,或一天两次,因此捕获可能非常麻烦。 现在,多个人遇到了同样的问题,但是我将尝试@zhangyanjiaoesp发布的调试版本,如果仍然

自动重新连接是否可以按预期工作? 听起来@sidoh可以解决这个问题,但我不太幸运。 只有重新启动似乎可以解决这些断开循环。

这个周末我会重新编译并加载它。

编辑:wifi_lib.tar.gz文件为空。 你可以转贴吗?

我认为我注意到的最有趣的事情是:

WiFi.disconnect(true);
WiFi.begin(SSID, PASSWORD);

总是最终对我重新连接( true参数到disconnect很重要)。 我认为WiFi.disconnect(true)关闭收音机。 我的猜测是,在某些情况下,ESP32应该连接到的网络状态会被清除,上面的操作会将其重置。

同样有趣的是,通过关闭wifi网络,等待ESP32注意到它已断开连接并重新打开网络,该问题似乎可以100%重现。 如果网络在ESP32发出通知之前重新出现,则有时可以成功重新连接。 从日志来看,差异似乎是在前一种情况下触发了NO_AP_FOUND事件,而在后一种情况下未触发。

重新运行与调试库链接的代码。 记录在这里:

这些全都在开放的网络上。

编辑-链接到原始日志,而不是要点页面。

@zhangyanjiaoesp-有什么新闻吗? 我没有尝试过调试代码,因为@sidoh已经这样做了,并且已经提供了很多日志,但是

@sidoh
slow_ap_recreate.log ,我们发现有类似

[1513308152] ssid =
正在尝试重新连接...

看来您的ssid为空,因此在扫描所有频道后,找不到返回的ap。
因此,您应该检查代码以查看ssid设置是否正确。
screenshot from 2018-01-04 17-55-20

@zhangyanjiaoesp

我认为这可能是问题的关键。 在slow_ap_recreate.log ,重新连接代码正在执行(此处为完整草图):

WiFi.begin();

因此它不提供AP。 我对SDK的理解是,它应该仅重新连接到最后一个已知的AP。 也许如果找不到最后使用的SSID,就清除配置吗? 那是预期的吗?

使用此方法似乎总是可行的:

WiFi.disconnect(true);
WiFi.begin(ssid, passwd);

编辑-为了确保设置清晰,重新连接不起作用的情况是AP消失了足够长的时间,以便SDK决定它已经消失了。 不过,也许这是预期的行为。

@sidoh是的,你是对的。 这是预期的行为,可以通过以下方法解决此问题:

WiFi.disconnect(true);
WiFi.begin(ssid,passwd);

我知道,这很有意义。 在接下来的几天中,我将尝试在没有WiFi.begin()的情况下进行复制。 认为正确的事情是让SDK处理重新连接。

SDK在哪里处理重新连接? 我只能在这里找到参考,它似乎使用WiFi.begin() 。 那是预期的吗?

是的,你是对的

这是否意味着处理重新连接的SDK代码会遇到与演示相同的问题? 如果在AP消失后尝试重新连接,SSID将被清除,除非重新提供AP信息,否则它将无法重新连接?

明确地,SDK应该尝试自动重新连接。 这就是拥有WiFi.setAutoReconnect(true)的全部意义。

@everslick-我完全同意,它似乎不起作用,这就是为什么我在3个月前最初发布此内容。 WiFi.setAutoReconnect(true)似乎没有使其重新连接,这至少可以说是具有讽刺意味的。 唯一有效的方法是重新启动控制器,并使其通过正常连接返回(当控制LED熄灭时,这对我不起作用)或完全断开并重新连接。

@zhangyanjiaoesp-所以您说的是WiFi.setAutoReconnect(true)根本行不通? 要变通,我们必须调用断开连接,然后再次使用SSID和密码重新连接? 如果是这样,它将得到修复还是至少更新了文档以使其不起作用?

我有个类似的问题,
使用以下顺序通过软件复位后:
WiFi.disconnect(); //确保清除当前的ssid /密码
延迟(1000);
ESP.restart();
ESP重新启动,但直到硬件复位后才连接到AP。
Wifi.disconnect()函数也无法正常工作。
罗伯特

困难的方法是将GPIO引脚连接到EN,并在需要重新启动/重启或wifi(重新)连接的情况下强制系统复位(GPIO低)。

不要断开连接。 只是重新启动对我有效。 但是同样,如果WiFi.setAutoReconnect(true)正常工作,则不必重新启动。

Wifi.disconnect或autoreconnect正常工作应该很好,但是有什么要点,如果存在Wifi连接问题,这是ESP32的主要问题(所有后续应用程序可能都依赖Wifi),因此最终的解决方案如果此操作失败,请尝试进行硬件重置...再见ESP32使用。

重新启动不是解决方案。 我将其用于RGB LED控制,并且重新启动会将灯重置为熄灭。 如果有一个告诉ESP的功能,如果它失去了Wi-Fi,则应继续尝试重新连接,然后该功能应按文档所述实际运行。

好的,我试图通过GPIO重置ESP,但看起来ESP不喜欢自杀,因此如果没有外部设备,它就无法工作。 因此,我同意剩下的唯一解决方案是WiFi断开连接,ESP重新启动或Wifi自动重新连接实际上正在运行。
我们必须等待功能性ESP模块的另一个问题(我注意到,据我所能测试的那样,I2C协议是我正在等待解决方案的另一个问题)。
到目前为止,ESP32还是不可靠的....
罗伯特

而且我没有提到SPI接口...

esp_restart_noos();

对于ESP.restart()无法正常工作的情况。

我正在使用Arduino IDE来配置WeMos Lolin32。
我使用的功能:

void unitReset ()
 {
#ifdef DEBUGGING
  Serial.println ("Coordinator will REBOOT NOW ....");
#endif    
  WiFi.disconnect();                          //Ensure current  ssid/password is erased
  delay (1000);
  ESP.restart();
 }

当WeMos以WiFi.mode(WIFI_STA)连接时,我从MQTT调用此函数。
实际上,它会重新启动系统并启动草图,但是Wifi(无法从该点同步,连接尝试将陷入无限循环)。 手动重置即可解决。
但是,可以通过telnet从WiFi.mode(WIFI_STA)调用的相同功能起作用。

@vseven @everslick @rrobinet
您误解了函数WiFi.setAutoReconnect(true)的含义。
在我们的代码中, WiFi.setAutoReconnect(true)并不意味着会自动重新连接wifi。 这意味着如果ESP32之前已经连接过wifi,那么当系统下次重启时,它将连接最后连接的wifi。
因此,我们将在代码中添加一些注释。 抱歉影响到您的工作。

@zhangyanjiaoesp很抱歉这么说:那只是“错误”。 该API是为ESP8266引入的,它确实做到了:自动重新连接wifi。 您所描述的是WiFi.setAutoConnect(); 方法是。 您不能随意更改完善的API的语义。

此外,即使API像您所说的那样工作,函数命名也将是令人难以置信的错误和误导。

无论如何。 我们在这里谈论物联网设备。 默认设置是无论如何都保持与网络的连接。 如果有的话,应该有一些功能来禁用自动重新连接,并且不要求API用户跳过箍以使其具有这种行为。

@vseven @everslick @rrobinet
请在此处查看,它告诉用户此功能在开机时有效。

ESP.restart问题,更正。
上面的脚本可以在ESP8266上运行,而不是在ESP32上运行,但是经过一些测试,问题是在ESP.restart()之前使用了WiFi.disconnect(true)。 ESP32的此功能应放在Wifi初始化处(请参阅https://github.com/espressif/arduino-esp32/pull/466)
就像是:

<snip>
  WiFi.disconnect(true);                                      // Clear Wifi Credentials
  WiFi.persistent(false);                                     // Avoid to store Wifi configuration in Flash
  WiFi.mode(WIFI_STA);                                        // Ensure WiFi mode is Station 
  Serial.println("Now Connecting to Access Point ...");  
  // Connect to the Access Point
  WiFi.begin(ssid,key);
<snip>

并且单位重置应该简单地是:

void unitReset ()
 {
#ifdef DEBUGGING
  Serial.println ("Coordinator will REBOOT NOW ....");
#endif    
  delay (1000);
  ESP.restart();
 }

您是否可以确认以下内容?到目前为止,我在阅读此线程时已了解以下内容:

  • ESP32的行为与ESP8266不同,因此使用ESP32时,如果AP丢失或无法访问一段时间,WiFi不会自动重新连接。 用户必须检测到wifi丢失并在其代码中处理重新连接(如果不重新启动设备,则无法实现?)
  • ESP32的行为与ESP8266不同,因为启动后,有时ESP32不连接到AP。 我们需要某些代码行对其进行修复,例如此处https://github.com/espressif/arduino-esp32/issues/653#issuecomment -356534618
  • 所描述的问题被视为预期的行为,并不旨在更改api中的行为,因此在使用ESP32时,我们必须相应地调整代码

@Markusenz ,我可以确认https://github.com/espressif/arduino-esp32/issues/653#issuecomment -355659659似乎总是对我有用。 似乎对getAutoReconnect的唯一引用是我粘贴在注释中的链接,即使所有这些链接也无法很好地处理断开连接。

@zhangyanjiaoesp ,感谢您的帮助。 :)

您误解了WiFi.setAutoReconnect(true)函数的含义。
在我们的代码中,WiFi.setAutoReconnect(true)并不意味着自动重新连接wifi。 这意味着如果ESP32之前已经连接过wifi,那么当系统下次重启时,它将连接最后连接的wifi。

链接到的方法是setAutoConnect ,而不是setAutoReconnect 。 我认为这些方法是不同的。 setAutoReconnect这里。 它只是设置一个标志,我认为使用标志的唯一位置是在这里

给定方法的名称以及该标志在内部的使用方式后,似乎该方法应该按照人们的设想进行—启用/禁用断开连接后自动尝试重新连接到AP。

我的想法是,此功能无法按预期方式工作,我认为这可能是因为SDK在内部使用了WiFi.begin() ,如果保存的AP不存在,该功能将清除SSID,如上所述。

因此,这似乎正在发生。 如果无法立即看到SDK,可以将其更新为不清除AP吗? 还是做一个WiFi。如果WiFi.setAutoReconnect(true)开始使用最后一个已知的SSID和密码,还是我错过了什么?

如果我的想法/挖掘是正确的,我真的怀疑这种行为是故意的还是预期的。 setAutoReconnect似乎应该具有该线程中人们所期望的功能,并且只包含一些错误。

我的建议是暂时解决它。 在我自己的项目中,我只是附加了一个事件处理程序

WiFi.disconnect(true);
WiFi.begin(ssid, passwd);

它对我有用。

似乎重新连接目前正在由Arduino SDK处理,而不是由底层处理。 使用ESP8266 Arduino SDK,重新连接由Non-OS SDK处理。 因此,ESP32 Arduino SDK的修复程序看起来很像是这种外部解决方法(再次,假设我的想法是正确的。我肯定是错的)。

编辑-是我的代码中处理重新连接的相关部分。

@Markusenz
你是对的。
@vseven @sidoh
我同意@sidoh ,您可以

经过一番挖掘后,我发现它可以很好地工作:

static bool sta_was_connected = false;

static void poll_connection(void) {                                         
#ifdef ESP32
  // this is a crude workaround due to the inability of
  // the ESP32 to reconnect to an accesspoint automatically.
  //
  // https://github.com/espressif/arduino-esp32/issues/653

  static uint32_t ms = millis();

  if (!WiFi.isConnected() && (millis() - ms) > 1000 * 5) {
    ms = millis();

    if (sta_was_connected) WiFi.reconnect(); else WiFi.begin();
  }
#endif
}

loop() {
  poll_connection();
}

在SYSTEM_EVENT_STA_GOT_IP的WiFi事件处理程序中,您必须将sta_was_connected设置为true。

当ESP32引导时接入点不可用时,这也将起作用。

好处是,它不会清除STA配置。 如果您设置了静态IP配置(不使用DHCP),这将特别有用。

你得到一个
[D][WiFiGeneric.cpp:293] _eventCallback(): Event: 8 - STA_LOST_IP
如果您等待足够长的时间(会有延迟)

我要尝试

    } else if(event->event_id == SYSTEM_EVENT_STA_LOST_IP) {
        if(WiFi.getAutoReconnect()){
            WiFi.begin();
        }

这是一个有效的解决方案,可绕过WiFi库的一些问题。
注意while在WiFi.begin()之后循环。
我发现连接延迟取决于路由器和加密设置,AES,WPA2似乎是最好,最快和最可靠的。

为此,请等到您知道连接正常为止,但要确保不锁定,几乎可以做到。

我注意到有人在叫WiFi.disconnect()。 注意使用WiFi.persistent(false); 使用它或每次恢复时,您都将重新写入NV FLASH,并在FLASH死后将其变为砖状。

部分代码样本

setup()
{
  WiFi.begin( rssiSSID , password );

  int WLcount = 0;
  while (WiFi.status() != WL_CONNECTED && WLcount < 250 ) 
  {
    delay( 100 );
    #ifdef DEBUG
       Serial.print(".");
    #endif
    ++WLcount;
  }
}

void loop() 
{
  if (WiFi.status() ==  WL_CONNECTED) 
  {
    // PUT_YOUR_UP_TIME_CODE_HERE   

    #ifdef DEBUG
       Serial.print("C");
       if (UpCount >= 20)   // just keep terminal from scrolling sideways
       {
        UpCount = 0;
        Serial.println();
       }
       ++UpCount;
    #endif

      // END WiFi connected loop()
  } else
  {
    // PUT_YOUR_DOWN_TIME_CODE_HERE
    //  WiFi DOWN loop

    #ifdef DEBUG
        WFstatus = getWifiStatus( WFstatus );
    #endif

    WiFi.begin( rssiSSID , password );
    int WLcount = 0;
    // loop - depending on router, connect can be from 4 - 20 seconds
    // usually longer to reconnect than the connect at boot
    // lopping till reconnect seems to let it settle
    // usually around 80 count to breakout
    while (WiFi.status() != WL_CONNECTED && WLcount < 250 ) 
    {
        delay( 100 );
        #ifdef DEBUG  
            Serial.print(".");
            // just keep terminal from scrolling sideways in test
            if (UpCount >= 20)
            {
                UpCount = 0;
                Serial.println();
            }
            ++UpCount;
        #endif
        ++WLcount;
    }
    delay( 1000 );
  }  // END WiFi DOWN 
} // END loop()


int getWifiStatus( int WiFiStatus  )
{
  WiFiStatus = WiFi.status();
  Serial.print("\tStatus "); Serial.print( WiFiStatus );
  switch( WiFiStatus )
     {
        case WL_IDLE_STATUS :           // WL_IDLE_STATUS     = 0, 
                Serial.println(", WiFi IDLE "); 
                break;
        case WL_NO_SSID_AVAIL:          // WL_NO_SSID_AVAIL   = 1,
                Serial.println(", NO SSID AVAIL ");
                break;
        case WL_SCAN_COMPLETED:         // WL_SCAN_COMPLETED  = 2,
                Serial.println(", WiFi SCAN_COMPLETED "); 
                break;
        case WL_CONNECTED:      // WL_CONNECTED       = 3,
                Serial.println(", WiFi CONNECTED "); 
                WiFi.persistent(true);  
                break;
        case WL_CONNECT_FAILED:         // WL_CONNECT_FAILED  = 4,
                Serial.println(", WiFi WL_CONNECT FAILED"); 
                break;
        case WL_CONNECTION_LOST:        // WL_CONNECTION_LOST = 5,
                Serial.println(", WiFi CONNECTION LOST");
                WiFi.persistent(false); // don't keep writing FLASH
                break;   
        case WL_DISCONNECTED:            // WL_DISCONNECTED    = 6
                Serial.println(", WiFi DISCONNECTED ==");
                break;
  }
  return WiFiStatus;
}  // END getWifiStatus()

======
平均需要8-15秒才能检测到模式变化
注意“。”的连接
“ C”已连接

OUTPUT
CCCCCCCCC     Status 5, WiFi CONNECTION LOST    Unplugged Router here
.........
....................                            Trying
 More lines of dots...
....................
...........       Status 1, NO SSID AVAIL       Gave up, Changed Modes
.........                                       Replugged Router here
....................
................CCCC                            TaDa I'm Back...
CCCCCCCCCCCCCCCCCCCC

我正在使用它,似乎为我工作

void WiFiEvent(WiFiEvent_t event){
    if(event == SYSTEM_EVENT_STA_DISCONNECTED){
      Serial.println("Event: SYSTEM_EVENT_STA_DISCONNECTED, reconnecting");
      WiFi.reconnect();
    }
}

if(WiFi.getAutoReconnect()) WiFi.onEvent(WiFiEvent);

我猜我附近有50个AP的公寓确实是测试此问题的好地方。 来自tablatronix的解决方案导致我的esp32转储,并且我看不到mickeypop的解决方案将如何发挥作用,但这没有帮助。 我发现重新启动wifi连接效果很好,但即使这样也需要不时地进行一次硬电源重置。 一方面,我在一个不需要任何人工干预的环境中使用了esp8266。 我在这里尝试了其他一些建议,但没有走运。

我认为所有开发工作都令人赞叹。 坦白说,我没有技巧来提出解决方案。 如果有人想在恶劣的环境中尝试某些东西,请随时向我发送测试。 我们确实需要esp32建立牢固的连接并优雅地处理间歇性wifi。

编辑:尝试了很多东西之后: @tablatronix如果我
if(WiFi.getAutoReconnect()) WiFi.onEvent(WiFiEvent);
Edit2:持续30分钟才下车

@thefatmoop我遇到了WiFi重新连接问题,最终成为NVS损坏问题。 #1147我重写了草图以转储nvs数据。 尝试一下并捕获输出。 它可能显示一些东西。
显示NVS密钥

查克

胖子

两种解决方案都应该起作用。
正如我所说的; “ __这是一种有效的解决方案,可绕过WiFi库的某些问题。_”

虽然一个绕过某些库问题,另一个绕过WiFi.onEvent()服务,但两者都仅检测连接断开的时间并重新启动新连接。

尽管有些人注意到几个小时后它们一直在颠簸,但这几乎可以肯定是路由器中DHCP服务器租用时间的函数。

如果路由器的租用时间不同,则有时设备“忘记”更新,即使没有WiFi连接,该设备也会导致没有IP地址。

  • WiFi.begin()强制DHCP获取新IP和新连接。
  • WiFi.reconnect()可以工作,但通常会假定该设备仍然具有IP,并且可能不执行DHCP请求。

解决此问题的简单方法是定期对DHCP路由器执行Ping操作。
这迫使路由器知道您仍在网络上并保持最新租约。

重新引导可能会重新连接,但不能解决断开连接的原因,如果您只是重新引导,应用程序通常可能会不同步。

因此,重新连接而不重新引导通常是必要的。

重新连接不会重做dhcp,我在尝试更改主机名并重新连接时发现了这一点,将其记录为错误。

@tablatronix的解决方案对我@thefatmoop可以检查OpenMQTTGateway.ino代码上的实现。

在MQTT断开连接之后,将调用该代码,如果我将代码放在此条件之外,则实际上是ESP转储。

如果WiFi.reconnect()重新连接,但MQTT客户端没有重新连接,则可以在尝试几次客户端重新连接后再创建一个setup_wifi() :带有connector()delay()和begin(),并且在新客户端中效果很好连接。 但是,当MQTT服务器关闭时会发生什么?

多数民众赞成在应用程序级别的问题..

Wiki添加了mickeypop代码建议

抱歉。 我是arduino / esp编程的初学者。 我还面临着wifi连接和重新连接的错误/问题。 我的代码部分同时管理WiFi和MQTT客户端(PubSubClient),并且实际上可以在Adafruit / Huzzah32的ESP32上运行:

void setupWiFi() {
  WiFi.disconnect(true);
  WiFi.begin(WLAN_SSID, WLAN_PASS);
  WiFi.waitForConnectResult();
}

boolean clientReconnect() {
  if(client.connect("esp32_client")) {
    client.subscribe("/test");
  }
  return client.connected();
}

boolean wifi_connected_once = false;
unsigned long last_client_reconnect_attempt = 0;
int client_reconnect_attempts = 0;

void setup() {  
  client.setServer(MQTT_SERVER, 1883);
  client.setCallback(client_callback);
}

void loop() {
  unsigned long loop_start = millis();

  if(WiFi.isConnected()) {
    // WiFi connected
    if(client.connected()) {
      // client connected
      // publish data every 5 seconds
      if(loop_start - last_client_publish >= 5000) {
        client_publish_data();
        last_client_publish = loop_start;
      }
      client.loop();
    } else {
      // client not connected
      // try reconnect a few times every 5 seconds
      if(client_reconnect_attempts <= 5) {
        if(loop_start - last_client_reconnect_attempt > 5000) {
          client_reconnect_attempts++;
          if(clientReconnect()) {
            // client connected
            client_reconnect_attempts = 0;
          }
          last_client_reconnect_attempt = loop_start;
        }
      } else {
        // maybe MQTT server is down
        // try reconnect in 5 minutes
        if(loop_start - last_client_reconnect_attempt > 300000) {
          last_client_reconnect_attempt = loop_start;
          client_reconnect_attempts = 0;
        }
      }
    }
  } else {
    // WiFi not connected
    // try connect for the first time or 
    // try reconnect every 2 minutes
    if((loop_start - last_client_reconnect_attempt > 120000) || wifi_connected_once == false) {
      last_client_reconnect_attempt = loop_start;
      wifi_connected_once = true;
      client_reconnect_attempts = 0;
      setupWiFi();
    }
  }
}

经过一些路由器重启测试,该代码似乎无需重启ESP就可以正常工作。
您有更好的建议吗?

这个问题使我丧命。 有时会在第一个小时内随机发生,有时会在六个小时后随机运行,而没有任何问题。 我已经尝试了各种配置,但没有一个是可靠的。 通过软件或硬件重新启动ESP是实际可行的最后手段,但这对我的产品而言不是可行的解决方案。

上次我让它继续运行并尝试了四千多次尝试,但都没有成功。

到目前为止,我已经尝试过:

1)启用自动重新连接并调用重新连接
2)禁用自动重新连接,然后手动断开并重新连接。 在此配置中,我尝试了两种完全关闭天线的方法。 在任何模式下均不起作用。

这里有一些日志(实际上正在运行,尝试在运行良好的路由器(TP-LINK)上进行600多次重新连接:

警告:WiFi失去连接。 在下一次迭代时尝试重新连接尝试632
触发WiFi重新连接尝试632
我(14944038)wifi:模式:softAP(30:ae:a4:1a:ca:1d)
使用SSID'Nano BAB-Development'和密码'#######'创建WiFi
连接到WiFi'TP-LINK_A8FB38'
[D] [WiFiGeneric。 cpp:293 ] _eventCallback():事件:3-STA_STOP
[D] [WiFiGeneric。 cpp:293 ] _eventCallback():事件:2-STA_START
[WiFi事件]事件:2
[D] [WiFiGeneric。 cpp:293 ] _eventCallback():事件:5-STA_DISCONNECTED
[W] [WiFiGeneric。

如您所见,认证失败,但是密码正确。 在同一示例的先前尝试(编号578 !!)上,出现错误2:

警告:WiFi失去连接。 在下一次迭代中尝试重新连接尝试578
触发WiFi重新连接尝试578
我(14134199)wifi:模式:softAP(30:ae:a4:1a:ca:1d)
使用SSID'Nano BAB-Development'和密码'########'创建WiFi
[D] [WiFiGeneric。 cpp:293 ] _eventCallback():事件:3-STA_STOP
[WiFi事件]事件:3
连接到WiFi'TP-LINK_A8FB38'
[D] [WiFiGeneric。 cpp:293 ] _eventCallback():事件:13-AP_START
[WiFi事件]事件:13I(14134890)wifi:模式:sta(30:ae:a4:1a:ca:1c)+ softAP(30:ae:a4:1a:ca:1d)
[D] [WiFiGeneric。 cpp:293 ] _eventCallback():事件:2-STA_START *

[WiFi事件]事件:2 [D] [WiFiGeneric.cpp:293] _eventCallback():事件:2-STA_START
[WiFi事件]事件:2I(14137748)wifi:ap频道调整o:1,1 n:6,1
我(14137749)wifi:n:6 1,o:1 0,ap:6 1,sta:6 1,prof:1
我(14138422)wifi:状态:初始化->身份验证(b0)
我(14139423)wifi:状态:身份验证->初始化(2)
我(14139424)wifi:n:6 0,o:6 1,ap:6 1, sta:6 1, prof:6
[D] [WiFiGeneric。 cpp:293 ] _eventCallback():事件:5-STA_DISCONNECTED
[W] [WiFiGeneric。

它始终是两个错误之一。 最后只是它没有重新连接。

有趣的是,我可以通过拉动电源线几分钟来手动断开路由器的连接,我的代码检测到断开连接并开始重试,然后我的系统重新插回时就可以正常连接,但是,如果路由器正常工作,则最终会发生此问题,并且ESP根本不会重新连接。

顺便说一句,我正在与:

在SDK上运行:“ v3.1-dev-239-g1c3dd23f-dirty”
CPU频率:240MHz
WiFi既可以创建自己的私人WiFi,又可以连接到另一个可以访问互联网的WiFi

您上次退出回购协议是什么时候?

1132

您只发布日志,没有草图或重新连接解决方​​案。

上一次大约是一周左右。 我的SDK版本是3.1-dev-239。
抱歉,我没有添加代码,因为我基本上测试了帖子中的所有解决方案。 在启动时,我称呼类似:

WiFi.disconnect(true);
WiFi.softAP(wifiName, wifiPassword);
WiFi.begin(connectoToWifiSSID, connectToWifiPassword);

然后,我处理WiFi事件,尤其是事件SYSTEM_EVENT_STA_DISCONNECTED 。 发生此事件时,我尝试了3种不同的重新连接方式:

1)启用Wifi自动重新连接后,我离开了系统以自行处理重新连接
2)我尝试通过禁用自动重新连接并在该事件上调用WiFi.reconnect()
3)我最近尝试的一种方法是通过关闭无线电并在没有其他断开触发的情况下再次连接来断开连接。 我有类似的东西:

reconnections++;
needsReconnection = true;
reconnectionDetection = millis();
Serial.printf("\r\nWARNING: WiFi lost connection. Trying reconnection attempt %d on next iteration\r\n", reconnections);

needsReconnection是一个在主循环中检查的标志,并通过基本运行

希望现在有意义;-)

不知道是否还有另一种方法。

我忘了提一下,我在运行猫鼬服务器时也无法实现Rest API,最多允许3个并发连接。 不知道这是否可能是它的原因。

  1. 没有自动重新连接,这就是此问题的目的。
  2. WiFi.reconnect可能与断开连接,begin()(dhcp等)不同
  3. 这可能是特定于模式的,没有代码,没人知道您在做什么,不知道您如何处理事件,或者“关闭无线电”

我建议进行更改并制作一个简单的测试用例。

约斯蒙帕夫

您的问题可能是WiFi模式的

您的代码

WiFi.softAP(wifiName, wifiPassword);
WiFi.begin(connectoToWifiSSID, connectToWifiPassword);

您正在运行混合模式。
WiFi.softAP() ; 默认为WIFI_MODE_AP模式

WiFi.begin(); 默认为WIFI_AP_STA模式

如果您继续使用WIFI_MODE_APSTA模式(混合模式),则不应更改它们,WiFi EVENT也不会与其他模式混淆。

WiFi.mode( WIFI_MODE_APSTA );
WiFi.softAP(wifiName, wifiPassword);
WiFi.begin(connectoToWifiSSID, connectToWifiPassword);

参考信息
在esp_wifi_types.h中

typedef enum {
    WIFI_MODE_NULL = 0,  /**< null mode */
    WIFI_MODE_STA,       /**< WiFi station mode */
    WIFI_MODE_AP,        /**< WiFi soft-AP mode */
    WIFI_MODE_APSTA,     /**< WiFi station + soft-AP mode */
    WIFI_MODE_MAX
} wifi_mode_t;

在wifitypes.h中

typedef enum {
    WL_NO_SHIELD        = 255,   // for compatibility with WiFi Shield library
    WL_IDLE_STATUS      = 0,
    WL_NO_SSID_AVAIL    = 1,
    WL_SCAN_COMPLETED   = 2,
    WL_CONNECTED        = 3,
    WL_CONNECT_FAILED   = 4,
    WL_CONNECTION_LOST  = 5,
    WL_DISCONNECTED     = 6
} wl_status_t;

嗨, mickeypop

我正在测试您的解决方案:


WiFi.mode( WIFI_MODE_APSTA );
WiFi.softAP(wifiName, wifiPassword);
WiFi.begin(connectoToWifiSSID, connectToWifiPassword);

事件SYSTEM_EVENT_STA_DISCONNECTED发生时,我正在呼叫WiFi.reconnect() ,我尝试通过手动断开路由器的连接来进行尝试,并且似乎可以正常工作(之前也可以工作)。

到目前为止,它已经在7个晚上不间断运行了2个不同的ESP32。 我一直每5秒钟对它们执行一次ping操作,到目前为止没有任何问题。 无法想象混合模式声明可能是原因,我认为在调用WiFi.beginWiFi.softAP()时会自动启用它。 手指交叉。 我现在将开始进行更严格的测试,以确认这是我所面临问题的解决方案。

顺便说一句,谢谢你!

@mickeypop @josmunpav感谢您分享您的发现。
我已将其添加到Wiki

如果事先设置模式更改了结果,则这表示没有意义enableta或enablesoftap中的错误。 这就是为什么我建议这是特定于模式的原因,不需要解决方法。 所以复制代码会很好

@everslick在上面明确指出了很多这样的含义: https

为什么没有自动重新连接的称为“ autoReconnect”的东西令人困惑。 每个人似乎都在编写自己的代码来克服此缺点/错误。 我将按照@tablatronix的建议刷写,但这的重点是我们不必做任何此类事情....它应该像ESP8266一样工作并自行重新连接!

我个人仍然遇到芯片完全进入此断开循环时完全锁定的问题。 我将其计数为10并重新启动,但是随机地(15个左右的重新启动中的1个)它不会重新启动,而只是硬锁,需要冷重启。 如果它具有更好/更多的模拟输入,我会心跳切换到ESP8266,但不幸的是没有。 ESP32也不擅长于此(https://www.esp32.com/viewtopic.php?f=19&t=2881)。

在esp8266中,自动重连是在SDK中实现的,在esp32中没有实现,因此将其添加到库中以带来某种形式的兼容性,尽管它仅针对WIFI_REASON_AUTH_EXPIRE

它可以实现,但需要解决,并且该库仍然是alpha库,因此确实没有期望,SDK可能会更改,整个事件系统可能会更改。 因此,实现此类核心功能需要花费时间。

更不用说,如果espressif在SDK中实现了这一点,那么我们就浪费了所有时间。

当我说需要解决时,我的意思是有几个悬而未决的问题需要解决。 这就是为什么我要为上述事件解决方案失败的人提供测试草图的原因。

  • 重新连接,可能会丢失dhcp分配,而不是断开连接(),开始()**
  • 自动连接导致错误的wl_status发出并无限循环
  • sdk在某些路由器上为auth_fail发出auth_expire,上面的触发器
  • esp_wifi_set_mode是异步的,竞争条件
  • 自动连接甚至不起作用, https://github.com/espressif/arduino-esp32/issues/173

** reconnect does not enablesta, it just returns false, you should always be checking for return values!

如果使用上面的解决方法,建议禁用自动重新连接以避免其中两个错误。

大家好,我提供了一个样本,该样本重现了我所面临的问题。 该示例充满了评论,但基本上包括:

  1. 两个任务:主要任务和Web / wifi(由mongoose 6.11库实现)
  2. 一些共享对象可以执行虚拟任务,例如在引脚上设置PWM,读取ADC平均值和共享的int计数器
  3. 您可以在http:// your_esp32_ip /上的测试页上保持它的运行状态,并在断开连接时通知您。 它还显示了正在执行的虚拟任务的值
  4. 避免任务之间的数据损坏的信号灯。 主要任务是改变pwm引脚,从ADC读取并增加计数器。 Web任务将数据显示在主页上。
  5. 连接,断开连接和处理WiFi事件的典型WiFi方法。
  6. 它以APSTA模式运行,因此您需要配置自己的WiFi(由于主页使用CDN中的jQuery进行示例中的ESP32的API调用,因此您的WiFi需要互联网连接)

到目前为止,我发现如果禁用虚拟任务(有一个标志),则两个任务都会无休止地运行。 如果启用它们,则ESP32最终会(有时可能要花几个小时,但通常会在第一个小时内发生),从WiFi断开连接,无法重新连接,每10秒运行一次连接尝试,但一直没有成功。

我认为ADC或PWM库之间存在一些干扰(由esp32-hal-ledc.h实现),因为当主要任务除了做虚拟等待外什么都不做时,我无法重现该问题。

我注意到的另一件事是,当断开连接发生时,用于AP的WiFi信号下降了很多。 我在智能手机上检查了一下。

这是您失败时可以找到的典型WiFi日志消息:

[WiFi-event] event: 5
Disconnected from WiFi. Trying connection again in 10000ms
Web/Main Task is up and running. Shared counter is 11309, Average ADC Value = 1305.000000, PWM Value = 0
Connecting to WiFi 'TP-LINK_A8FB38' with password: 'C1A8FB38' on connection attempt = 108
Oops, there was a problem when connecting. It returned error: 1[D][WiFiGeneric.cpp:293] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:298] _eventCallback(): Reason: 2 - AUTH_EXPIRE

请找到随附的源代码和示例页面:

working
not_working

ESP32_APSTA_Mode_Disconnection_Test.zip

PS:我的真实应用程序也做同样的事情。 从两项任务开始APSTA模式,一项任务是更新传感器,设备和GPIOS,另一项任务是处理由猫鼬实现的WiFi和Web服务器,并且面临同样的问题。

我建立了这个草图来测试连接,每10秒获取时间10次,断开wifi,重新连接wifi。 似乎工作得很好,所以我在其他代码中实施了几天,因为我遇到了重新连接问题。

#include <WiFi.h>
#include "time.h"

const char* ssid       = "ssid1";
const char* password   = "password1";

const char* ntpServer = "pool.ntp.org";
const long  gmtOffset_sec = 3600;
const int   daylightOffset_sec = 3600;

byte wfConnectTry = 0;
byte loopCnt = 0;

void printLocalTime()
{
  struct tm timeinfo;
  if (!getLocalTime(&timeinfo)) {
    Serial.println("Failed to obtain time");
    return;
  }
  Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
}

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

  //connect to WiFi
  Serial.printf("Connecting to %s ", ssid);
  //WiFi.begin(ssid, password);
  wifiStart();
  //init and get the time
  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
  if (WiFi.status() == WL_CONNECTED) {
    printLocalTime();
  }

}

void loop()
{
  delay(10000);
  printLocalTime();
  while (WiFi.status() != WL_CONNECTED || wfConnectTry >=5) {
    wfConnectTry++;
    wifiReconnect();

  }
  if (loopCnt >= 10){
    wifiReconnect();
  }
  loopCnt++;
}

void wifiReconnect()
{
  Serial.println(F("Disconnecting"));
  WiFi.disconnect(true);
  delay(500);
  Serial.println(F("Starting WiFi!"));
  wifiStart();
  loopCnt = 0;
}

void wifiStart()
{
  unsigned long timer1 = millis();
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED && millis() - timer1 < 5000UL) {
    delay(500);
    Serial.print(".");
  }
  if (WiFi.status() == WL_CONNECTED) {
    Serial.println(F(" CONNECTED"));
    wfConnectTry = 0;
  }
  else {
    Serial.println(F("Could not connect!"));
  }
}

....感谢代码提示@tablatronix

在amd之后使用代码围栏三行换行符

这是一条有趣的信息。 我尝试了此线程中提到的所有技巧,但没有任何效果。 但是,每次我安装和运行SimpleWiFiServer时

我的应用程序可以很好地连接到WiFi,在某些时候(几天或几周)它失去了连接,没有任何连接可以使它连接。 我尝试了该线程和Nada上的所有技巧。 就像我在上面说过的那样,我才能使ESP32再次连接到Wifi的唯一方法是安装此其他应用程序以重置东西。 我想知道它能使我的ESP32再次与WiFi一起工作是做什么的。

@gdombiak ,您有任何调试信息来显示ESP32锁定时的功能吗? 我最近遇到一个问题,除了新的一天结束时,我的一个草图像冠军一样工作,有两行使其连续循环,而ESP最终会自行崩溃直到我重置或重新加载。 我遇到的另一个问题是,我拥有另一个作为AP_STA的ESP,并且它一直尝试连接到它,而不是正常的WiFI。 必须重新加载其他ESP并规定WiFi.mode(WIFI_STA)可以解决此问题。

@AIWIndustries

查看我张贴在以下位置的帖子: https :
搜索“ SmartConfig / WiFi骨架

我写了一个完整的骨架; 保存,使用SmartConfig进行设置,处理WiFi UP和DOWN,如果Down则自动重新连接。

它是一个完整的结构,并且在WiFi掉线或由于未知原因刚刚断开连接时始终会重新连接。

在loop()中记下“ // WiFi DOWN ”。 我使用一个简单的if()/ else来跟踪WiFi状态。
由于使用了espressif库,因此报告WiFi中断的时间大约需要30-40秒,然后才开始重新连接。

如果AP重新启动,则AP大约需要30秒钟启动,而重新连接又需要15秒钟,但始终会重新连接。

@AIWIndustries

如果将Traceback打印到终端,则有一种查找锁定的方法。

从安装“ ESP Exception Decoder”; https://github.com/me-no-dev/EspExceptionDecoder
指示在那里。

安装后,只需复制并粘贴回溯行,它将告诉您锁定时发生了什么。

大家好,

以下代码对我有用。

无效的wifiReconnect(){
而(WiFi.status()!= WL_CONNECTED){
WiFi.begin(ssid,密码);
for(int i = 0; i <= 50; i ++){
digitalWrite(LED_BUILTIN,HIGH);
延迟(100);
Serial.print(“。”);
digitalWrite(LED_BUILTIN,LOW);
延迟(100);
}
}
}

在loop()中使用它作为

如果(WiFi.status()!= WL_CONNECTED){
wifiReconnect();
}

大家好
我使用的是大约2个月前更新的ESP32内核。
在我的程序中,我在setup()中使用Wifi.begin(ssid,pass)并在“ SYSTEM_EVENT_STA_DISCONNECTED”事件上调用WiFi.reconnect()方法。 如果断开连接,系统将自动连接。 但是昨天我更新到最新的内核,并开始使用原因码8给出错误。
经过一番尝试之后,我评论了WiFi.reconnect()然后它开始完美运行。 如果AP已关闭又打开,wifi也会自动重新连接。

就我而言,仅在设置方法中,我使用
WiFi.mode(WIFI_STA);
Wifi.begin()

这工作正常。
我们可以说在新的内核中不需要调用reconnect()并且自动重新连接现在可以在最新的内核中工作吗?

正确。 不再需要调用reconnect了;)我已经解决了:P

wifi.Reconnect()中存在严重缺陷。

通过深入了解我在几种情况下发现的库,它将在不进行DHCP更新的情况下连接,因此无需IP地址即可连接。 -我报告了,但还没有找到解决方法。

我证明这是一次购买,在一些测试代码中添加了UDP调用。 -我可以通过UDP与AP通讯,但没有IP地址。 同时,MAC显示在AP连接列表中。

您要使用wifi.begin()始终可靠。 -您只需要确保在调用它进行连接时就处于关闭状态,否则可能会遇到堆栈溢出问题。

_我在下面编写的模板从未重新连接过。_它使用SmartConfig和首选项,而不是对AP / Pass进行硬编码,尽管可以轻松更改。

我的某些代码专用于LED闪光灯,因此我改为保留注释。 您可以在此处放置任何指标代码。

看看loop()的wifi down部分。 我叫WiFi.begin(PrefSSID.c_str(),PrefPassword.c_str()); 同时始终测试返回状态为WL_CONNECTED。

希望这会有所帮助。

// ESP32 only,  8266 will not work here
#include "FS.h"
#include "esp_system.h"
#include <esp_wifi.h>
#include <string.h>
#include <WiFi.h>
#include <Preferences.h> // WiFi storage

const char* rssiSSID;        // NO MORE hard coded set AP, all SmartConfig
const char* password;
String PrefSSID, PrefPassword;   // used by preferences storage

int WFstatus;
int UpCount; = 0;
int32_t rssi;         // store WiFi signal strength here
String getSsid;
String getPass;
String MAC;

// SSID storage
  Preferences preferences;       // declare class object
// END SSID storage

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

  Serial.printf("\tWiFi Setup -- \n" ); 
  wifiInit();      // get WiFi connected
  IP_info();
  MAC = getMacAddress();

  delay(2000);  // let thing settle
} // END setup()

void loop()
{
  if ( WiFi.status() == WL_CONNECTED )
  {   // Main connected loop

         // ANY MAIN LOOP CODE HERE

  }   // END Main connected loop()
  else
  {      // WiFi DOWN

    //  wifi down start LED flasher here

    WFstatus = getWifiStatus( WFstatus );
    WiFi.begin(  PrefSSID.c_str() , PrefPassword.c_str() );
    int WLcount = 0;
    while (  WiFi.status() != WL_CONNECTED && WLcount < 200 )
    {
      delay( 100 );
      Serial.printf(".");

        if (UpCount >= 60)  // keep from scrolling sideways forever
        {
           UpCount = 0;
           Serial.printf("\n");
        }
        ++UpCount;
        ++WLcount;
    }

    if( getWifiStatus( WFstatus ) == 3 )   //wifi returns
    { 
      // stop LED flasher, wifi going up
    }
   delay( 1000 );
  } // END WiFi down
} // END loop()


void wifiInit() //
{
  WiFi.mode(WIFI_AP_STA); // required to read NVR before WiFi.begin()

  // load credentials from NVR, a little RTOS code here
  wifi_config_t conf;
  esp_wifi_get_config(WIFI_IF_STA, &conf);     // load wifi settings to struct comf
  rssiSSID = reinterpret_cast<const char*>(conf.sta.ssid);
  password = reinterpret_cast<const char*>(conf.sta.password);

  //  Serial.printf( "SSID = %s\n", rssiSSID );  // un-comment for debuging
  //  Serial.printf( "Pass = %s\n", password );  // un-comment for debuging
  // Open Preferences with wifi namespace. Namespace is limited to 15 chars
  preferences.begin("wifi", false);
    PrefSSID     = preferences.getString("ssid", "none"); //NVS key ssid
    PrefPassword = preferences.getString("password", "none"); //NVS key password
  preferences.end();

  // keep from rewriting flash if not needed
  if( !checkPrefsStore() )   // see is NV and Prefs are the same
  {                          // not the same, setup with SmartConfig
    if( PrefSSID == "none" ) // New...setup wifi
    {
      initSmartConfig();
      delay( 3000);
      ESP.restart(); // reboot with wifi configured
    }
  }

  // I flash LEDs while connecting here

  WiFi.begin( PrefSSID.c_str() , PrefPassword.c_str() );

  int WLcount = 0;
  while (WiFi.status() != WL_CONNECTED && WLcount < 200 ) // can take > 100 loops depending on router settings
  {
    delay( 100 );
    Serial.printf(".");
    ++WLcount;
  }
  delay( 3000 );

  // stop the led flasher here

} // END wifiInit()

// match WiFi IDs in NVS to Pref store, assumes WiFi.mode(WIFI_AP_STA); was executed
bool checkPrefsStore()
{
  bool val = false;
  String NVssid, NVpass, prefssid, prefpass;

  NVssid = getSsidPass( "ssid" );
  NVpass = getSsidPass( "pass" );

  // Open Preferences with my-app namespace. Namespace name is limited to 15 chars
  preferences.begin("wifi", false);
    prefssid  =  preferences.getString("ssid",     "none"); //NVS key ssid
    prefpass  =  preferences.getString("password", "none"); //NVS key password
  preferences.end();

  if( NVssid.equals(prefssid) && NVpass.equals(prefpass) )
  { 
    val = true; 
  }
  return val;
} // END checkPrefsStore()

void initSmartConfig()
{
  // start LED flasher here
  int loopCounter = 0;

  WiFi.mode( WIFI_AP_STA );     //Init WiFi, start SmartConfig
  Serial.printf( "Entering SmartConfig\n" );

  WiFi.beginSmartConfig();

  while (!WiFi.smartConfigDone())
  { // flash led to indicate not configured
    Serial.printf( "." );
    if( loopCounter >= 40 )
    {
      loopCounter = 0;
      Serial.printf( "\n" );
    }
    delay(600);
    ++loopCounter;
  }
  loopCounter = 0;

  // stopped flasher here

  Serial.printf("\nSmartConfig received.\n Waiting for WiFi\n\n");
  delay(2000 );

  while( WiFi.status() != WL_CONNECTED )
  { // check till connected
     delay(500);
  }
  IP_info();

  preferences.begin("wifi", false); // put it in storage
    preferences.putString( "ssid" ,    getSsid);
    preferences.putString( "password", getPass);
  preferences.end();

  delay(300);
} // END SmartConfig()

void IP_info()
{
  getSsid = WiFi.SSID();
  getPass = WiFi.psk();
  rssi = getRSSI( rssiSSID );
  WFstatus = getWifiStatus( WFstatus );
  MAC = getMacAddress();

  Serial.printf( "\n\n\tSSID\t%s, ", getSsid.c_str() );
  Serial.print( rssi);  Serial.printf(" dBm\n" );  // printf??
  Serial.printf( "\tPass:\t %s\n", getPass.c_str() ); 
  Serial.print( "\n\n\tIP address:\t" );  Serial.print(WiFi.localIP() );
  Serial.print( " / " );              Serial.println( WiFi.subnetMask() );
  Serial.print( "\tGateway IP:\t" );  Serial.println( WiFi.gatewayIP() );
  Serial.print( "\t1st DNS:\t" );     Serial.println( WiFi.dnsIP() );
  Serial.printf( "\tMAC:\t\t%s\n", MAC.c_str() );
}  // END IP_info()

int getWifiStatus( int WiFiStatus )
{
  WiFiStatus = WiFi.status();
  Serial.printf("\tStatus %d", WiFiStatus );
  switch( WiFiStatus )
  {
    case WL_IDLE_STATUS : // WL_IDLE_STATUS = 0,
        Serial.printf(", WiFi IDLE \n");
        break;
    case WL_NO_SSID_AVAIL: // WL_NO_SSID_AVAIL = 1,
        Serial.printf(", NO SSID AVAIL \n");
        break;
    case WL_SCAN_COMPLETED: // WL_SCAN_COMPLETED = 2,
        Serial.printf(", WiFi SCAN_COMPLETED \n");
        break;
    case WL_CONNECTED: // WL_CONNECTED = 3,
        Serial.printf(", WiFi CONNECTED \n");
        break;
    case WL_CONNECT_FAILED: // WL_CONNECT_FAILED = 4,
        Serial.printf(", WiFi WL_CONNECT FAILED\n");
        break;
    case WL_CONNECTION_LOST: // WL_CONNECTION_LOST = 5,
        Serial.printf(", WiFi CONNECTION LOST\n");
        WiFi.persistent(false); // don't write FLASH
        break;
    case WL_DISCONNECTED: // WL_DISCONNECTED = 6
        Serial.printf(", WiFi DISCONNECTED ==\n");
        WiFi.persistent(false); // don't write FLASH when reconnecting
        break;
  }
  return WiFiStatus;
}  // END getWifiStatus()

// Get the station interface MAC address.
// <strong i="14">@return</strong> String MAC
String getMacAddress(void)
{
  WiFi.mode(WIFI_AP_STA); // required to read NVR before WiFi.begin()
  uint8_t baseMac[6];
  esp_read_mac( baseMac, ESP_MAC_WIFI_STA ); // Get MAC address for WiFi station
  char macStr[18] = { 0 };
  sprintf(macStr, "%02X:%02X:%02X:%02X:%02X:%02X", baseMac[0], baseMac[1], baseMac[2], baseMac[3], baseMac[4], baseMac[5]);
  return String(macStr);
}  // END getMacAddress()

// Return RSSI or 0 if target SSID not found
// const char* SSID = "YOUR_SSID"; // declare in GLOBAL space
// call: int32_t rssi = getRSSI(SSID);
int32_t getRSSI( const char* target_ssid )
{
  byte available_networks = WiFi.scanNetworks();

  for (int network = 0; network < available_networks; network++)
  {
    if ( strcmp( WiFi.SSID( network).c_str(), target_ssid ) == 0)
    {
      return WiFi.RSSI( network );
    }
  }
  return 0;
} // END getRSSI()

// Requires; #include <esp_wifi.h>
// Returns String NONE, ssid or pass arcording to request
// ie String var = getSsidPass( "pass" );
String getSsidPass( String s )
{
  String val = "NONE"; // return "NONE" if wrong key sent
  s.toUpperCase();
  if( s.compareTo("SSID") == 0 )
  {
    wifi_config_t conf;
    esp_wifi_get_config( WIFI_IF_STA, &conf );
    val = String( reinterpret_cast<const char*>(conf.sta.ssid) );
  }
  if( s.compareTo("PASS") == 0 )
  {
    wifi_config_t conf;
    esp_wifi_get_config( WIFI_IF_STA, &conf );
    val = String( reinterpret_cast<const char*>(conf.sta.password) );
  }
  return val;
}  // END getSsidPass()

我也注意到了这一点,但从未缩小范围,但我注意到reconnect()和begin(ssid ..)并不总是重置dhcp,我认为是边缘情况

开始(参数)
仅在config不相等或尚未连接时才重做dhcp,否则它将返回,这可能是一个问题。

    wifi_config_t current_conf;
    esp_wifi_get_config(WIFI_IF_STA, &current_conf);
    if(!sta_config_equal(current_conf, conf)) {
        if(esp_wifi_disconnect()){
            log_e("disconnect failed!");
            return WL_CONNECT_FAILED;
        }

        esp_wifi_set_config(WIFI_IF_STA, &conf);
    } else if(status() == WL_CONNECTED){
        return WL_CONNECTED;
    }
 // We do not always get here
    if(!_useStaticIp) {
        if(tcpip_adapter_dhcpc_start(TCPIP_ADAPTER_IF_STA) == ESP_ERR_TCPIP_ADAPTER_DHCPC_START_FAILED){
            log_e("dhcp client start failed!");
            return WL_CONNECT_FAILED;
        }
    } else {
        tcpip_adapter_dhcpc_stop(TCPIP_ADAPTER_IF_STA);
    }

@mickeypop感谢您分享代码。 但是我有一个疑问。
如你所说:
I proved this once buy adding a UDP call in some test code. - I could talk to the AP by UDP but had no IP address. At the same time the MAC showed up on the AP connection list.

但据我所知,没有IP我们就无法建立UDP连接。 UDP建立在IP层上。

@jjassar

UDP根本不需要任何IP,只是它自己的MAC。

UDP是SmartConfig中不可思议的地方。 单元上的应用程序仅针对具有AP凭证的ESP32发送特殊格式的UDP数据包。

由于UDP是无连接的,因此AP上或下的所有WiFi设备都可以看到它。

ESP32看到此消息后,会向AP发送一个不同的UDP,以从AP获取连接和IP地址。 记住在连接之前没有IP。

UDP是DHCP最初用于获取IP的底层,但它也以许多其他方式使用。

@mickeypop是否可能将TCP / UDP与广播/多播混合?
TCP和UDP都位于传输层上,该传输层构建在IP所在的Internet层之上。

@mickeypop @bedenko你们俩可能都是正确的,我认为,这可能是UDP广播在地址255.255.255.255上的。
无论如何,我发现了最新的回购新问题。
我有一个连接到AP的esp32,一段时间后我关闭了AP并将其切换回。
断开连接时,如果原因码为201(REASON_NO_AP_FOUND),则它将自动连接
但是有时断开连接原因码7(REASON_NOT_ASSOCED)则从不连接回去,仅在硬件重启后才重新连接。
如果我已关闭AP,为什么会出现原因代码7?

可能是因为代码201在这里被抢救代码7被忽略了。

@jjassar @bedenko

考虑一下。
在设备具有IP之前,必须有一个连接协议,否则DHCP将无法通过任何方式联系DHCP服务器以“获取” IP。

我担任网络工程师已有30多年的时间,如果UDP不是TCP / IP的组成部分,则每次移动到另一个网络时都必须重新设置IP。

这是一个小入门。

DHCP协议

_DHCP协议是使用UDP_端口68和67

DHCP在UDP上运行,因为DHCP客户端在广播上运行,而这只能由UDP支持。 这是必需的,因为客户端计算机仍未接收到IP地址(这是DHCP协商协议的目的),并且没有IP地址本身将无法建立TCP流。

DHCP客户端通过广播DHCP DISCOVER数据包开始。 广播由DHCP服务器接收,然后由DHCP服务器回复DHCP OFFER消息。 DHCP OFFER消息包含服务器提供的IP地址和分配IP地址的时间段(IP可以是随机的,也可以基于管理策略)。

DHCP客户端可能会收到多个DHCP OFFER消息,但是它会根据DHCP客户端中配置的策略仅选择一个DHCP OFFER消息。 通常其先到先得的原则。 但是,我们可以配置DHCP客户端以选择具有最长租用时间或某个首选子网的DHCP OFFER。 现在,DHCP客户端以DHCP REQUEST消息答复。

DHCP REQUEST消息是广播消息。 当其他DHCP服务器收到此消息时,它们会撤回对客户端可能提供的任何报价,并将提供的地址返回到可用地址池中。 预期的DHCP服务器在收到消息后会发送DHCP ACK消息,从而确认交易并在指定的时间内将IP分配给主机。

@mickeypop :我同意您的解释,但事实上UDP可以在没有IP地址的情况下运行。 所有DHCP协商都在广播IP 255.255.255.255( info )上完成。

@bedenko
您几乎必须同意。 我直接从官方文档中剪切并粘贴了它。

你是对是非,这就是原因。

所有网络协议都使用相同的数据包结构。 AppleTalk,TCP / IP,Arpnet,AIX等...这使它们可以在同一以太网上共存而不会发生冲突。

该结构包括协议,类型,校验和,目的地等的位。所有这些都在目的地标识符中寻找24(255.255.255.255)位作为特殊标识符。

那说;

IP流量通过网络掩码进行处理,因此所有设备都可以确定数据包是否适合他们以及路由。

UDP没有网络掩码。 255.255.255.255并非供UDP发送者使用,甚至不供UDP发送者使用,因此所有其他设备都可以看到特殊标识符。 在这种情况下,根本不将其视为IP。

注意:UDP通过MAC发送而不是通过IP发送。

以DHCP为例,您还没有IP或网络掩码,因此设备进入混杂模式,以查找具有其自己的MAC地址的任何数据包。

UDP通过发送方MAC地址发送DHCP DISCOVER数据包,因为DHCP服务器必须知道谁在请求IP。

发件人显然不能将其作为IP流量进行处理,为此,DHCP服务器无法使用IP发送响应。 因此是UDP。

UDP返回的DHCP OFFER消息必须包含MAC,客户端才能知道这是给他们的。 请注意,所有流量的结构都相同,但它根本不是IP。

直到所有谈判结束,才有可能进行任何IP通信。

=====
另外,我应该注意;
我在1968年加入团队,当时70岁是在开发UNIX OS。 TCP / IP诞生了。
在TCP / IP出现之前,我们使用了UDP的早期草案。

@mickeypop感谢您的工作! 我们都可以触摸天空,因为我们站在巨人的肩膀上!

查克

你好
我为此使用此代码

  if (WiFi.status() != WL_CONNECTED)
{
  digitalWrite(26,0);
  WIFI_Connect();
} else {
  digitalWrite(26,1);
}

而且,这是“ WIFI_Connect”功能

无效的WIFI_Connect()
{
digitalWrite(26,HIGH);
WiFi.disconnect();
Serial.println(“ Reconectando WiFi ...”);
WiFi.mode(WIFI_AP_STA);
WiFi.begin(ssid,密码);
//等待连接
对于(int i = 0; i <50; i ++)
{
如果(WiFi.status()!= WL_CONNECTED){
延迟(500);
digitalWrite(26,0);
Serial.print(“。”);
延迟(500);
digitalWrite(26,1);
}
}
digitalWrite(26,0);
}

对我来说,这段代码有效。
Obs:版本2.3

包括

包括

定义WIFI_SSID“ ====”

定义WIFI_PASSWORD“ ===”

//此firebase项目已删除
//您需要输入自己的Firebase信息

定义FIREBASE_HOST“ home-automation-1122.firebaseio.com”

定义FIREBASE_AUTH“ =============”

定义LED1 5

定义LED2 4

定义LED3 0

定义LED4 2

定义LED5 14

定义LED6 12

定义LED7 13

定义LED8 15

void setup(){

pinMode(LED1,输出);

digitalWrite(LED1,0);

pinMode(LED2,输出);

digitalWrite(LED2,0);

pinMode(LED3,输出);

digitalWrite(LED3,0);

pinMode(LED4,输出);

digitalWrite(LED4,0);

pinMode(LED5,输出);

digitalWrite(LED5,0);

pinMode(LED6,输出);

digitalWrite(LED6,0);

pinMode(LED7,输出);

digitalWrite(LED7,0);

pinMode(LED8,输出);

digitalWrite(LED8,0);

Serial.begin(9600);

WiFi.begin(WIFI_SSID,WIFI_PASSWORD);

Serial.print(“ connecting”);

而(WiFi.status()!= WL_CONNECTED){

Serial.print(“。”);

延迟(500);

}

Serial.println();

Serial.print(“ connected:”);

Serial.println(WiFi.localIP());

Firebase.begin(FIREBASE_HOST,FIREBASE_AUTH);

Firebase.setInt(“ LEDStatus”,0);

}

无效循环(){

if(Firebase.getInt(“ field1”))

{

digitalWrite(LED1,LOW);

}

其他

{
digitalWrite(LED1,HIGH);

}
if(Firebase.getInt(“ field2”))

{

digitalWrite(LED2,LOW);

}

其他

{

digitalWrite(LED2,HIGH);

}

if(Firebase.getInt(“ field3”))

{

digitalWrite(LED3,LOW);

}

其他

{
digitalWrite(LED3,HIGH);

}

if(Firebase.getInt(“ field4”))

{

digitalWrite(LED4,LOW);

}

其他

{

digitalWrite(LED4,HIGH);

}
if(Firebase.getInt(“ field5”))

{

digitalWrite(LED5,LOW);

}

其他

{

digitalWrite(LED5,HIGH);

}
if(Firebase.getInt(“ field6”))

{

digitalWrite(LED6,LOW);

}

其他

{

digitalWrite(LED6,HIGH);

}
if(Firebase.getInt(“ field7”))

{

digitalWrite(LED7,LOW);

}

其他

{

digitalWrite(LED7,HIGH);

}
if(Firebase.getInt(“ field8”))

{

digitalWrite(LED8,LOW);

}

其他

{

digitalWrite(LED8,HIGH);

}

//Serial.println(Firebase.getInt("led1“));
//Serial.println(Firebase.getInt("led2“));
//Serial.println(Firebase.getInt("led3“));
//Serial.println(Firebase.getInt("led4“));
//Serial.println(Firebase.getInt("led5“));
//Serial.println(Firebase.getInt("led6“));
//Serial.println(Firebase.getInt("led7“));
//Serial.println(Firebase.getInt("led8“));

Serial.println(“ ......”);
if(Firebase.failed())//检查错误{

Serial.print(“设置/编号失败:”);

Serial.println(Firebase.error());

返回;

}

连接断开后我的nodemcu esp8226无法重新连接,直到重新为其供电

该线程用于esp32。 您使用的是esp8266,还是错字?

esp82255 nodemcu

在2018年9月11日星期二,贝登科下午1:45, notifications @ github.com写道:

该线程用于esp32。 您使用的是esp8266,还是错字?

-
您收到此邮件是因为您发表了评论。
直接回复此电子邮件,在GitHub上查看
https://github.com/espressif/arduino-esp32/issues/653#issuecomment-420196435
或使线程静音
https://github.com/notifications/unsubscribe-auth/ApKpJ7SS4fk4KrHA1sVKmwV7brGVeh93ks5uZ3gxgaJpZM4PfOia

对不起,这是esp8266

在2018年9月11日星期二下午1:48,Ijaz Ahmad, conceptualboy2 @ gmail.com写道:

esp82255 nodemcu

在2018年9月11日星期二,贝登科下午1:45, notifications @ github.com写道:

该线程用于esp32。 您使用的是esp8266,还是错字?

-
您收到此邮件是因为您发表了评论。
直接回复此电子邮件,在GitHub上查看
https://github.com/espressif/arduino-esp32/issues/653#issuecomment-420196435
或使线程静音
https://github.com/notifications/unsubscribe-auth/ApKpJ7SS4fk4KrHA1sVKmwV7brGVeh93ks5uZ3gxgaJpZM4PfOia

这里有人帮我吗?

该线程用于ESP32,而不是8266。尝试其他回购。

你能帮我8226吗

@vseven我如何解决这个问题?

@ ijaz1122如果有适合您问题的问题,请看这里。 否则在那儿打开一个新的。
您当前正在其他设备上寻求解决方案。 这是您问题的错误存储库。

嘿,终于,我得到了这段代码,可以多次连接和重新连接wifi /便携式热点

感谢@ThiagoCas的代码

`/ * * * * * * * * * * * * *
包括图书馆
* * * * * * * * * * * * * /

包括

/ * * * * * * * * * * * * *
定义常数
* * * * * * * * * * * * * /

定义WIFISSID“ ==您的Wifi SSID ==” //将WifiSSID放在此处

define PASSWORD“ ==您的密码==” //在此处输入您的wifi密码

//常量不会改变。 此处用于设置密码:
const int ledPin = 2; // LED引脚号

/ * * * * * * * * * * * * *
定义变量
* * * * * * * * * * * * * /
//变量将更改:
int ledState = LOW; // ledState用于设置LED

int间隔= 100; //闪烁间隔(毫秒)

//通常,对于保留时间的变量,应使用“ unsigned long”
//该值很快会变得太大而无法存储int
unsigned long前一个Millis = 0; //将存储上次更新LED的时间

/ * * * * * * * * * * * * *
辅助功能
* * * * * * * * * * * * * /
无效的WIFI_Connect()
{
WiFi.disconnect();
Serial.println(“正在连接WiFi ...”);
WiFi.mode(WIFI_AP_STA);
WiFi.begin(WIFISSID,PASSWORD);

对于(int i = 0; i <60; i ++)
{
如果(WiFi.status()!= WL_CONNECTED)
{
延迟(250);
digitalWrite(ledPin,LOW);
Serial.print(“。”);
延迟(250);
digitalWrite(ledPin,HIGH);
}
}
如果(WiFi.status()== WL_CONNECTED)
{
Serial.println(“”);
Serial.println(“ WiFi Connected”);
Serial.println(“ IP地址:”);
Serial.println(WiFi.localIP());
}
digitalWrite(ledPin,0);
}

/ * * * * * * * * * * * * *
主要功能
* * * * * * * * * * * * * /

无效setup()
{
Serial.begin(115200);

//将数字引脚设置为输出:
pinMode(ledPin,输出);
WIFI_Connect();
}

无效循环()
{
unsigned long currentMillis = millis();

如果(currentMillis-previousMillis> =间隔)
{
如果(WiFi.status()!= WL_CONNECTED)
{
Serial.println(“ wifi断开连接”);
WIFI_Connect();
}
//保存上一次您使LED闪烁的时间
previousMillis =当前Millis;
//如果LED熄灭,则将其打开,反之亦然:
如果(ledState == LOW)
{
ledState =高;
间隔= 100;
}
其他
{
ledState = LOW;
间隔= 2500;
}
//使用变量的ledState设置LED:
digitalWrite(ledPin,ledState);
}
}`

较新的固件似乎可以解决这个问题。

@vseven使用较新的固件...您是说该库的主管提供最新版本吗? 自9月26日以来,我看不到要提交的新内容,因此不知道您是否在指其他东西。

感谢您的澄清
加斯顿

我是一年多以前打开的,所以是,最近几个月都比较新。

大。 感谢您的澄清。 我不确定何时更新(2个月前?),但是上次更新后却再也没有看到此错误(而且过去每隔几个月就会发生一次)。 我以为我很幸运,但现在我发现这不仅仅是运气。 ;)

很好。
加斯顿

这似乎也有帮助:

    esp_wifi_set_ps(WIFI_PS_NONE);

@vseven

较新的固件似乎可以解决这个问题。

你好,
我一直认为Platformio通过更新arduino-esp32库也可以更新您所说的固件。 我错了吗? 我仍然在遭受这个问题!

@vseven
较新的固件似乎可以解决这个问题。

你好,
我一直认为Platformio通过更新arduino-esp32库也可以更新您所说的固件。 我错了吗? 我仍然在遭受这个问题!

同样在这里。 想要获得如何通过Platformio更新固件的指示以自己解决断开连接的问题...

@vseven
此处介绍了平台IO设置说明和更新
https://github.com/espressif/arduino-esp32/blob/master/docs/platformio.md

然而,有一点提示:在Arduino和Platform IO上,当我使用git更新SDK时,我有时发现更新未完成且出现问题。

重命名esp32文件夹并从新鲜的git重新安装,我一直都得到一个干净的更新。
只需按照他们的指示进行即可。

@mickeypop :好的,我的platformio是最新的稳定版本,但是我仍然遇到断开连接的问题。 您是否建议使用舞台或上游版本? 顺便说一下,马stable仅在几天前进行了更新。

如果仅使用IDF示例,是否存在@ Miq1这个问题?

我必须承认,我仅在Platformio环境中使用Arduino-我从未与IDF接触过。 我今天将研究它,看看是否可以在那里建立应用程序的基本版本。

仅作记录:我发现,如果我在两者之间进行了mode(WIFI_OFF)和mode(WIFI_STA)之间的操作,则connector()和后续begin()的变通方法对我而言有效。 我目前正在尝试连续5次进行重新连接,如果所有尝试均失败,则将执行esp.restart(),但到目前为止,无需重新启动。

我在此期间观察到一些重新启动,因此解决方法似乎没有那么有效。

是否有关于此错误的任何更新?

FWIW我也经常在ESP8266上看到这一点-完全一样的症状。 我发现我可以通过简单地改变设备的方向来彻底改变连接-因此,这似乎与设备(ESP8266和ESP32)如何响应不良信号有关。

鉴于我正在使用NonOS和ESP8266,共同点似乎是lwIP以下的低层网络

(使用Arduino-esp32 1.0.4版本)

我在这里有同样的问题(使用ESP32)。 发现重启路由器可以解决问题……一次。 也就是说,重新启动后,ESP32能够连接到AP,获得IP地址并保持连接,但是如果由于某种原因导致连接失败(例如重新启动ESP32),则ESP32则_将永远无法连接到再次AP_。

该路由器是TP-Link TL-MR2030,我一直在进行有线以太网测试,并且其固件已经过时了多年,并且没有较新的官方固件。

但是,如果我尝试使用其他AP(例如办公室中的一些较新的Ubiquiti单元),则根本不会发生此问题。 我甚至迫使董事会故意重新启动并尽可能快地反复重复连接,从而持续数小时,这使IT人员感到有些怀疑……而且完全没有问题。

_因此,最后,虽然ESP32库中可能有错误或不完整,但我准备将所有责任归咎于旧路由器的固件。但是。

我通常怀疑dns这样的事情。 有时路由器仍然认为您已连接并且从不允许您重新连接

不,不要责怪路由器。 至少就我而言。 当然,它不是最新的(wnr2200),但已安装了最新的DD-WRT,并且多个android,linux和Windows设备正常工作。

为了最终为我自己解决这个问题,我从WiFiClientEvents.ino开始,使用了一个全新的实现-因此它是基于事件的。 我还阅读了arduino-esp32的最新提交消息,该消息显示了最新但相关的提交。 我必须在WiFiGeneric.cpp中进行一些调试,发现该模式并不总是能达到预期的效果(https://github.com/espressif/arduino-esp32/issues/1306)。

最终结果:在WiFiGeneric.cpp上有一个小补丁(请参阅文件末尾),我能够与AP进行多次连接和断开连接-欢呼:)

让我知道您是否有需要改进的地方。

/*
 * This is a very stable example of repeated connecting and disconnecting to/from a wifi access point on STA32
 * Unfortunately, it needs patching of the WiFiGeneric.cpp library file
 * Author: Daniel Alder, based on the example WiFiClientEvents.ino
 * Tested with Arduino 1.8.5 and 1.8.10 with ESP library from Nov 11 2019 (cec3fca4) + patch
*/

#include <WiFi.h>   

#include "HomeWifiConfig.h" // use an extra include or uncomment the following 2 lines
//const char* ssid     = "myssid"; // your network SSID (name of wifi network)
//const char* password = "****";   // your network password

typedef enum {
  MYSTATE_OFFLINE = 0,
  MYSTATE_CONNECTING,
  MYSTATE_ONLINE,
  MYSTATE_DISCONNECTING
} mystate_t;
mystate_t mystate = MYSTATE_OFFLINE;
long state_since = 0;

#define TIMEOUT_ONLINE     20  // reconnect after this [s] offline time
#define TIMEOUT_OFFLINE    20  // disconnect after this [s] online time
#define TIMEOUT_CONNECTING 20  // cancel connecting after this [s] without success

////////////////////////////////////////////////////////////////////////////////

long getUptime() {
  return esp_timer_get_time() / 1000000L;
}

void changeState(mystate_t state) {
  mystate = state;
  state_since = getUptime();
}

void WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info)
{
    Serial.printf("[WiFi-event] event: %d\n", event);

    switch (event) {
        case SYSTEM_EVENT_WIFI_READY: 
            Serial.println("WiFi interface ready");
            break;
        case SYSTEM_EVENT_SCAN_DONE:
            Serial.println("Completed scan for access points");
            break;
        case SYSTEM_EVENT_STA_START:
            Serial.println("WiFi client started");
            break;
        case SYSTEM_EVENT_STA_STOP:
            Serial.println("WiFi client stopped");
            changeState(MYSTATE_OFFLINE);
            break;
        case SYSTEM_EVENT_STA_CONNECTED:
            Serial.println("Connected to access point");
            break;
        case SYSTEM_EVENT_STA_DISCONNECTED:
            Serial.println("Disconnected from WiFi access point");
            break;
        case SYSTEM_EVENT_STA_AUTHMODE_CHANGE:
            Serial.println("Authentication mode of access point has changed");
            break;
        case SYSTEM_EVENT_STA_GOT_IP:
            Serial.print("Obtained IP address: ");
            //Serial.println(WiFi.localIP());
            //Serial.println("WiFi connected");
            //Serial.print("IP address: ");
            Serial.println(IPAddress(info.got_ip.ip_info.ip.addr));

            changeState(MYSTATE_ONLINE);

            break;
        case SYSTEM_EVENT_STA_LOST_IP:
            Serial.println("Lost IP address and IP address is reset to 0");
            //changeState(MYSTATE_OFFLINE);
            break;
        case SYSTEM_EVENT_STA_WPS_ER_SUCCESS:
            Serial.println("WiFi Protected Setup (WPS): succeeded in enrollee mode");
            break;
        case SYSTEM_EVENT_STA_WPS_ER_FAILED:
            Serial.println("WiFi Protected Setup (WPS): failed in enrollee mode");
            break;
        case SYSTEM_EVENT_STA_WPS_ER_TIMEOUT:
            Serial.println("WiFi Protected Setup (WPS): timeout in enrollee mode");
            break;
        case SYSTEM_EVENT_STA_WPS_ER_PIN:
            Serial.println("WiFi Protected Setup (WPS): pin code in enrollee mode");
            break;
        case SYSTEM_EVENT_AP_START:
            Serial.println("WiFi access point started");
            break;
        case SYSTEM_EVENT_AP_STOP:
            Serial.println("WiFi access point  stopped");
            break;
        case SYSTEM_EVENT_AP_STACONNECTED:
            Serial.println("Client connected");
            break;
        case SYSTEM_EVENT_AP_STADISCONNECTED:
            Serial.println("Client disconnected");
            break;
        case SYSTEM_EVENT_AP_STAIPASSIGNED:
            Serial.println("Assigned IP address to client");
            break;
        case SYSTEM_EVENT_AP_PROBEREQRECVED:
            Serial.println("Received probe request");
            break;
        case SYSTEM_EVENT_GOT_IP6:
            Serial.println("IPv6 is preferred");
            break;
        case SYSTEM_EVENT_ETH_START:
            Serial.println("Ethernet started");
            break;
        case SYSTEM_EVENT_ETH_STOP:
            Serial.println("Ethernet stopped");
            break;
        case SYSTEM_EVENT_ETH_CONNECTED:
            Serial.println("Ethernet connected");
            break;
        case SYSTEM_EVENT_ETH_DISCONNECTED:
            Serial.println("Ethernet disconnected");
            break;
        case SYSTEM_EVENT_ETH_GOT_IP:
            Serial.println("Obtained IP address");
            break;
        default: break;
    }
}

#include "esp_wifi.h" // only for fixWifiPersistencyFlag()
/**
 * Disable persistent mode, see https://github.com/espressif/arduino-esp32/issues/1393
 */
void fixWifiPersistencyFlag() {
  wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
  Serial.printf("cfg.nvs_enable before: %d\n", cfg.nvs_enable);
  cfg.nvs_enable = 0;
}

////////////////////////////////////////////////////////////////////////////////

void setup()
{
  Serial.begin(115200);
  Serial.println("-----------------------------------------");
  Serial.println("THIS IS: newWifiImplementationUsingEvents");
  Serial.println("-----------------------------------------");

  WiFi.persistent(false);
  fixWifiPersistencyFlag();

  //Serial.setDebugOutput(true); 
  //WiFi.printDiag(Serial); 

  // delete old config
  WiFi.disconnect(true);

  state_since = getUptime();

  delay(1000);

  // warning: only the last defined event handler gets events!
  WiFi.onEvent(WiFiEvent);

  Serial.println("End of setup");
}

bool firstTime = true;

void loop()
{
  long uptime = getUptime();
  if (mystate == MYSTATE_ONLINE && state_since + TIMEOUT_ONLINE < uptime) {
    Serial.println("Disconnecting NOW");
    changeState(MYSTATE_DISCONNECTING);
    WiFi.disconnect(true);
    WiFi.mode(WIFI_OFF);
  } else if (mystate == MYSTATE_OFFLINE && state_since+TIMEOUT_OFFLINE < uptime) {
    Serial.println("Connecting NOW");
    changeState(MYSTATE_CONNECTING);
    if (firstTime) {
      Serial.println("(firstTime)");
      WiFi.begin(ssid, password);
      firstTime = false;
    } else {
      // doesn't work without WiFiGeneric.cpp patch below
      WiFi.mode(WIFI_STA);
      WiFi.reconnect();
    }
  } else if (mystate == MYSTATE_CONNECTING && state_since+TIMEOUT_CONNECTING < uptime) {
    Serial.println("Cancelling NOW after no connect success");
    changeState(MYSTATE_DISCONNECTING);
    WiFi.disconnect(true);
    WiFi.mode(WIFI_OFF);
  }

  delay(1000);
  if (uptime % 10 == 0) {
    Serial.printf("uptime %d\n", uptime);
  }
}

/* PATH FOR LIBRARY
diff --git a/libraries/WiFi/src/WiFiGeneric.cpp b/libraries/WiFi/src/WiFiGeneric.cpp
index e562921..aab5805 100644
--- a/libraries/WiFi/src/WiFiGeneric.cpp
+++ b/libraries/WiFi/src/WiFiGeneric.cpp
@@ -483,8 +483,10 @@ void WiFiGenericClass::enableLongRange(bool enable)
 bool WiFiGenericClass::mode(wifi_mode_t m)
 {
     wifi_mode_t cm = getMode();
+    log_d("mode() cm=%d, m=%d", cm, m);
     if(cm == m) {
-        return true;
+        log_d("HACK: skip return true");
+        //return true;
     }
     if(!cm && m){
         if(!wifiLowLevelInit(_persistent)){
*/


/* ISSUES:
 *  
 * 1) The example WiFiClientEvents.ino says:
 * 
 *   WiFi.onEvent(WiFiEvent);
 *   WiFi.onEvent(WiFiGotIP, WiFiEvent_t::SYSTEM_EVENT_STA_GOT_IP);
 *   
 *   but the WiFiEvent function never receives a SYSTEM_EVENT_STA_GOT_IP!
 *   
 * 2) I used code from https://github.com/espressif/arduino-esp32/issues/1393 to fix the persistent config issue
 * 
 * 3) The list of events in WiFiClientEvents.ino (comment block) is missing an event. Same bug as fixed in 188560e7f33
 * 
 * 4) Without pathing of WiFiGeneric.cpp, the mode() function doesn't do anything anymore once WiFi it was initialized (not even connected)
 * 
 *   see also: https://github.com/espressif/arduino-esp32/issues/1306 (but the this patch is not yet mentioned there)
 * 
 * 5) just a note: there is a STA_LOST_IP event, 2 minutes after disconnecting. 
 *   So if you want to make your code stable, you should also test with TIMEOUT_OFFLINE > 130
 */

有没有人窃窃私语?

arduino wifi rev 2也有类似的问题(不同的硬件,但ap和设备之间的协商问题极为相似。)

https://github.com/arduino/nina-fw/issues/14

@mrarmyant您希望使用

自发布以来,我的代码(在您的帖子上方)运行稳定。 但是我不认为问题可以移植到与ESP *芯片不同的东西上,因为它解决了ESP SDK而不是Arduino的问题

我把这样的问题归咎于电源

我不会怪PS,除非您的货源真的很弱,否则这是不可能的。

Wireshark在这里真的没用。

要了解您必须深入研究完成真正工作的RTOS库,而不是Arduino库,因为它们是包装器。

如果您使用的是WiFi.reconnect()而不是WiFi.begin(),则需要了解一些知识。

WiFi.begin()首先在连接之前在wifi芯片上设置所有需要的寄存器和RTOS状态开始,而reconnect()则不需要。
这是2年前的报道。

WiFi.reconnect()通常仅建立一半的连接,与UDP建立芯片级MAC连接,但从不建立TCP / IP连接,因为它们是单独的协议。 这是由于所需的状态没有通过reconnect()预先设置,它只是假设它们在那里。
这就是为什么有些人在重新连接时未获得SYSTEM_EVENT_STA_GOT_IP的原因。

记得; 由于状态已更改,因此需要重新连接。

我总是与WiFi.begin()重新连接,并且从未失败过。

======
关于未连接的重置,并说您已经有一个连接需要知道DHCP。
通常每15秒重新建立一次DHCP IP地址。
现在,假设您在重新设置后2秒钟按了重置按钮。
DHCP服务器不会再释放IP 13秒钟,并且在尝试连接时会报告IP地址正在使用中。

连接之前的简单启动延迟对我来说都是固定的。
如果要设置多个其他库,请先将它们全部设置在WiFi.begin()之前。

一个好的启动计时器将在这里有所帮助。
长var = millis(); 在setup()和Serial.print(millis()-var)的第一行中

我已经使用ESP32超过6年了,并且一直都能正常工作。

更新; 我看到使用了很多WiFiEvent并用于调试它的功能,但是每次仅能可靠地检测wifi断开并重新连接下面的IF / ELSE即可。

之所以可行,是因为从下到报告WL_CONNECTED更改大约需要18秒钟,这使DHCP服务器有时间释放IP,以便以后进行可靠的重新连接。

它已经工作了6年以上,并且还在不断增加。

loop()
{
  if ( WiFi.status() ==  WL_CONNECTED ) 
  {
    // WiFi is UP,  do what ever
  } else
  {
    // wifi down, reconnect here
   WiFi.begin(  );
    int WLcount = 0;
    while (WiFi.status() != WL_CONNECTED && WLcount < 200 ) 
    {
      delay( 100 );
         Serial.printf(".");
         if (UpCount >= 60)  // just keep terminal from scrolling sideways
         {
            UpCount = 0;
               Serial.printf("\n");
         }
         ++UpCount;
      ++WLcount;
    }
  }
} // END loop()

看看我在https://github.com/espressif/arduino-esp32/issues/1100上发布的框架代码

尽管它是使用SmartConfig进行设置的,但它确实可以工作。

@mrarmyant您希望使用

自发布以来,我的代码(在您的帖子上方)运行稳定。 但是我不认为问题可以移植到与ESP *芯片不同的东西上,因为它解决了ESP SDK而不是Arduino的问题

我并不是真的在说arduino,而是那个特定单元上的wifi soc。 基于与dhcp的重插,它在重新连接方面存在问题。 有人报告说,重新启动路由器可以解决此问题,这是我们遇到的问题(请重新启动Windows dhcp服务器)。 它确认是否断开连接的方式存在问题。 只是认为这可能有助于解决那里的那些问题,因为在重新连接时,任何一个单元都不会显示为已连接,而wireshark向我们展示了原因。 静态IP没问题。 最终,它变成了wifi soc固件,必须对其进行修复才能处理上述DHCP问题所引起的延迟。 所有这些都是通过wireshark发现的。

此页面是否有帮助?
5 / 5 - 1 等级

相关问题

jhowkis picture jhowkis  ·  3评论

OAXP picture OAXP  ·  4评论

NickChungVietNam picture NickChungVietNam  ·  3评论

mistergreen picture mistergreen  ·  4评论

lonerzzz picture lonerzzz  ·  3评论