JAndrassy / WiFiEspAT

Arduino networking library. Standard Arduino WiFi networking API over ESP8266 or ESP32 AT commands.
GNU Lesser General Public License v2.1
271 stars 44 forks source link

WiFiServer stop working after second WiFi.begin(ssid,pass) #83

Closed Vovanchik closed 2 years ago

Vovanchik commented 2 years ago

Right now, I am working on the failover function for WiFi connection, in other words, initiating WiFi reconnect when WiFi.status() != WL_CONNECTED. The problem is that WiFi re-connection works well, but WiFiServer stops working after reconnecting. Is it a way to restart WebServer as well with WiFi connection?

Firmware on ESP8266:

AT version:1.7.5.0(Oct  9 2021 09:26:04)
SDK version:3.0.5(b29dcd3)
compile time:Oct 15 2021 18:05:30
Bin version(Wroom 02):1.7.5

Sketch is simple:

#include <SoftwareSerial.h>
#include <WiFiEspAT.h>

SoftwareSerial EspSerial(4, 5);

WiFiServer server(80);

void setup() {
  int  baund = 9600;

  Serial.begin(9600;);
  EspSerial.begin(9600;);
  delay(1000);
  Serial.println("[INFO] --== SERIAL PORTS CONFIGURED ==--");

  WiFi.init(EspSerial,ESP_RESET_PIN);
  delay(1000);
  WiFi.reset(ESP_RESET_PIN);
  delay(1000);  
  connectToWiFi();
  Serial.println("[INFO] --== WiFi CONNECTED ==--");

  server.begin();
  Serial.println("[INFO] --== WEB SERVER STARTED ==--");

}

void loop(){
  if (millis() - timing > 5000) {
    timing = millis(); 

    if (WiFi.status() != WL_CONNECTED) {
      Serial.println("[INFO] WiFi disconnected!!!");
      connectToWiFi();

      server.end();     <---- possible Web server restart
      server.begin();  <---- possible Web server restart
    }

 }
}

void connectToWiFi(){
  statusWiFi = WiFi.status();

  while (statusWiFi != WL_CONNECTED) {
      Serial.print('.');
      statusWiFi = WiFi.begin(ssid, pass);
    }
}
JAndrassy commented 2 years ago

I guess it is a feature of the AT firmware. Just use server.begin() again

Vovanchik commented 2 years ago

I am using it loop(), but it doesn't work.

Thank you for your response. I'll create an issue in AT firmware project: https://github.com/espressif/ESP8266_NONOS_SDK.

Feel free to close this one.

JAndrassy commented 2 years ago

turn on debug logging so we can see the AT commands exchange

Vovanchik commented 2 years ago

If you have some instructions on how to turn it on, it will be awesome.

JAndrassy commented 2 years ago

https://github.com/JAndrassy/WiFiEspAT#logging

Vovanchik commented 2 years ago

Hi JAndrassy. It looks like there is a small bug in the library.

After enabling debug logging and investigation I noticed that command AT+CIPSERVER which is used to manage a server work's only when AT+CIPMUX is set to 1, which means that multiple connections are activated. Source: https://www.espressif.com/sites/default/files/documentation/4a-esp8266_at_instruction_set_en.pdf page 51.

11:05:08.585 -> esp INFO: stop server
11:05:08.622 -> esp> AT+CIPSERVER=0 ...sent
11:05:08.660 -> esp> AT+CIPSIYԂj ...ignored
11:05:08.698 -> esp> ERROR ...error
11:05:08.698 -> esp ERROR: expected OK got ERROR

11:05:08.736 -> esp INFO: begin server at port 80
11:05:08.774 -> esp> AT+CIPSERVERMAXCONN=1 ...sent
11:05:08.848 -> esp> AT+CIPSIY⸮a=99⸮1 ...ignored
11:05:08.885 -> esp> OK ...matched
11:05:08.885 -> esp> AT+CIPSERVER=1,80 ...sent
11:05:08.885 -> esp> AT+CIPSIYԊb‚j ...ignored
11:05:08.922 -> esp> ERROR ...error
11:05:08.988 -> esp ERROR: expected OK got ERROR

After code review, I noticed that AT+CIPMUX is set in utility/EspAtDrv.cpp, line 98 during WiFi.reset() or WiFi.init commands.

  if (!simpleCommand(PSTR("ATE0")) || // turn off echo. must work
      !simpleCommand(PSTR("AT+CIPMUX=1")) ||  // Enable multiple connections.                      <---- HERE
      !simpleCommand(PSTR("AT+CIPRECVMODE=1"))) // Set TCP Receive Mode - passive
    return false;

In my case, I made an HW reset of the ESP8266 module without restarting Arduino Nano.

Proposition: As for me command AT+CIPMUX=1 must be set every time when AT+CIPSERVER is called, in other words when either serverBegin (utility/EspAtDrv.cpp, line 699) or serverStop (utility/EspAtDrv.cpp, line 723) is called.

NOTE: In the current implementation, it is not obvious that WiFi.reset needs to be called to set AT+CIPMUX=1.

JAndrassy commented 2 years ago

the library needs all the commands sent in init() for all WiFiClient and WiFiUDP functions. I will not send all initialization commands before every command. don't reset the esp without resenting the Arduino.

Vovanchik commented 2 years ago

Make sense. Thank you for your response.

I found a workaround for my case with reset() function.