Arduino-esp32: A reconexão automática do WiFi ainda não funciona - existe uma prática recomendada para garantir a conexão?

Criado em 21 set. 2017  ·  150Comentários  ·  Fonte: espressif/arduino-esp32

Placa: ModeMCU ESP32 Dev Module
Data de instalação / atualização do núcleo: 15 / set / 2017
Nome IDE: Arduino IDE

Parece que não há lógica de reconexão automática permitindo que o ESP32 se reconecte quando a conexão cair ou se não estiver funcionando corretamente. Tive resultados completamente aleatórios com minha placa ESP32, às vezes dura apenas 30 minutos e no máximo 18 a 20 horas. O WiFi está caindo e não quer se reconectar.

A biblioteca que estou usando para WiFi está assistindo o evento WiFi e em uma desconexão está tentando reconectar o que ajuda, mas às vezes falha na reconexão e é isso ... Tenho que reiniciar. Não há nenhum modo de espera / baixo consumo de energia envolvido e o dispositivo está constantemente alimentado por 3,3 V pol. Foi aberto um caso sobre isso, https://github.com/espressif/arduino-esp32/issues/353 , mas é fechado sem qualquer resposta real (diz que a conexão automática é meio que implementada ... não tenho certeza do que isso significa)

Acho que a questão se resume a se a reconexão automática é implementada no próprio código, de forma confiável, e se não, qual é a melhor forma de código do Arduino para garantir que ele esteja conectado?

-Allan

bug

Comentários muito úteis

ATUALIZAR; Eu vejo um monte de WiFiEvent usado e para depurar é bom, mas simplesmente detectar o wi-fi e reconectar o IF / ELSE abaixo funciona sempre de forma confiável.

isso funciona porque leva cerca de 18 segundos para relatar a alteração WL_CONNECTED, isso dá ao servidor DHCP tempo para liberar o IP para uma reconexão confiável mais tarde.

Ele está trabalhando há mais de 6 anos e continua.

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

dê uma olhada no esqueleto do código que postei em https://github.com/espressif/arduino-esp32/issues/1100

embora fosse para configuração com SmartConfig, ele simplesmente funciona.

Todos 150 comentários

você pode habilitar a depuração no menu do fórum e ver por que ele não deseja se reconectar quando você diz para fazê-lo?

Eu posso tentar isso esta noite. O código do Arduino é bastante básico, observando o evento WiFi e depois tem isso:

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

Mas não deveria haver algo que pode ser chamado para fazer isso acontecer por conta própria?

Apenas para uma solução rápida:
Inicie um cronômetro no SYSTEM_EVENT_STA_DISCONNECTED que chama o WiFi.reconnect (); função e pará-lo no SYSTEM_EVENT_STA_CONNECTED. O principal problema é com a sua ideia, se o dispositivo não consegue se conectar, então o evento SYSTEM_EVENT_STA_DISCONNECTED não é chamado, então nunca tente se reconectar novamente.

Infelizmente, estou adaptando a biblioteca de outra pessoa e não estou muito familiarizado com C ++, mas verei o que posso fazer para adicionar um cronômetro (eu conheço VB.net ... posso pelo menos descobrir as partes lógicas e espero adaptar).

Mas acho que você está certo sobre não reconectar ou, melhor ainda, apenas tentar uma desconexão que, se falhar apenas uma vez, desiste. Habilitar a depuração pode me mostrar isso, então vou começar por aí.

Mas voltando à questão original e ao problema encerrado anteriormente: esta funcionalidade não está embutida? E se não, por que a edição anterior foi encerrada como "meio que" funcionando? Além disso, se não, será?

Mudei o nível de depuração para depuração e abri o monitor serial e recuperei isso repetidamente:

[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...

Eu verifiquei a última vez que ele enviou dados para outro controlador e isso foi há mais de 24 horas, então estou assumindo que está preso neste modo. Então eu desliguei e liguei, ele se conectou a WiFi perfeitamente e transmitiu dados como deveria por cerca de 2 horas desta vez. Então, sem qualquer outra mensagem, ele se desconectou e começou com a mesma mensagem repetidamente. Eu o deixei ir por uma hora, reiniciei o controlador e ele está conectado novamente, mas tenho certeza que é apenas uma questão de tempo antes de reiniciar.

Portanto, a primeira pergunta é como faço para corrigir isso. Em segundo lugar, isso ainda me leva às minhas perguntas anteriores sobre reconexão automática

Pessoal, habilitem a depuração para que possam ver a saída do estado WiFi mais detalhada:
screen shot 2017-09-22 at 13 48 16

Eu uso o código a seguir para verificar se meu dispositivo ainda está conectado ao STA (chame isso de loop ()). Você entendeu a ideia? wifi_is_connected é um global que é definido e redefinido no retorno de chamada do evento 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;
      }
    }
  }
}

Sim, não vejo um Loop () na biblioteca que estou usando para WiFi (novamente, de terceiros), mas entendo o que você está fazendo e posso executá-lo.

Vou ligar o registro verboso e ver se consigo mais informações antes de alterar qualquer coisa.

Além disso, os eventos WiFi que estão sendo verificados e realizados são SYSTEM_EVENT_STA_GOT_IP, SYSTEM_EVENT_STA_DISCONNECTED, SYSTEM_EVENT_STA_START e SYSTEM_EVENT_STA_CONNECTED. Há mais, entretanto, em https://github.com/espressif/esp-idf/blob/master/components/esp32/include/esp_event.h, então adicionei um padrão: ao switch que deve imprimir o evento para ver se a biblioteca está obtendo alguma coisa, mas não está agindo de acordo.

Vi na biblioteca que estou usando um //WiFi.setAutoReconnect(true); então estou assumindo que o autor original tentou usar a reconexão automática, mas não estava funcionando, então comentou?

@ me-no-dev - Verbose deu uma explicação muito melhor. Bem ... talvez para você:

Tudo estava bem, então consegui repetir, talvez 150 vezes:

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

Seguido por este:

[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

A última parte (reconectar, evento 5, motivo 2) apenas se repete a cada 4 - 5 segundos.

Com base naquele primeiro erro que se repete continuamente, encontrei este: https://github.com/espressif/arduino-esp32/issues/180. Nele você disse "Tente limpar o cliente ou ler todos os dados disponíveis". Como eu faria isso? Estou olhando a biblioteca que estou usando e é isso que eles precisam para capturar o evento WiFi:

//**************************************************************************************
/// 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;
        }

    }

Com base nos erros do post anterior, estou obtendo o "5" que é traduzido para a conexão Wi-Fi perdida e, em seguida, o código está tentando executar "WiFi.reconnect ();" mas obviamente não está funcionando. Devo ter algo mais lá? Talvez um contador parecido com o exemplo

Tente chamar WiFi.begin () em vez de reconectar e relatar :)

@ me-no-dev - mudei para WiFi.begin () em vez de WiFi.reconnect (), mas não ajudou. Trabalhou por cerca de uma hora, em seguida, obtive a linha lwip_connect_r: 113, cada uma com cerca de um minuto ou mais de distância seguida pela desconexão a cada 5 ou mais segundos:

[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

E então as 4 linhas se repetem indefinidamente até que o controle seja reiniciado. O que mais posso tentar? O fato de @everslick estar reiniciando o controlador quando ele está no mesmo estado desconectado é preocupante ... Eu acho que reiniciar é a última opção e algo pode ser feito para mantê-lo online.

Como observação lateral, dois ESP8266 conectados ao mesmo roteador (Netgear R8000) não têm problemas e estão estáveis ​​há mais de um mês sem desconexões.

hmmm .... isso parece ser um problema na pilha inferior ou em seu roteador.
você pode ver o primeiro motivo sendo NOT_ASSOCED e então você obtém AUTH_EXPIRE.
você poderia desligar o STA e ligá-lo novamente? A causa da desconexão me faz pensar que algo na solicitação de re-assoc não foi alterado ou seu roteador não aceita, então ele se recusa a se conectar novamente. Vou ver se consigo levantar um problema interno sobre isso. Qual é a versão do firmware do roteador que você está usando?

É um Netgear Nighthawk R8000. Atualmente no firmware mais recente V1.0.3.54_1.1.37, embora também o tenha feito na última versão. Tenho de 20 a 25 dispositivos conectados a qualquer momento sem problemas, incluindo os dois ESP8266 mencionados anteriormente.

Vou tentar substituir a linha de início / reconexão do Wi-Fi com o STA desligado e ligado e ver o que acontece.

Edit: Não sabendo muito sobre isso e usando a biblioteca de outra pessoa ... como faço para "desligar o STA e ligá-lo novamente"?

Segunda edição: não poderia estar relacionado a https://github.com/espressif/esp-idf/issues/499#issuecomment -314262611 poderia? Uma das únicas coisas que vi com o mesmo NOT_ASSOCED e AUTH_EXPIRE. Eu não pensaria assim apenas porque me compilei sem o material BLE, mas nunca sei.

Também alertei a equipe wi-fi :) vamos ver se sai alguma coisa disso

Obrigado. Devo tentar ligar e desligar o STA? Se sim, você pode me orientar ou apontar a direção certa?

Eu também vi isso: https://github.com/espressif/esp-idf/issues/738#issuecomment -311626685 que indicou que não posso chamar o WiFi.connect ou WiFi.Begin do manipulador de eventos? Esse também poderia ser o meu problema? @rojer ?

Então comprei um segundo ESP32, o mesmo, para tentar e ter certeza de que não é um problema de hardware. Eu recompilei o firmware ontem à noite com um novo pull do github (https://nodemcu.readthedocs.io/en/dev-esp32/en/build/) e atualizei o novo chip e o antigo. Eu também mostrei os dois exatamente com o mesmo esboço. O original está na minha garagem, um pouco afastado do meu roteador, e o outro de teste está na minha sala onde o WiFi é bem mais forte. Ambos têm monitor serial em execução em um PC conectado com conjunto detalhado. Vou relatar tudo que eu encontrar.

Com o que foi dito acima, há algo mais que eu possa tentar? Como faço para ligar e desligar o STA? Isso pode ser feito na parte STA_Disconnect onde está o WiFi.reconnect?

Bem, isso não durou muito ... Estou tendo o mesmo problema com o novo. Primeiro, o original começou com o mesmo erro "[E] [WiFiClient. Cpp : 97 ] connect (): lwip_connect_r: 113" e não enviou dados depois de apenas 30 minutos online. Normalmente recebo esse erro dois de cada vez com cerca de 5 ou 6 segundos entre 45 - 50 segundos entre o próximo conjunto, mas novamente meio aleatório. Fiz isso por cerca de 10 minutos e depois entrou no mesmo padrão de desconexão:


[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

E repetiu as últimas 4 linhas indefinidamente. Em um ponto, ele fez algo diferente ... a mensagem de erro mudou ligeiramente:

[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

Observe que o erro mudou para terminar em 118 ao invés de 113. Mas daquele ponto em diante, ele apenas repetiu o erro 118 aleatoriamente junto com STA_DISCONNECTED e AUTH_EXPIRED continuamente.

Então, o novo ESP32 começou a fazer exatamente a mesma coisa. principalmente erro 113, em seguida, o mesmo padrão de NOT_ASSOCED, ASSOC_FAIL e AUTH_EXPIRE seguido apenas pela desconexão e AUTH_EXPIRE repetidamente.

Eles falharam em momentos diferentes, com 25 minutos de intervalo, enquanto eram iniciados exatamente ao mesmo tempo. O sinal WiFi não parece ser um fator, nem qualquer momento determinado.

Editar: apenas para esclarecer uma reinicialização, ele se conecta instantaneamente na primeira tentativa sempre:

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

Ainda aguardando resposta da equipe WiFi. Fará mais barulho, pois isso também é irritante para mim. O problema está em algum lugar abaixo do Arduino e na biblioteca wi-fi de código fechado.

Obrigado. Vou tentar adicionar um contador para a instrução de switch de evento STA_DISCONNECTED que continuo recebendo e após 5 tento reinicializar o wi-fi e após 10 reinicializar o controlador e em uma conexão redefinir o contador para 0, veja se isso em menos mantém o controlador ativo.

Se houver mais alguma coisa que eu possa fornecer para ajudar a consertar isso ou tentar o código, entre em contato. Se for importante, o ESP32 que estou usando está sendo usado para duas entradas de tensão, uma entrada binária e um DTH22 (temp + umidade), então esses dados estão sendo enviados para um controlador por meio de HTTP.

Olá @vseven , não consigo reproduzir esse problema sozinho. Você poderia me informar a versão do firmware do WiFi? Você pode obtê-la no log de inicialização, parece "I (588) wifi: versão do firmware wi-fi: 2cd69aa", então posso fornecer uma versão de depuração wifi lib para você depurar esse problema.

@vseven você poderia me informar a lógica de reconexão do WiFi? Quero dizer quando chamar esp_wifi_connect ()? Será útil colar a lógica de implementação.

O log de wi-fi
@vseven comente esta linha para mostrá-la

Ok, eu comentei essa linha e recompilei. Vou relatar de volta. Como observação lateral, tentei adicionar um contador para reconectar, lembrando meu init (), mas não fez nada ... era como se o init () nunca tivesse sido chamado. Eu posso estar fazendo errado embora. Mas quando o contador chegou a 10, o ESP.restart desafiadoramente foi chamado e reiniciado corretamente, que depois se reconectou:

    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 - aqui está a informação extra com essa linha comentada:

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

E os arquivos que estou usando (antes de adicionar o contador de desconexão):

SmartThingsESP32WiFi.h.txt
SmartThingsESP32WiFi.cpp.txt

@liuzfesp - Então fez a mesma coisa com a depuração habilitada, espero que algo aqui diga a você. Funcionou bem por uma hora ou mais, então começou a lançar o erro 113 aleatoriamente. Após cerca de 15 minutos de erros 113 aleatórios entre as rotinas de envio de dados reais, ele fez o seguinte:

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)

Então, para cada STA_DISCONNECT, ele tentou chamar WiFi.reconnect sem sucesso aparente, em seguida, tentou executar init () depois de mais de 5 desconexões, o que também não ajudou, uma vez que atingiu 10 desconexões, ele reiniciou o que reinicializou e reconectou.

Eu mantive o monitor serial em execução no meu ESP32 durante todo o fim de semana e ele reiniciou cerca de 10 vezes entre as 18h de sexta-feira à noite e as 21h de domingo à noite. Cada vez era exatamente como os registros acima.

@ me-no-dev - você pode me orientar de forma a desligar e ligar o STA para ver se isso também funciona para reconectar e se eu posso tentar isso após 5 tentativas malsucedidas? A reinicialização após 10 funciona, mas pretendo usar isso para controlar a iluminação RGB e realmente não quero que as luzes sejam desligadas e ligadas.

@liuzfesp - Posso fornecer mais alguma coisa para depuração? Ou algo que se destaque que eu possa experimentar?

Alguma atualização? Ainda tem desconexões constantes com ambos os dispositivos.

@liuzfesp alguma novidade aqui?

Vejo que há algumas alterações de código no bluetooth e no WiFi. Não tenho certeza se isso vai me ajudar ou não. Ainda continuo tendo os mesmos problemas e a reinicialização está funcionando para manter meus dados sendo passados, mas não consegui usá-lo para o controle de faixa de luz RGB, pois as luzes ficavam apagadas na reinicialização.

@liuzfesp - Há algo nos logs que ajude ou algo mais que eu possa fornecer ou tentar?

Limpei algumas coisas, certifiquei-me de que no meu código não havia nada causando atrasos ou bloqueando, e agora tenho menos erros (não veja os erros 113 e 118), mas ainda tendo o mesmo problema de desconexão e parece diretamente relacionado ao WiFi tentando autenticar (renovar?) E falhando. Aqui está uma nova captura deste fim de semana em que reiniciei cerca de 5 vezes em um período de 24 horas. Novamente, a mesma coisa em dois ESP32s diferentes, procuro a desconexão (evento 5) e tento reconectar com um WiFi.reconnect e um WiFi.begin ambos sem sorte, então após 10 tentativas ele reinicia e se conecta bem depois:

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-dev - Posso fornecer mais alguma informação? Isso está acontecendo com mais alguém ou apenas com meus dois HiLetGo ModeMCU ESP32s? Existe algum firmware personalizado que eu possa experimentar?

-Allan

Tenho exatamente o mesmo comportamento no meu módulo WROOM-32.
A cada 3 ou 4a reinicialização, ele trava no loop STA_DISCONNECTED -> AUTH_EXPIRED.
Foi verificado um segundo módulo do mesmo tipo, apresentando o mesmo comportamento.
Meu roteador é um TL-WR841 (TPLINK), mas também funciona com um ASUS RT-AC87U.

Quando haverá uma solução, não adianta se houver necessidade de um reboot em tais situações ...

editar: para mim, esse problema também ocorre após a inicialização, ou seja, WiFi.begin () não estabelecerá nenhuma conexão, mas fará loops em STA_DISCONNECTED -> AUTH_EXPIRED

Não recebo uma resposta há um mês, embora, sem ofensa, esteja feliz que esteja acontecendo com outra pessoa, então sei que não estou sozinha.

@liuzfesp / @ me-no-dev - Houve algum progresso nisso ou em qualquer coisa que possamos tentar fazer para permanecer conectado de forma confiável ao WiFi.

cutucou @liuzfesp de novo ... isso é o máximo que posso fazer. Eu não tenho acesso à fonte WiFi lib

@igrr

@copercini por quê?

Já que fui marcado aqui ... @vseven , há alguma chance de você realizar a captura de pacotes usando o Wireshark e um adaptador WiFi no modo monitor? De particular interesse é o momento em que o processo de reconexão começa a falhar. Como não sabemos o que está acontecendo aqui e não podemos reproduzir um problema semelhante em nosso ambiente de CI, a captura de pacotes pode revelar alguma anomalia, dando uma pista sobre a situação que você está enfrentando.

Outra ideia (apenas para reduzir o número de variáveis), esse problema também acontece se você se conectar a uma rede WiFi aberta?

atualmente, todas as reconexões falham com meus WROOM32s com a seguinte saída de depuração:

[D] [WiFiGeneric. cpp: 265 ] _eventCallback (): Evento: 2 - STA_START
.... [D] [WiFiGeneric. cpp: 265 ] _eventCallback (): Evento: 4 - STA_CONNECTED
.. [D] [WiFiGeneric. cpp: 265 ] _eventCallback (): Evento: 7 - STA_GOT_IP
WiFi conectado
... então eu bloqueio a recepção da antena ou pressiono RESET no meu AP, para forçar a desconexão ...
[D] [WiFiGeneric. cpp: 265 ] _eventCallback (): Evento: 5 - STA_DISCONNECTED
[W] [WiFiGeneric. cpp: 270 ] _eventCallback (): Motivo: 200 - NO_AP_FOUND
... quando a recepção deve estar ok novamente, leva cerca de 2 minutos até que diga:

[D] [WiFiGeneric. cpp: 265 ] _eventCallback (): Evento: 8 - STA_WPS_ER_SUCCESS

No entanto, ele permanece desconectado da rede para sempre nesse estado.
WPS está desligado no meu AP. Não sei o que significa a mensagem de depuração.
Mesmo comportamento com dois APs diferentes e dois módulos WROOM32 diferentes, usando o esboço de exemplo wificlient. Não importa se WPA2 é usado ou rede aberta.
Pode enviar log do Wireshark no modo monitor, se necessário.

Em primeiro lugar, obrigado a todos por seu trabalho árduo no SDK. Eu me diverti muito desenvolvendo com ele e sou muito grato por todo o esforço que foi feito.

Também estou vendo esse problema. Acho que consegui diminuir um pouco. Estou usando este esboço muito pequeno que deve funcionar tanto no ESP8266 quanto no ESP32:

https://github.com/sidoh/esp32_reconnect_demo

Desativei a reconexão automática para ter mais controle das variáveis.

Configuração

  1. Testando em ESP8266 e ESP32
  2. Usando uma rede de ponto de acesso móvel. Tentei WPA2 PSK e redes abertas
  3. Permita que o MCU se conecte à rede e execute por alguns segundos. Eu adicionei um cliente NTP para verificar a conectividade.

Então tentei duas coisas diferentes:

(A) Destruir a rede, recriar imediatamente

Sob essas circunstâncias, a rede geralmente é recriada no momento em que o MCU percebe que ela está desconectada.

(B) Destruir a rede, esperar que o MCU perceba que está desconectado, recriar a rede

Observações

  1. O comportamento é o mesmo com WPA2 e redes abertas.
  2. O ESP8266 reconecta-se com êxito com (A) e (B).
  3. O ESP32 se reconecta no experimento (A), mas fica preso em (B).
  4. O ESP32 se reconecta com sucesso em (A) e (B) se: WiFi.disconnect(true); _and_ WiFi.begin(WIFI_SSID, WIFI_PASSWD); são chamados. Parece que ambos são necessários.
    \
    O parâmetro booleano wifioff para disconnect sendo definido como verdadeiro também parece necessário. Visto que WiFi.disconnect(true); parece limpar as configurações de WiFi, é necessário especificar novamente o SSID e a senha na chamada para begin .

Histórico

Todos eles estão em uma rede aberta. Estou omitindo os logs ESP8266, pois o comportamento era o esperado, mas posso fornecer se eles forem úteis.

ESP32, experimento (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, experimento (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, experimento (B) com desconexão (verdadeiro) + início (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

Embrulhar

Fiz algumas pesquisas no SDK, mas não vejo nada óbvio. Posso pesquisar um pouco, mas espero que as informações acima sejam úteis. Se houver qualquer outra informação que eu possa fornecer, por favor me avise; Eu ficaria mais do que feliz em atender.

Tentei obter alguns pcaps no modo monitor, mas não eram muito interessantes. Parecia que o ESP32 não estava enviando nada após a desconexão.

Estou feliz que pelo menos encontrei uma solução alternativa (desconectar (true) + iniciar (ssid, passwd)).

@vseven @Markusenz @sidoh
Desculpe responder mais tarde e obrigado por seu trabalho árduo no SDK.
O anexo é a versão de depuração do wifi lib, você pode usá-lo para fazer um teste, então podemos analisar seus logs para resolver o problema.
wifi_lib.tar.gz

@igrr - tentei abrir e proteger com os mesmos resultados. Posso tentar obter uma captura de pacote, mas o problema é extremamente aleatório. Isso pode acontecer 4 vezes em uma hora ou duas vezes por dia, portanto, a captura pode ser muito tediosa. Agora que várias pessoas estão tendo o mesmo problema, porém, vou tentar a versão de depuração que @zhangyanjiaoesp postou e se isso ainda não levar à solução, tentarei a captura de pacotes.

A reconexão automática será corrigida para funcionar conforme planejado? Parece que @sidoh está dando a volta por

Vou recompilar e carregar isso neste fim de semana.

EDIT: O arquivo wifi_lib.tar.gz está vazio. Você pode postar novamente?

Acho que a coisa mais interessante que notei foi:

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

sempre eventualmente se reconecta para mim (o parâmetro true para disconnect é importante). Acho que WiFi.disconnect(true) desliga o rádio. Meu palpite é que, em certas circunstâncias, algum estado sobre a rede à qual o ESP32 deveria se conectar é apagado e o procedimento acima o redefine.

Também interessante é que o problema parece ser 100% reproduzível ao desligar a rede wi-fi, esperar que o ESP32 perceba que foi desconectado e ligar a rede novamente. Se a rede reaparecer antes dos avisos do ESP32, às vezes é possível reconectar com êxito. A partir dos logs, a diferença parece ser que um evento NO_AP_FOUND é disparado no primeiro caso, mas não no último.

Execute novamente o código vinculado às bibliotecas de depuração. Registros aqui:

Tudo isso em uma rede aberta.

editar - link para logs brutos em vez da página principal.

@zhangyanjiaoesp - Alguma notícia sobre isso? Eu não tentei o código de depuração porque @sidoh já fez e já forneceu muitos logs, mas, novamente, já se passaram mais algumas semanas e nenhuma resposta real.

@sidoh
Em slow_ap_recreate.log , descobrimos que existem impressões semelhantes

[1513308152] ssid =
Tentar reconectar...

parece que seu ssid está vazio, então após escanear todos os canais, não retorne nenhum ap encontrado.
portanto, você deve verificar seu código para ver se o SSID está configurado corretamente.
screenshot from 2018-01-04 17-55-20

Olá @zhangyanjiaoesp ,

Acho que essa é provavelmente a essência do problema. No slow_ap_recreate.log , o código de reconexão está apenas fazendo (esboço completo aqui ):

WiFi.begin();

então não está fornecendo um AP. Meu entendimento do SDK é que ele deve apenas se reconectar ao último AP conhecido. Talvez, se não conseguir encontrar o último SSID usado, ele limpe a configuração? Isso é esperado?

Usar isso parece sempre funcionar:

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

editar - apenas para ter certeza de que a configuração está clara, o caso em que a reconexão não está funcionando é quando o AP desaparece por tempo suficiente para que o SDK decida que ele foi removido. Talvez esse seja o comportamento esperado.

@sidoh Sim, você está certo. Este é o comportamento esperado, você pode contorná-lo com seu método:

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

Eu vejo, isso faz sentido. Vou tentar reproduzir sem o WiFi.begin() nos próximos dias. Acho que a coisa certa é apenas ter a reconexão do identificador do SDK.

Onde a reconexão é tratada no SDK? A única referência que posso encontrar está aqui , que parece usar WiFi.begin() . Isso é esperado?

sim você está certo

Isso não significa que as reconexões de tratamento do código SDK teriam o mesmo problema que minha demonstração? Se ele tentar se reconectar após o AP ter desaparecido, o SSID será limpo e não será possível reconectar a menos que as informações do AP sejam fornecidas novamente.

definitivamente, o SDK deve tentar se reconectar automoticamente. Esse é o objetivo de ter WiFi.setAutoReconnect (true).

@everslick - Concordo totalmente, não parece funcionar, e é por isso que postei isto originalmente há mais de 3 meses. O WiFi.setAutoReconnect (true) não parece fazer com que ele se reconecte, o que é irônico para dizer o mínimo. A única coisa que funciona é reiniciar o controlador e deixá-lo voltar por sua conexão normal (o que não vai funcionar para mim ao controlar os LEDs quando eles desligam) ou fazer a desconexão completa e reconectar.

@zhangyanjiaoesp - Então você está dizendo que WiFi.setAutoReconnect (true) simplesmente não funciona? E para contornar temos que ligar para o desligamento e reconectar com o SSID e senha novamente? Se isso for verdade, isso será corrigido ou pelo menos a documentação será atualizada para dizer que não funciona?

Eu tenho um problema parecido,
Depois de redefinir pelo software usando a seguinte sequência:
WiFi.disconnect (); // Certifique-se de que o ssid / senha atual seja apagado
atraso (1000);
ESP.restart ();
O ESP é reinicializado, mas nunca se conecta ao AP até uma reinicialização do hardware.
A função Wifi.disconnect () também não está funcionando corretamente.
Robert

A maneira mais difícil é conectar um pino GPIO ao EN e forçar uma reinicialização do sistema (GPIO baixo) caso seja necessário reiniciar / reiniciar ou (re) conexão wi-fi.

Não faça a desconexão. Basta reiniciar funciona para mim. Mas, novamente ... não deve ser necessário reiniciar se WiFi.setAutoReconnect (true) funcionou corretamente.

Deve ser bom ter o Wifi.disconnect ou autoreconnect funcionando, mas qual é o ponto, se houver um problema de conexão Wifi, este é um dos principais no caso do ESP32 (todos os aplicativos subsequentes provavelmente dependem do Wifi), então a solução definitiva é tentar um reset de hardware, se este falhar ... tchau, uso do ESP32.

Reinicializar NÃO é uma solução. Estou usando isso para o controle de LED RGB e a reinicialização apaga as luzes. Se houver uma função que diga ao ESP que se ele perder o WiFi, ele deve continuar tentando se conectar, então essa função deve realmente funcionar conforme documentado.

OK, tentei reiniciar o ESP através de um GPIO, mas parece que o ESP não gosta de suicídio, por isso não funciona sem um dispositivo externo. Portanto, concordei que a única solução que restava é que a desconexão do WiFi, a reinicialização do ESP ou a reconexão automática do WiFi estão realmente funcionando.
Outro problema para o qual temos que esperar por um módulo ESP funcional (noto que até onde pude testá-lo, o protocolo I2C é outro para o qual estou aguardando uma solução).
ESP32 está longe de ser confiável até agora ....
Robert

e não mencionei a interface SPI ...

esp_restart_noos ();

Para quando ESP.restart () não funcionar.

Estou usando o IDE do Arduino para configurar um WeMos Lolin32.
Eu uso a função:

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

Quando o WeMos está conectado em WiFi.mode (WIFI_STA), eu chamo essa função do MQTT.
Na verdade, ele reinicia o sistema e o esboço começa, mas Wifi (não é possível sincronizar a partir desse ponto, as tentativas de conexão seguem em um loop infinito). Uma redefinição manual resolve isso.
No entanto, funciona a mesma função chamada com WiFi.mode (WIFI_STA) via telnet.

@vseven @everslick @rrobinet
Você entendeu mal o significado da função WiFi.setAutoReconnect(true) .
Em nosso código, WiFi.setAutoReconnect(true) não significa reconectar wi-fi utomoticamente. Isso significa que se o ESP32 já se conectou ao wi-fi antes, quando o sistema reiniciar da próxima vez, ele conectará o último wi-fi conectado.
Portanto, adicionaremos alguns comentários no código. Desculpe ter afetado seu trabalho.

@zhangyanjiaoesp Desculpe por dizer isso: Isso é simplesmente "errado". Essa API foi introduzida para o ESP8266 e fez exatamente isso: reconectar wi-fi automaticamente. O que você descreve é ​​o que o WiFi.setAutoConnect (); método é para. Você não pode alterar a semântica de uma API bem estabelecida à vontade.

Além disso, mesmo quando a API foi criada para funcionar como você disse, a nomenclatura da função seria incrivelmente ruim e enganosa.

De qualquer forma. Estamos falando de dispositivos IoT aqui. O padrão deve ser permanecer conectado à rede de qualquer maneira. Se houver alguma coisa, deve haver funções para desabilitar reconexões automáticas e não exigir que o usuário da API passe por muitos obstáculos para fazê-lo se comportar dessa maneira.

@vseven @everslick @rrobinet
Por favor, olhe aqui , ele diz ao usuário que esta função funciona quando ligado.

ESP.restart problema, correção.
Bem, o script acima estava funcionando com um ESP8266 e não com um ESP32, porém após alguns testes, o problema é o uso do WiFi.disconnect (true), antes do ESP.restart (). Esta função para ESP32 deve ser colocada na inicialização Wifi (consulte https://github.com/espressif/arduino-esp32/pull/466)
Algo como:

<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>

e a redefinição da unidade deve ser simplesmente:

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

Você pode confirmar o seguinte, que entendi até agora ao ler este tópico:

  • O ESP32 se comporta de maneira diferente do ESP8266, de modo que com o ESP32 não há reconexão automática do wi-fi durante o tempo de execução, caso o AP seja perdido ou inacessível por algum tempo. O usuário deve detectar a perda de wi-fi e lidar com a reconexão em seu código (não é possível sem reiniciar o dispositivo ??)
  • O ESP32 se comporta de maneira diferente do ESP8266 porque, após a inicialização, às vezes não se conecta ao AP. Precisamos de certas linhas de código para corrigi-lo, como aqui https://github.com/espressif/arduino-esp32/issues/653#issuecomment -356534618
  • os problemas descritos são vistos como comportamento esperado e não se destinam a alterar o comportamento na API, portanto, temos que adaptar nosso código de acordo ao trabalhar com ESP32

@Markusenz , posso confirmar que https://github.com/espressif/arduino-esp32/issues/653#issuecomment-355659659 parece sempre funcionar para mim. Parece que a única referência a getAutoReconnect é o link que colei no comentário, que não controlaria bem as desconexões, se é que tudo.

@zhangyanjiaoesp , obrigado pela ajuda nisso. :)

Você entendeu mal o significado da função WiFi.setAutoReconnect (true).
Em nosso código, WiFi.setAutoReconnect (true) não significa reconectar wi-fi utomoticamente. Isso significa que se o ESP32 já se conectou ao wi-fi antes, quando o sistema reiniciar da próxima vez, ele conectará o último wi-fi conectado.

O método ao qual você vinculou é setAutoConnect , não setAutoReconnect . Acho que esses métodos são diferentes. setAutoReconnect está aqui . Isso apenas define um sinalizador, e acho que o único lugar em que esse sinalizador é usado é aqui .

Dado o nome do método, e como esse sinalizador está sendo usado internamente, parece que esse método deve fazer o que as pessoas estão assumindo - habilitar / desabilitar tentativas automáticas de reconectar a um AP após uma desconexão.

Minha opinião é que esse recurso simplesmente não está funcionando conforme o esperado e acho que é possível porque internamente o SDK está usando WiFi.begin() , que limpará o SSID se o AP salvo não existir, como descobri acima.

Então é assim que parece estar acontecendo. O SDK pode ser atualizado para NÃO limpar o AP se ele não o vir instantaneamente. Ou fazer um WiFi. Comece usando o último SSID e senha conhecidos se WiFi.setAutoReconnect (verdadeiro) ou estou faltando alguma coisa?

Se meu pensamento / escavação estiver correto, eu realmente duvido que esse comportamento seja intencional ou esperado. Parece provável que setAutoReconnect tenha a funcionalidade que as pessoas neste tópico esperam, e tem apenas alguns bugs.

Minha sugestão seria contornar isso por enquanto. No meu próprio projeto, acabei de anexar um manipulador de eventos que faz

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

E funciona para mim.

Parece que a reconexão está sendo tratada pelo Arduino SDK, e não pelas coisas subjacentes. Com o ESP8266 Arduino SDK, a reconexão é feita pelo SDK não-SO. Portanto, uma correção para o ESP32 Arduino SDK provavelmente se parecerá muito com essa solução alternativa externa (novamente - presumindo que meu pensamento esteja correto. Eu certamente poderia estar errado).

editar - aqui está a seção relevante em meu código que trata da reconexão.

@Markusenz
você está certo.
@vseven @sidoh
Eu concordo com @sidoh , você pode contornar isso por enquanto. Implementaremos a função de conexão automática e sabemos a importância desse problema, mas precisamos de tempo para fornecer a você uma solução perfeita.

Após algumas pesquisas, descobri que isso funcionava muito bem:

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

No manipulador de eventos WiFi para SYSTEM_EVENT_STA_GOT_IP, você deve definir sta_was_connected como true.

Isso também funcionará quando o ponto de acesso não estava disponível quando o ESP32 foi inicializado.

A vantagem é que ele não limpa a configuração do STA. Isso é especialmente útil se você definiu uma configuração de IP estático (sem usar DHCP).

você consegue um
[D][WiFiGeneric.cpp:293] _eventCallback(): Event: 8 - STA_LOST_IP
se você esperar o tempo suficiente (há um atraso)

Vou tentar

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

Aqui está uma solução de trabalho que contorna alguns problemas com a biblioteca WiFi.
Observe os loops while após um WiFi.begin ().
Descobri que o atraso da conexão varia dependendo do roteador e das configurações de criptografia, AES, WPA2 parecem melhores, mais rápidos e mais confiáveis.

Para esse fim, esperar até saber se uma conexão funcionou, mas certificando-se de não travar, praticamente o faz.

Observei que alguns estão chamando WiFi.disconnect (). Tenha cuidado ao usar WiFi.persistent (false); com ele ou toda vez que você se recuperar, você está reescrevendo o NV FLASH e o bloqueará quando o FLASH morrer.

AMOSTRA PARCIAL DE CÓDIGO

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

======
leva em média 8-15 segundos para detectar a mudança de modo
observe que "." está conectando
"C" estão conectados

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

Estou usando isso, parece funcionar para mim

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

Acho que meu apartamento com 50 APs próximos é realmente um ótimo lugar para testar esse problema. A solução do tablatronix faz com que meu esp32 seja descartado e não vejo como a solução de mickeypop faria bem, o que não ajudou. Descobri que reiniciar a conexão wi-fi funciona muito bem, mas mesmo isso requer uma reinicialização do hard power de vez em quando. Por outro lado, tenho um esp8266 no mesmo ambiente que nunca requer qualquer intervenção manual. Tentei algumas outras sugestões aqui sem sorte.

Acho incrível todo o desenvolvimento feito. Francamente, não tenho as habilidades necessárias para encontrar uma solução. Se alguém tiver algo que deseja experimentar em um ambiente hostil, sinta-se à vontade para me enviar testes. Nós realmente precisamos que o esp32 tenha uma conexão sólida e lide com wi-fi intermitente normalmente.

Edit: depois de tentar muitas coisas: @tablatronix Se eu rodar essa linha muito rápido ela trava / dá backtrace. Ligar a cada poucos segundos não me deu problemas. Agora, para deixá-lo rodar por alguns dias para ver o que acontece
if(WiFi.getAutoReconnect()) WiFi.onEvent(WiFiEvent);
Edit2: durou 30 minutos antes de cair

@thefatmoop Encontrei um problema de reconexão de Wi-Fi que acabou sendo um problema de corrupção de NVS. # 1147 Reescrevi um esboço para despejar os dados nvs. Experimente e capture o resultado. Pode mostrar algo.
Mostrar chaves NVS

Mandril.

thefatmoop

Ambas as soluções devem funcionar.
Como eu observei; "_Aqui está uma solução de trabalho que contorna alguns problemas com a biblioteca WiFi._"

Enquanto um ignora alguns problemas da biblioteca, o outro usa o serviço WiFi.onEvent () , ambos simplesmente detectam quando uma conexão é interrompida e reiniciam uma nova conexão.

Embora alguns tenham notado depois de várias horas que continuam sofrendo choques, isso quase certamente é uma função do tempo de aluguel do servidor DHCP no roteador.

Se o tempo de aluguel do roteador não for o mesmo, às vezes os dispositivos "esquecem" de atualizar, causando um não endereço IP, embora às vezes a conexão WiFi ainda esteja lá.

  • WiFi.begin () força o DHCP a obter um novo IP junto com uma nova conexão.
  • WiFi.reconnect () funciona, mas geralmente assume que a unidade ainda tem um IP e pode não fazer uma solicitação de DHCP.

A maneira simples de contornar isso é fazer ping no roteador DHCP periodicamente.
Isso força o roteador a saber que você ainda está na rede e manter o lease atualizado.

A reinicialização pode reconectar, mas não resolve o PORQUÊ de ser desconectado e, muitas vezes, os aplicativos podem ficar fora de sincronia se você simplesmente reiniciar.

Portanto, reconectar sem reinicializar geralmente é uma necessidade.

reconectar não refaz dhcp, descobri isso ao tentar mudar o nome do host e reconectar, ia arquivar como um bug.

A solução de @tablatronix está funcionando para mim, obrigado! @thefatmoop você pode verificar a implementação no código OpenMQTTGateway.ino .

O código é chamado após a desconexão MQTT, se eu colocar o código fora dessa condição, o despejo ESP de fato.

Se WiFi.reconnect() reconectar, mas o cliente MQTT não, você pode fazer outro setup_wifi() : com disconnect (), delay () e begin (), após algumas tentativas de reconexão do cliente e funciona muito bem dentro do novo conexão. Mas o que acontece quando o servidor MQTT está inativo?

Isso é um problema de nível de aplicativo.

Adicionada proposta de código mickeypop ao Wiki

Desculpa. Sou um iniciante em programação arduino / esp. Também estou enfrentando bugs / problemas de conexão e reconexão wi-fi. Minha parte do código que gerencia o cliente WiFi e MQTT (PubSubClient) e que realmente funciona em um ESP32 de Adafruit / Huzzah32:

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

Testado com algumas reinicializações do roteador e o código parece funcionar sem a necessidade de reinicialização do ESP.
Você tem alguma sugestão muito melhor?

Este problema está me matando. Está acontecendo aleatoriamente, às vezes na primeira hora, às vezes depois de seis horas, durante a execução sem problemas. Tentei todos os tipos de configurações e nenhuma delas é confiável. Reiniciar o ESP por software ou hardware é o último recurso que realmente funciona, mas não é uma solução viável para o meu produto.

Da última vez, eu o deixei funcionando e tentei mais de QUATRO MIL tentativas, nenhuma delas com sucesso.

Eu tentei até agora:

1) Ativando autoReconnect e chamando reconectar
2) Desativando autoReconnect e manualmente desconectando e reconectando. Nesta configuração tentei os dois métodos de desligar completamente a antena ou não. Não funciona em nenhum modo.

Aqui você tem alguns registros (na verdade, está em execução agora com mais de 600 tentativas de reconectar em um roteador funcionando perfeitamente (TP-LINK):

AVISO: conexão sem fio perdida. Tentando tentativa de reconexão 632 na próxima iteração
Ativando tentativa de reconexão WiFi 632
I (14944038) wi-fi: modo: softAP (30: ae: a4: 1a: ca: 1d)
Criando WiFi com SSID 'Nano BAB - Development' e senha '########'
Conectando-se ao WiFi 'TP-LINK_A8FB38'
[D] [WiFiGeneric. cpp: 293 ] _eventCallback (): Evento: 3 - STA_STOP
[D] [WiFiGeneric. cpp: 293 ] _eventCallback (): Evento: 2 - STA_START
Evento [evento WiFi]: 2
[D] [WiFiGeneric. cpp: 293 ] _eventCallback (): Evento: 5 - STA_DISCONNECTED
[W] [WiFiGeneric.

Como você pode ver, está falhando na autenticação, porém a senha está correta. Em alguma tentativa anterior (número 578 !!) do mesmo exemplo está levantando o erro 2:

AVISO: conexão sem fio perdida. Tentando tentativa de reconexão 578 na próxima iteração
Ativando tentativa de reconexão WiFi 578
I (14134199) wifi: modo: softAP (30: ae: a4: 1a: ca: 1d)
Criando WiFi com SSID 'Nano BAB - Development' e senha '##########'
[D] [WiFiGeneric. cpp: 293 ] _eventCallback (): Evento: 3 - STA_STOP
Evento [evento WiFi]: 3
Conectando-se ao WiFi 'TP-LINK_A8FB38'
[D] [WiFiGeneric. cpp: 293 ] _eventCallback (): Evento: 13 - AP_START
[Evento WiFi] evento: 13I (14134890) wifi: modo: sta (30: ae: a4: 1a: ca: 1c) + softAP (30: ae: a4: 1a: ca: 1d)
[D] [WiFiGeneric. cpp: 293 ] _eventCallback (): Evento: 2 - STA_START *

[Evento WiFi] evento: 2 [D] [WiFiGeneric.cpp: 293] _eventCallback (): Evento: 2 - STA_START
[Evento WiFi] evento: 2I (14137748) wi-fi: ajuste de canal ap o: 1,1 n: 6,1
I (14137749) wi-fi: n: 6 1, o: 1 0, ap: 6 1, sta: 6 1, prof: 1
I (14138422) wi-fi: estado: init -> auth (b0)
I (14139423) wi-fi: estado: auth -> init (2)
I (14139424) wi-fi: n: 6 0, o: 6 1, ap: 6 1, sta: 6 1, prof: 6
[D] [WiFiGeneric. cpp: 293 ] _eventCallback (): Evento: 5 - STA_DISCONNECTED
[W] [WiFiGeneric.

É sempre um dos dois erros. No final das contas é simplesmente que ele não se reconecta.

O engraçado é que posso desconectar manualmente o roteador puxando o cabo de alimentação por alguns minutos, meu código detecta a desconexão e começa a tentar novamente e, em seguida, meu sistema se reconecta OK quando voltar, no entanto, se o roteador estiver funcionando normalmente, esse problema eventualmente acontece e o O ESP simplesmente não se reconecta.

A propósito, estou executando com:

Executando no SDK: 'v3.1-dev-239-g1c3dd23f-dirty'
Freqüência da CPU: 240 MHz
WiFi criando seu próprio WiFi privado e conectando-se a outro com acesso à internet

Quando foi a última vez que você retirou do repo?

1132

você apenas postou logs, nenhum esboço ou solução de reconexão.

A última vez foi cerca de uma semana ou mais. Minha versão do SDK é 3.1-dev-239.
Desculpe, não adicionei o código porque basicamente testei todas as soluções do post. No início, chamo algo semelhante a:

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

Então, eu lido com eventos WiFi e especialmente o evento

1) Quando a reconexão automática de Wifi foi habilitada, deixei o sistema para realizar a reconexão
2) Tentei desabilitar a reconexão automática e, nesse evento, chamar
3) O último que estou tentando desconectar desligando o rádio e conectando novamente se nenhuma outra desconexão o acionou. Eu tenho algo como:

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

needsReconnection é um sinalizador que é verificado no loop principal e dispara novamente a conexão, basicamente executando as primeiras 3 linhas de código.

Espero que faça sentido agora ;-)

Não tenho certeza se existe outra maneira de fazer isso.

Esqueci de mencionar que estou executando um servidor mongoose para implementar uma API Rest, permitindo no máximo 3 conexões simultâneas. Não tenho certeza se essa poderia ser a causa disso.

  1. Não há reconexão automática, é para isso que serve esse problema.
  2. WiFi.reconnect pode não ser o mesmo que desconectar, começar () (dhcp etc)
  3. Isso pode ser específico do modo, sem código, ninguém sabe o que você está fazendo, nenhuma ideia de como você está lidando com eventos ou "desligando o rádio"

Eu sugeriria puxar as mudanças e fazer um caso de teste simples.

josmunpav

seu problema pode ser do modo WiFi

seu código

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

Você está executando modos mistos.
WiFi.softAP () ; o padrão é o modo WIFI_MODE_AP

WiFi.begin (); o padrão é o modo WIFI_AP_STA

se você continuar com o modo WIFI_MODE_APSTA (modo misto), eles não devem mudar e o EVENTO WiFi não se confundirá com modos diferentes.

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

REF INFO
em 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;

em 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;

Oi mickeypop ,

Estou testando sua solução de:


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

Estou chamando WiFi.reconnect () quando acontece o evento SYSTEM_EVENT_STA_DISCONNECTED , que tentei desconectar manualmente o roteador e parece estar funcionando (essa parte também funcionou antes).

Até agora ele tem trabalhado durante 7 horas sem parar em 2 ESP32 diferentes. Eu tenho pingado eles a cada 5 segundos e nenhum problema até agora. Não conseguia imaginar que a declaração de modo misto pudesse ser o motivo, pensei que ela foi ativada automaticamente ao chamar WiFi.begin e WiFi.softAP () . Dedos cruzados. Vou começar agora com testes mais pesados ​​para confirmar se é a solução para os problemas que estou enfrentando.

A propósito, MUITO OBRIGADO !!

@mickeypop @josmunpav obrigado por compartilhar suas descobertas.
Eu adicionei ao Wiki

Isso não faz sentido, isso indica que há um bug no enablesta ou no enableoftap se o modo de configuração muda antecipadamente o resultado. É por isso que sugeri que este é um modo específico, soluções alternativas não devem ser necessárias. Então, o código de reprodução seria bom

Muito disso não faz sentido, como @everslick claramente apontou acima: https://github.com/espressif/arduino-esp32/issues/653#issuecomment -356515973. Na verdade, não posso acreditar que postei isso há 6 meses e ainda estava falando sobre isso quando, para começo de conversa, nunca deveria ter sido um problema.

Por que algo é chamado de "autoReconnect", mas não se reconecta automaticamente, é intrigante. Todo mundo parece estar criando seu próprio código para superar essa deficiência / bug. Vou puxar uma nova cópia do código e fazer um reflash de acordo com a sugestão de

Pessoalmente, ainda estou tendo problemas com o bloqueio completo do chip ocasionalmente, quando entra neste ciclo de desconexão. Eu tenho que contar até 10 e reiniciar, mas aleatoriamente (1 em 15 ou mais reinicializações), ele não reinicia e apenas bloqueia o disco que requer uma reinicialização a frio. Eu mudaria para o ESP8266 em um piscar de olhos se ele tivesse melhores / mais entradas analógicas, mas infelizmente não tem. Não que o ESP32 seja muito bom nisso (https://www.esp32.com/viewtopic.php?f=19&t=2881).

No esp8266 o autoreconnect é implementado no SDK, no esp32 não há implementação, então ele foi adicionado à biblioteca para trazer alguma forma de compatibilidade, embora seja implementado apenas para WIFI_REASON_AUTH_EXPIRE .

Pode ser implementado, mas precisa ser resolvido, e esta biblioteca ainda é alfa, então realmente não deve haver expectativa, o SDK está sujeito a alterações, todo o sistema de eventos está sujeito a alterações. Portanto, a implementação de recursos essenciais como esse leva tempo.

Para não mencionar, se espressif implementa isso no SDK, então nós simplesmente perdemos nosso tempo.

Quando digo que precisa ser resolvido, quero dizer que há várias questões pendentes que precisam ser resolvidas. É por isso que peço esboços de teste para pessoas em que a solução do evento acima está falhando.

  • reconectar, pode falhar, perder atribuição de dhcp, ao contrário de desconectar (), começar () **
  • a autoconexão causa a emissão errada de wl_status e um loop infinito
  • sdk emite auth_expire para auth_fail em alguns roteadores, acionadores acima
  • esp_wifi_set_mode é assíncrono, condições de corrida
  • autoconectar, nem funciona, https://github.com/espressif/arduino-esp32/issues/173

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

Se estiver usando minha solução alternativa acima, sugiro desativar a reconexão automática para evitar 2 desses bugs.

Olá pessoal, estou de volta com uma amostra que reproduz os problemas que estou enfrentando. O exemplo está cheio de comentários, mas consiste basicamente em:

  1. Duas tarefas: principal e web / wi-fi (implementado pela biblioteca mongoose 6.11)
  2. Alguns objetos compartilhados para fazer tarefas fictícias, como definir PWM em um pino, ler o valor ADC médio e um contador interno compartilhado
  3. Uma página de teste em http: // your_esp32_ip / que você pode deixar em execução e
  4. Um semáforo para evitar corrupção de dados entre tarefas. A tarefa principal faz alterações no pino pwm, lê do ADC e aumenta o contador. A tarefa da Web apresenta esses dados na página inicial.
  5. Métodos WiFi típicos para conectar, desconectar e manipular eventos WiFi.
  6. Ele é executado no modo APSTA, então você precisa configurar seu próprio WiFi (seu WiFi precisa de conexão com a internet, pois a página inicial da web usa jQuery de um CDN para fazer chamadas de API implementadas pelo ESP32 no exemplo)

O que descobri até agora é que, se você desabilitar as tarefas fictícias (há um sinalizador para isso), ambas as tarefas funcionam bem indefinidamente. Se você ativá-los, eventualmente (às vezes pode levar horas, mas normalmente acontece na primeira hora) o ESP32 se desconecta do WiFi e não pode se reconectar, executando a tentativa de conexão a cada 10 segundos sem sucesso o tempo todo.

Acho que há alguma interferência entre a biblioteca ADC ou PWM (implementada por esp32-hal-ledc.h ), porque não consegui reproduzir o problema quando a tarefa principal não faz nada além de fazer uma espera fictícia.

Outra coisa que notei é que quando acontece a desconexão o sinal WiFi para o AP diminui muito. Eu verifiquei isso no meu smartphone.

Estas são as mensagens de log de WiFi típicas que você pode encontrar quando ele falha:

[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

Encontre o código-fonte e as páginas de amostra em anexo:

working
not_working

ESP32_APSTA_Mode_Disconnection_Test.zip

PS: Meu aplicativo real está fazendo o mesmo. Iniciar o modo APSTA com duas tarefas, uma para atualizar sensores, dispositivos e GPIOS e a segunda para lidar com WiFi e o servidor web implementado pelo mangusto e enfrentando o mesmo problema.

Eu construí este sketch para testar a conexão, obter tempo a cada 10 segundos 10 vezes, desconectar wi-fi, reconectar wi-fi. Parece funcionar muito bem, então estou implementando meu outro código para ser executado por alguns dias porque estava tendo problemas de reconexão.

#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!"));
  }
}

.... obrigado pela dica de código @tablatronix

Use o código cerca três ticks nova linha antes e depois

Aqui está uma informação interessante. Tentei todos os truques mencionados neste tópico e nada funcionou. No entanto, sempre que instalo e executo o SimpleWiFiServer, as coisas são reiniciadas e, em seguida, posso reinstalar meu aplicativo e tudo funciona novamente.

Meu aplicativo se conecta perfeitamente ao WiFi e em algum momento (dias ou semanas) ele perde a conexão e nada pode fazer com que ele se conecte. Eu tentei todos os truques neste tópico e nada. Como eu disse acima, a única maneira de fazer meu ESP32 se conectar novamente ao Wifi é instalando este outro aplicativo para redefinir as coisas. Eu me pergunto o que isso faz com que meu ESP32 funcione novamente com wi-fi.

@gdombiak , você tem alguma informação de depuração para mostrar o que o ESP32 está fazendo quando trava? Tive um problema recente em que um dos meus esboços funcionou como um campeão, exceto quando o novo dia chegou e havia duas linhas que o colocaram em um loop contínuo e o ESP finalmente se desligou até que eu reiniciei ou recarreguei. Outro problema que tive foi que tinha outro ESP que estava funcionando como AP_STA e ficava tentando se conectar a ele em vez do WiFI normal. Tive que recarregar o outro ESP e estipular WiFi.mode (WIFI_STA) para consertar isso.

@AIWIndustries

Confira uma postagem que coloquei em: https://github.com/espressif/arduino-esp32/issues/1100
Procure por " esqueleto SmartConfig / WiFi "

Eu escrevi um esqueleto completo que; salva, definido com SmartConfig, lida com WiFi UP e DOWN, reconecta automaticamente se Down.

É uma estrutura completa e sempre se reconectou quando o WiFi caiu ou apenas desconectou por motivos desconhecidos.

Anote em loop () para " // WiFi DOWN ". Eu uso um if () / else simples para rastrear o status do WiFi.
Por causa das bibliotecas espressif, leva cerca de 30-40 segundos para relatar quando o WiFi está desligado e, em seguida, começa a tentar reconectar.

Se o AP for desligado e ligado novamente, leva cerca de 30 segundos para o AP inicializar e outros 15 segundos para reconectar, mas sempre reconecta.

@AIWIndustries

Existe uma maneira de pesquisar um travamento se o Traceback for impresso no terminal.

Instale o "Descodificador de exceção ESP" a partir de; https://github.com/me-no-dev/EspExceptionDecoder
As instruções estão aí.

Depois de instalado, basta copiar e colar a linha de rastreamento e ela dirá o que está acontecendo no bloqueio.

Olá a todos,

O código a seguir está funcionando para mim.

void wifiReconnect () {
enquanto (WiFi.status ()! = WL_CONNECTED) {
WiFi.begin (ssid, senha);
para (int i = 0; i <= 50; i ++) {
digitalWrite (LED_BUILTIN, HIGH);
atraso (100);
Serial.print (".");
digitalWrite (LED_BUILTIN, LOW);
atraso (100);
}
}
}

Use isso no loop () como

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

Olá a todos
Eu estava usando o núcleo ESP32 atualizado há cerca de 2 meses.
No meu programa eu uso Wifi.begin (ssid, pass) em setup () e chamando o método WiFi.reconnect () no evento "SYSTEM_EVENT_STA_DISCONNECTED". O sistema estava se conectando automaticamente se houver alguma desconexão. Mas ontem eu atualizei para o núcleo mais recente e começou a dar erro com o código de razão 8.
Depois de alguns acessos e tentativas, comentei WiFi.reconnect () e começou a funcionar perfeitamente. Além disso, o wi-fi se reconecta automaticamente se o AP estiver desligado e ligado.

No meu caso, apenas no método de configuração que estou usando
WiFi.mode (WIFI_STA);
Wifi.begin ()

isso está funcionando corretamente.
Podemos dizer que no novo núcleo não há necessidade de chamar reconnect () e autoreconnect agora está funcionando no núcleo mais recente?

corrigir. não há mais necessidade de ligar para reconectar;) Eu consertei: P

Existe uma falha séria no wifi.Reconnect ().

Em uma análise aprofundada das bibliotecas que encontrei em várias condições, ele se conectará sem fazer uma atualização de DHCP, então você estará conectado sem um endereço IP. - Eu relatei, mas ainda não vi uma correção.

Eu provei isso uma vez, adicionando uma chamada UDP em algum código de teste. - Consegui falar com o AP por UDP mas não tinha endereço IP. Ao mesmo tempo, o MAC apareceu na lista de conexão do AP.

Você deseja usar wifi.begin () , é sempre confiável. - Você simplesmente deve ter certeza de que está desligado ao chamá-lo para conectar ou pode acabar com problemas de estouro de pilha.

_O modelo que escrevi abaixo nunca falhou ao reconectar._ Ele usa o SmartConfig e as preferências em vez de codificar o AP / Passe, embora isso possa ser facilmente alterado.

Parte do meu código é propriedade do pisca-pisca de LED, então deixei comentários no lugar. Você pode colocar qualquer código de indicador que desejar lá.

Dê uma olhada na parte inferior do wi-fi de loop (). Eu chamo WiFi.begin (PrefSSID.c_str (), PrefPassword.c_str ()); enquanto sempre testa um status de retorno de WL_CONNECTED.

Espero que isso ajude um pouco.

// 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()

Percebi isso também, mas nunca reduzi, mas percebi que reconectar () e iniciar (ssid ..) nem sempre zera dhcp, caso extremo eu acho

Begin (args)
apenas refaz dhcp se config não for igual ou já não estiver conectado, caso contrário, ele retorna, o que pode ser um problema.

    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 obrigado por compartilhar o código. Mas tenho uma dúvida.
Como você disse:
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.

mas até onde eu sei, não podemos fazer conexão UDP sem ter um IP. UDP é construído na camada IP.

@jjassar

O UDP não requer nenhum IP, apenas seu próprio MAC.

UDP é onde está a mágica do SmartConfig. O aplicativo em sua célula envia um pacote UDP especialmente formatado apenas para o ESP32 com as credenciais do AP.

Como o UDP não tem conexão, todos os dispositivos WiFi dentro ou fora do AP podem vê-lo.

Quando o ESP32 vê isso, ele envia um UDP diferente ao AP para obter uma conexão e o endereço IP do AP. Lembre-se antes de conectar não há IP.

UDP é a camada inferior usada no DHCP para obter o IP em primeiro lugar, mas também é usado de muitas outras maneiras.

@mickeypop é possível que você esteja misturando TCP / UDP com broadcast / multicast?
O TCP e o UDP residem na camada de transporte, que é construída sobre a camada da Internet, onde está o IP.

@mickeypop @bedenko vocês dois podem estar certos, eu acho, pode ser uma transmissão UDP no endereço 255.255.255.255.
De qualquer forma, encontrei um novo problema com o repo mais recente.
Estava tendo um esp32 que estava conectado ao AP, desliguei o AP e troquei depois de algum tempo.
Na desconexão, se o código de razão for 201 (REASON_NO_AP_FOUND), ele se conecta automaticamente
Mas às vezes o código de razão da desconexão 7 (REASON_NOT_ASSOCED) então ele nunca se conecta de volta, somente reconecta após a reinicialização do hardware.
Por que o código de razão 7 está chegando se eu desliguei o AP?

Provavelmente, porque o código 201 foi removido aqui , mas o código 7 foi ignorado.

@jjassar @bedenko

Pense nisso por um momento.
Deve haver um protocolo para conectar ANTES do dispositivo ter um IP, caso contrário o DHCP não teria nenhum meio de contatar o servidor DHCP para "obter" um IP.

Fui engenheiro de rede por mais de 30 anos e se o UDP não fosse parte integrante do TCP / IP, você teria que reconfigurar os IPs toda vez que mudasse para outra rede.

aqui está um pequeno manual.

PROTOCOLO DHCP

_O protocolo DHCP é um protocolo sem conexão que usa UDP_ Portas 68 e 67. Ele opera no modelo cliente e servidor. O cliente DHCP é o nosso dispositivo (viajante) e o servidor DHCP é quem nos fornecerá o IP (o hospedeiro).

O DHCP opera em UDP porque o cliente DHCP funciona em broadcasts, que só podem ser suportados por UDP. Isso é necessário porque a máquina cliente ainda não recebeu um endereço IP (este é o propósito do protocolo de negociação DHCP) e não haveria nenhuma maneira de estabelecer um fluxo TCP sem o próprio endereço IP.

O cliente DHCP começa transmitindo o pacote DHCP DISCOVER. A transmissão é recebida pelo (s) servidor (es) DHCP, que por sua vez responde com a mensagem DHCP OFFER. A mensagem DHCP OFFER contém o endereço IP oferecido pelo servidor e o período de tempo para o qual o endereço IP é alocado (o IP pode ser aleatório ou baseado em uma política administrativa).

O cliente DHCP pode receber várias mensagens de OFERTA DHCP, no entanto, ele escolhe apenas uma mensagem de OFERTA DHCP com base na política configurada no Cliente DHCP. Normalmente é na base de ordem de chegada. No entanto, podemos configurar o Cliente DHCP para escolher a OFERTA DHCP com o tempo de concessão mais longo ou alguma sub-rede preferida. O cliente DHCP agora responde com a mensagem DHCP REQUEST.

A mensagem DHCP REQUEST é uma mensagem de difusão. Quando outros servidores DHCP recebem essa mensagem, eles retiram quaisquer ofertas que possam ter feito ao cliente e retornam o endereço oferecido ao pool de endereços disponíveis. O servidor DHCP pretendido ao receber a mensagem envia uma mensagem DHCP ACK, confirmando assim a transação e alocando o IP ao host pelo período de tempo especificado.

@mickeypop : concordo com sua explicação, exceto pelo fato de que o UDP pode operar sem endereço IP. Todas as negociações de DHCP são feitas em broadcast IP 255.255.255.255 ( info ).

@bedenko
Você praticamente tem que concordar. Cortei e colei diretamente dos documentos oficiais.

Você está certo e errado e aqui está o porquê.

Todos os protocolos de rede usam a mesma estrutura de pacotes. AppleTalk, TCP / IP, Arpnet, AIX, etc ... Isso permite que eles coexistam na mesma ethernet sem conflito.

A estrutura inclui bits para protocolo, tipo, checksum, destino, etc ... Todos procuram os 24 (255.255.255.255) bits no identificador de destino como um Identificador Especial.

dito isto;

O tráfego IP é processado através de uma máscara de rede para que todos os dispositivos possam determinar se um pacote se destina a eles ou não, bem como o roteamento.

UDP não tem máscara de rede. O 255.255.255.255 não se destina ao remetente UDP ou mesmo usado por ele, é para que todos os outros dispositivos vejam o Identificador Especial. Ele não é tratado como um IP neste caso.

NOTA: o UDP envia por MAC, não por IP.

Pegue o DHCP, por exemplo, você ainda não tem IP ou máscara de rede, então o dispositivo entra em modo promíscuo procurando por qualquer pacote com seu próprio endereço MAC.

Um pacote DHCP DISCOVER é enviado por UDP com o endereço MAC do remetente, pois o servidor DHCP deve saber quem está solicitando um IP.

O remetente claramente ainda não pode processá-lo como tráfego IP e, para esse fim, o servidor DHCP não pode usar o IP para enviar uma resposta. Daí UDP.

A mensagem de OFERTA DHCP retornada pelo UDP deve incluir o MAC para que o cliente saiba que é para ele. Lembre-se de que todo o tráfego é estruturado da mesma forma, mas ainda não é IP.

Não é até que todas as negociações sejam concluídas que qualquer tráfego IP será possível.

=====
Separadamente, devo observar;
Eu estava na equipe em 1968-70 desenvolvendo o sistema operacional UNIX. É aí que surgiu o TCP / IP.
Usamos um rascunho do UDP antes mesmo de o TCP / IP existir.

@mickeypop Obrigado pelo seu trabalho! Todos nós podemos tocar o céu porque estamos sobre os ombros de gigantes!

Mandril.

Oi.
Eu uso este código para isso

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

e esta é a função "WIFI_Connect"

void WIFI_Connect ()
{
digitalWrite (26, ALTO);
WiFi.disconnect ();
Serial.println ("Reconectando WiFi ...");
WiFi.mode (WIFI_AP_STA);
WiFi.begin (ssid, senha);
// Aguarde a conexão
para (int i = 0; i <50; i ++)
{
if (WiFi.status ()! = WL_CONNECTED) {
atraso (500);
digitalWrite (26,0);
Serial.print (".");
atraso (500);
digitalWrite (26,1);
}
}
digitalWrite (26,0);
}

Para mim, esse código funciona.
Obs: A versão 2.3

incluir

incluir

definir WIFI_SSID "===="

definir WIFI_PASSWORD "==="

// este projeto do Firebase foi excluído
// você precisará inserir suas próprias informações de firebase

definir FIREBASE_HOST "home-automation-1122.firebaseio.com"

definir FIREBASE_AUTH "============"

definir LED1 5

definir LED2 4

definir LED3 0

definir LED4 2

definir LED5 14

definir LED6 12

definir LED7 13

definir LED8 15

void setup () {

pinMode (LED1, OUTPUT);

digitalWrite (LED1,0);

pinMode (LED2, OUTPUT);

digitalWrite (LED2,0);

pinMode (LED3, OUTPUT);

digitalWrite (LED3,0);

pinMode (LED4, OUTPUT);

digitalWrite (LED4,0);

pinMode (LED5, OUTPUT);

digitalWrite (LED5,0);

pinMode (LED6, OUTPUT);

digitalWrite (LED6,0);

pinMode (LED7, OUTPUT);

digitalWrite (LED7,0);

pinMode (LED8, OUTPUT);

digitalWrite (LED8,0);

Serial.begin (9600);

WiFi.begin (WIFI_SSID, WIFI_PASSWORD);

Serial.print ("conectando");

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

Serial.print (".");

atraso (500);

}

Serial.println ();

Serial.print ("conectado:");

Serial.println (WiFi.localIP ());

Firebase.begin (FIREBASE_HOST, FIREBASE_AUTH);

Firebase.setInt ("LEDStatus", 0);

}

void loop () {

if (Firebase.getInt ("field1"))

{

digitalWrite (LED1, LOW);

}

outro

{
digitalWrite (LED1, HIGH);

}
if (Firebase.getInt ("field2"))

{

digitalWrite (LED2, LOW);

}

outro

{

digitalWrite (LED2, ALTO);

}

if (Firebase.getInt ("field3"))

{

digitalWrite (LED3, LOW);

}

outro

{
digitalWrite (LED3, ALTO);

}

if (Firebase.getInt ("field4"))

{

digitalWrite (LED4, LOW);

}

outro

{

digitalWrite (LED4, ALTO);

}
if (Firebase.getInt ("field5"))

{

digitalWrite (LED5, LOW);

}

outro

{

digitalWrite (LED5, ALTO);

}
if (Firebase.getInt ("field6"))

{

digitalWrite (LED6, LOW);

}

outro

{

digitalWrite (LED6, ALTO);

}
if (Firebase.getInt ("field7"))

{

digitalWrite (LED7, LOW);

}

outro

{

digitalWrite (LED7, ALTO);

}
if (Firebase.getInt ("field8"))

{

digitalWrite (LED8, LOW);

}

outro

{

digitalWrite (LED8, ALTO);

}

//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 ()) // Verifique se há erros {

Serial.print ("configuração / número falhou:");

Serial.println (Firebase.error ());

Retorna;

}

meu nodemcu esp8226 não reconectar após a conexão ser perdida até que eu ligue

Este tópico é para esp32. Você está usando esp8266 ou foi um erro de digitação?

esp82255 nodemcu

Na terça-feira, 11 de setembro de 2018, 13:45 Bedenko, notificaçõ[email protected] escreveu:

Este tópico é para esp32. Você está usando esp8266 ou foi um erro de digitação?

-
Você está recebendo isso porque comentou.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/espressif/arduino-esp32/issues/653#issuecomment-420196435 ,
ou silenciar o tópico
https://github.com/notifications/unsubscribe-auth/ApKpJ7SS4fk4KrHA1sVKmwV7brGVeh93ks5uZ3gxgaJpZM4PfOia
.

Desculpe, é esp8266

Na terça, 11 de setembro de 2018, 13h48, Ijaz Ahmad, [email protected] escreveu:

esp82255 nodemcu

Na terça-feira, 11 de setembro de 2018, 13:45 Bedenko, notificaçõ[email protected] escreveu:

Este tópico é para esp32. Você está usando esp8266 ou foi um erro de digitação?

-
Você está recebendo isso porque comentou.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/espressif/arduino-esp32/issues/653#issuecomment-420196435 ,
ou silenciar o tópico
https://github.com/notifications/unsubscribe-auth/ApKpJ7SS4fk4KrHA1sVKmwV7brGVeh93ks5uZ3gxgaJpZM4PfOia
.

alguem aqui me ajuda?

Este segmento é para um ESP32, não um 8266. Tente um repo diferente.

você pode me ajudar por favor com 8226

@vseven como posso resolver esse problema?

@ ijaz1122 veja aqui se houver algum problema que seja adequado ao seu. caso contrário, abra um novo ali.
você está pedindo uma solução em um dispositivo diferente. este é o repositório errado para o seu problema.

Olá a todos, finalmente consegui colocar este código funcionando para conectar e reconectar meu wi-fi / hotspot portátil várias vezes

Obrigado a @ThiagoCas por seus códigos

`/ * * * * * * * * * * * * *
Incluir Bibliotecas
* * * * * * * * * * * * * * /

incluir

/ * * * * * * * * * * * * *
Definir constantes
* * * * * * * * * * * * * * /

define WIFISSID "== Seu Wifi SSID ==" // Coloque seu WifiSSID aqui

define PASSWORD "== Your Password ==" // Coloque sua senha wifi aqui

// constantes não mudam. Usado aqui para definir um número PIN:
const int ledPin = 2; // o número do pino do LED

/ * * * * * * * * * * * * *
Definir Variáveis
* * * * * * * * * * * * * * /
// As variáveis ​​mudarão:
int ledState = LOW; // ledState usado para definir o LED

intervalo interno = 100; // intervalo para piscar (milissegundos)

// Geralmente, você deve usar "unsigned long" para variáveis ​​que mantêm o tempo
// O valor rapidamente se tornará muito grande para um int armazenar
sem sinal long previousMillis = 0; // irá armazenar a última vez que o LED foi atualizado

/ * * * * * * * * * * * * *
Funções Auxiliares
* * * * * * * * * * * * * * /
void WIFI_Connect ()
{
WiFi.disconnect ();
Serial.println ("Conectando ao WiFi ...");
WiFi.mode (WIFI_AP_STA);
WiFi.begin (WIFISSID, PASSWORD);

para (int i = 0; i <60; i ++)
{
if (WiFi.status ()! = WL_CONNECTED)
{
atraso (250);
digitalWrite (ledPin, LOW);
Serial.print (".");
atraso (250);
digitalWrite (ledPin, HIGH);
}
}
if (WiFi.status () == WL_CONNECTED)
{
Serial.println ("");
Serial.println ("WiFi conectado");
Serial.println ("endereço IP:");
Serial.println (WiFi.localIP ());
}
digitalWrite (ledPin, 0);
}

/ * * * * * * * * * * * * *
Funções principais
* * * * * * * * * * * * * * /

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

// definir o pino digital como saída:
pinMode (ledPin, OUTPUT);
WIFI_Connect ();
}

void loop ()
{
currentMillis longo sem sinal = millis ();

if (currentMillis - previousMillis> = intervalo)
{
if (WiFi.status ()! = WL_CONNECTED)
{
Serial.println ("wi-fi desconectado");
WIFI_Connect ();
}
// salve a última vez que você piscou o LED
anteriorMillis = currentMillis;
// se o LED estiver desligado, ligue-o e vice-versa:
if (ledState == LOW)
{
ledState = HIGH;
intervalo = 100;
}
outro
{
ledState = LOW;
intervalo = 2500;
}
// definir o LED com o ledState da variável:
digitalWrite (ledPin, ledState);
}
} `

O firmware mais recente parece ajudar, vou fechar isso.

@vseven por firmware mais recente ... você quer dizer a versão mais recente do master desta biblioteca? Não vejo novos commits para masterizar desde 26 de setembro, então me pergunto se você está se referindo a outra coisa.

Obrigado pelo seu esclarecimento
Gaston

Abri este há mais de um ano, então sim, mais recente como nos últimos dois meses.

Ótimo. Obrigado pelo esclarecimento. Não tenho certeza de quando atualizei pela última vez (2 meses atrás?), Mas nunca vi esse erro depois da última atualização (e costumava acontecer uma vez a cada dois meses). Achei que estava tendo sorte, mas agora vejo que era mais do que sorte. ;)

Bom trabalho.
Gaston

Além disso, isso parece ajudar:

    esp_wifi_set_ps(WIFI_PS_NONE);

@vseven

O firmware mais recente parece ajudar, vou fechar isso.

Olá,
Sempre pensei que o platformio atualizando a biblioteca arduino-esp32 também era capaz de atualizar o que você chama de firmware. Estou errado? Ainda estou sofrendo desse problema!

@vseven
O firmware mais recente parece ajudar, vou fechar isso.

Olá,
Sempre pensei que o platformio atualizando a biblioteca arduino-esp32 também era capaz de atualizar o que você chama de firmware. Estou errado? Ainda estou sofrendo desse problema!

O mesmo aqui. Gostaria de saber como atualizar o firmware por platformio para contornar o problema de desconexão sozinho ...

@vseven
As instruções de configuração e atualização da plataforma IO são abordadas aqui
https://github.com/espressif/arduino-esp32/blob/master/docs/platformio.md

um pouco, no entanto: no Arduino e no Platform IO, quando uso o git para atualizar o SDK, em algumas ocasiões descobri que a atualização não foi concluída e teve problemas.

Renomeie a pasta esp32 e reinstale a partir de um git novo e sempre recebo uma atualização limpa.
Basta seguir suas instruções.

@mickeypop : bem, meu platformio está na última versão estável, mas ainda tenho o problema de desconexão. Você sugere usar as versões stage ou upstream? O estável só foi atualizado há alguns dias, aliás.

@ Miq1 esse problema existe se usar apenas o exemplo IDF?

Devo confessar que estou usando o Arduino apenas no ambiente Platformio - nunca lidei com o IDF. Vou dar uma olhada nisso hoje para ver se consigo configurar uma versão básica do meu aplicativo lá.

Apenas para registro: descobri que a solução alternativa com disconnect () e subsequente begin () funciona para mim se eu fizer um modo (WIFI_OFF) e um modo (WIFI_STA) entre os dois. No momento, estou tentando reconectar 5 vezes seguidas e faria um esp.restart () se todas as tentativas falhassem, mas até agora não foi necessário reiniciar.

Observei algumas reinicializações nesse meio tempo, então a solução alternativa parece não ser tão eficaz.

Existe alguma atualização sobre esse bug?

FWIW Eu vejo isso frequentemente em unidades ESP8266 também - exatamente os mesmos sintomas. Descobri que posso mudar a conexão drasticamente simplesmente orientando a unidade de forma diferente - então, parece estar relacionado a como as unidades (ESP8266 e ESP32) respondem a sinais ruins.

Dado que estou usando o NonOS e um ESP8266, o denominador comum parece ser a rede de baixo nível abaixo do lwIP

(Usando a versão 1.0.4 do Arduino-esp32)

Eu tive o mesmo problema aqui (usando ESP32). Descobri que reiniciar o roteador resolve o problema ... uma vez . Ou seja, após a reinicialização, o ESP32 é capaz de se conectar ao AP, obter um endereço IP e permanecer conectado, mas se algo fizer com que a conexão falhe (como reiniciar o ESP32), o ESP32 então _nunca será capaz de se conectar ao AP novamente_.

O roteador é um TP-Link TL-MR2030 que mantenho por perto para testes de Ethernet com fio e tem firmware que está irremediavelmente desatualizado por anos e nenhum firmware oficial mais recente existe.

Porém, se eu tento usar outros APs, como algumas unidades Ubiquiti bastante novas no escritório, o problema simplesmente não acontece. Eu até levantei algumas suspeitas sobre a equipe de TI, forçando a placa a reiniciar propositalmente e reconectar repetidamente o mais rápido possível por horas a fio ... e sem nenhum problema.

_Então, no final das contas, embora seja possível que algo esteja errado ou incompleto nas bibliotecas do ESP32, estou pronto para colocar toda a culpa no firmware do roteador antigo._ É hora de obter um novo roteador para testes, não do TP-LINK , Contudo.

Eu geralmente suspeito de dns para coisas assim. Ou às vezes o roteador ainda pensa que você está conectado e nunca permite que você se reconecte

Não, o roteador não é o culpado. Ao menos em meu caso. Claro, não é o mais novo (wnr2200), mas com um DD-WRT atualizado instalado e vários dispositivos Android, Linux e Windows funcionando sem problemas.

Para finalmente resolver esse problema para mim, comecei com uma implementação completamente nova, baseada em WiFiClientEvents.ino - portanto, é baseada em eventos. Eu também li as mensagens de commit mais recentes do arduino-esp32 que revelaram commits muito recentes, mas relevantes. Tive que fazer alguma depuração em WiFiGeneric.cpp e descobri que o modo nem sempre faz o que é esperado (https://github.com/espressif/arduino-esp32/issues/1306).

Resultado final: com um pequeno patch em WiFiGeneric.cpp (veja o final do arquivo), consegui conectar e desconectar várias vezes de / para meu AP - uau :)

Deixe-me saber se você vê algo para melhorar.

/*
 * 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
 */

Alguém wireharked isto?

Tive um problema semelhante com um arduino wifi rev 2 (hardware diferente, mas os problemas de negociação entre aps e o dispositivo eram assustadoramente semelhantes).

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

@mrarmyant O que você espera ver usando o WireShark? Acho que estamos falando sobre problemas nas camadas OSI 1 e 2. Dito de maneira diferente: sem SSID, sem frequência, sem pacotes

Meu código (acima de sua postagem) está estável desde que o postei. Mas não acho que o problema seja portátil para algo diferente dos chips ESP * porque ele trata de problemas do ESP SDK, não do Arduino

Eu culpo problemas como este na fonte de alimentação

Eu não culpo o PS, é muito improvável, a menos que você tenha um estoque muito fraco, isso não vai acontecer.

Wireshark é realmente inútil aqui.

Para entender, você precisa se aprofundar nas bibliotecas RTOS onde o trabalho real é feito, não nas bibliotecas do Arduino, pois elas são um invólucro.

Se você estiver usando WiFi.reconnect () em vez de WiFi.begin (), você precisa saber algumas coisas.

WiFi.begin () começa definindo todos os registros necessários no chip wi-fi e os estados RTOS antes de conectar, reconectar () não.
Isso foi relatado há mais de 2 anos.

WiFi.reconnect () geralmente faz apenas metade da conexão, estabelecendo uma conexão MAC de nível de chip com UDP, mas nunca fazendo a conexão TCP / IP, pois esses são protocolos separados. Isso ocorre porque os estados necessários não são predefinidos por reconnect (), ele simplesmente assume que eles estão lá.
É por isso que alguns de vocês não estão obtendo SYSTEM_EVENT_STA_GOT_IP na reconexão.

Lembrar; é necessário reconectar porque os estados já foram alterados.

SEMPRE reconecto com WiFi.begin () e nunca falhei.

======
quanto a um reset não conectando e dizendo que já existe uma conexão, você precisa saber o DHCP.
O endereço IP do DHCP é normalmente restabelecido a cada 15 segundos.
Agora, digamos 2 segundos depois de restabelecer, você pressiona o botão reset.
O servidor DHCP não vai liberar o IP por mais 13 segundos e, ao tentar se conectar, relatará que está em uso.

Um simples atraso na inicialização antes de conectar sempre corrigiu isso para mim.
Se você estiver configurando várias outras bibliotecas, defina-as primeiro antes de WiFi.begin ().

Um bom cronômetro de início ajudará aqui.
tome um longo var = millis (); na primeira linha de setup () e Serial.print (millis () - var); pouco antes de WiFi.begin () e descubra o quão rápido você está realmente inicializando. Em seguida, ajuste de acordo.

Uso o ESP32 há mais de 6 anos e sempre funcionou.

ATUALIZAR; Eu vejo um monte de WiFiEvent usado e para depurar é bom, mas simplesmente detectar o wi-fi e reconectar o IF / ELSE abaixo funciona sempre de forma confiável.

isso funciona porque leva cerca de 18 segundos para relatar a alteração WL_CONNECTED, isso dá ao servidor DHCP tempo para liberar o IP para uma reconexão confiável mais tarde.

Ele está trabalhando há mais de 6 anos e continua.

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

dê uma olhada no esqueleto do código que postei em https://github.com/espressif/arduino-esp32/issues/1100

embora fosse para configuração com SmartConfig, ele simplesmente funciona.

@mrarmyant O que você espera ver usando o WireShark? Acho que estamos falando sobre problemas nas camadas OSI 1 e 2. Dito de maneira diferente: sem SSID, sem frequência, sem pacotes

Meu código (acima de sua postagem) está estável desde que o postei. Mas não acho que o problema seja portátil para algo diferente dos chips ESP * porque ele trata de problemas do ESP SDK, não do Arduino

Eu não estava me referindo realmente ao arduino, mas ao sistema wi-fi que está a bordo dessa unidade em particular. Ele teve problemas com reconectar por ser suspeito de dhcp. Alguém relatou que reiniciar seu roteador corrigiu o problema, que é o problema que tínhamos (bem reiniciar um servidor dhcp windows). Havia um problema com a forma como ele estava reconhecendo se havia sido desconectado ou não. Só pensei que poderia ajudar com esses problemas lá em cima, porque nenhuma unidade jamais apareceria como conectada nas reconexões, e o wirehark nos mostrou o porquê. IPs estáticos não tiveram nenhum problema. Acabou sendo o firmware soc wi-fi que teve que ser consertado para lidar com o atraso mencionado por problemas de DHCP. Todos os quais foram descobertos através do wirehark.

Esta página foi útil?
5 / 5 - 1 avaliações