khoih-prog / EthernetWebServer

This is simple yet complete WebServer library for AVR, AVR Dx, Portenta_H7, Teensy, SAM DUE, SAMD21/SAMD51, nRF52, STM32, RP2040-based, etc. boards running Ethernet shields. The functions are similar and compatible to ESP8266/ESP32 WebServer libraries to make life much easier to port sketches from ESP8266/ESP32. Coexisting now with `ESP32 WebServer` and `ESP8266 ESP8266WebServer` libraries. Ethernet_Generic library is used as default for W5x00 with custom SPI
MIT License
178 stars 49 forks source link

WiFi and Ethernet Bridge? #26

Closed HWEDK closed 3 years ago

HWEDK commented 3 years ago

Perhaps I'm missing this ability as an inherent part of the base libraries, but I cannot seem to get Wi-Fi and Ethernet servers to operate in one program. The intent is to connect one or the other based on if Ethernet is physically connected, or default to Wi-Fi if Ethernet isn't connected at startup. Removing Ethernet would start the Wi-Fi AP and server. Both listen for clients after switching.

I have not been able to successfully split the startup functions and declarations based on input feedback. I can compile a logic tree that starts one or the other, but there seems to be a problem with the class when trying to connect. It appears to me that the items to consider are as follows:

EthernetServer server( ); Ethernet.begin( ); EthernetClient client = server.available( );

WiFiServer server( ); WiFi.softAP( ); server.begin ( ); WiFiClient = server.available( );

Is it possible to merge these two functionally without major changes?

khoih-prog commented 3 years ago

You have to give the servers different names, such as server and wifiServer

Try the following sketch for ESP32 and see both Ethernet and WiFi can coexist, and one is still working if the other fails

#if !(ESP32)
  #error This code is for ESP32 only
#endif

#define USE_ETHERNET          true

#include <WiFi.h>
#include <WebServer.h>

#include <SPI.h>
#include <Ethernet.h>

const char* ssid     = "your-ssid";
const char* password = "your-password";

// Enter a MAC address and IP address for your controller below.

byte mac[] =
{
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};

// Select the IP address according to your local network
IPAddress ip(192, 168, 2, 100);

EthernetServer server(80);

WiFiServer wifiServer(80);

const int led = 13;

void setup(void)
{
  // Open serial communications and wait for port to open:
  Serial.begin(115200);
  delay(1000);
  Serial.println("\nStarting HelloServer on " + String(ARDUINO_BOARD));

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

  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

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

#if defined(ESP32)
  // Use the correct pin for ESP32
  #define USE_THIS_SS_PIN   27

  #if ( USE_ETHERNET || USE_ETHERNET_LARGE || USE_ETHERNET2 || USE_ETHERNET_ENC )
    // Must use library patch for Ethernet, EthernetLarge libraries
    // ESP32 => GPIO2,4,5,13,15,21,22 OK with Ethernet, Ethernet2, EthernetLarge
    // ESP32 => GPIO2,4,5,15,21,22 OK with Ethernet3

    //Ethernet.setCsPin (USE_THIS_SS_PIN);
    Ethernet.init (USE_THIS_SS_PIN);
  #endif
#endif

  // start the ethernet connection and the server:
  //Ethernet.begin(mac, ip);
  Ethernet.begin(mac);

  server.begin();

  Serial.print(F("HTTP EthernetWebServer is @ IP : "));
  Serial.println(Ethernet.localIP());

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

  wifiServer.begin();

  Serial.print(F("HTTP WiFiWebServer is @ IP : "));
  Serial.println(WiFi.localIP());
}

void processClient(Client &client, bool fromWiFi = false)
{
  if (client) 
  {
    if (fromWiFi)
      Serial.println("New WiFi client");
    else
      Serial.println("New Ethernet client");

    // an http request ends with a blank line
    boolean currentLineIsBlank = true;

    while (client.connected()) 
    {
      if (client.available()) 
      {
        char c = client.read();
        Serial.write(c);
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        if (c == '\n' && currentLineIsBlank) 
        {
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connection: close");  // the connection will be closed after completion of the response
          client.println("Refresh: 5");  // refresh the page automatically every 5 sec
          client.println();
          client.println("<!DOCTYPE HTML>");
          client.println("<html>");

          if (fromWiFi)
            client.println("<h1>Hello to WiFi client</h1>");
          else
            client.println("<h1>Hello to Ethernet client</h1>");

          // output the value of each analog input pin
          for (int analogChannel = 0; analogChannel < 6; analogChannel++) 
          {
            int sensorReading = analogRead(analogChannel);
            client.print("analog input ");
            client.print(analogChannel);
            client.print(" is ");
            client.print(sensorReading);
            client.println("<br />");
          }
          client.println("</html>");
          break;
        }

        if (c == '\n') 
        {
          // you're starting a new line
          currentLineIsBlank = true;
        } else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }

    // give the web browser time to receive the data
    delay(1);
    // close the connection:
    client.stop();
    Serial.println("client disconnected");
  }
}

void loop() 
{
  // listen for incoming clients
  EthernetClient client = server.available();

  processClient(client, false);

  // listen for incoming clients
  WiFiClient wifiClient = wifiServer.available();

  processClient(wifiClient, true);
}

But to use the high level EthernetWebServer and ESP32 WebServer is currently not ready, unless the library is modified to avoid conflicts.

I don't think I'll spend time to modify the library as this use case is not popular.

HWEDK commented 3 years ago

Thank you for that example. Helped getting it going, and I understand the oddity of wanting both connections. They do work just fine with small data having both run simultaneously. I tested them rapidly, connecting on and off and sending multiple HTTP requests, and they hold pretty steady. I guess I don't need to separate either/or. Trying to separate them, it didn't like use of the classes for some reason with Ethernet.

I only made a couple changes, but for others who may have similar questions and search their way into this closed issue, this can be a working connection at least using ESP32-Wrover to W5500 using an HTTP/HTML website with minimal data.

sdrshnptl commented 2 years ago

This method does not comply with handler. After separating wifi sever as WiFiServer serverWifi(80); I'm getting error like this in setup()serverWifi.on("/", handleRoot); //'class WiFiServer' has no member named 'on' //conflicting with ethernet in loop() serverWifi.handleClient(); //previous definition of 'class RequestHandler' //conflicting with ethernet

khoih-prog commented 2 years ago

@sdrshnptl

Thanks for chipping in.

Anyway, you're confused between WiFiServer and WebServer libraries. Only the latter can provide higher-level functions such as

serverWifi.on("/", handleRoot);

Try to change the sketch to

#if !(ESP32)
  #error This code is for ESP32 only
#endif

#define USE_ETHERNET          true

#include <WiFi.h>
#include <WebServer.h>

#include <SPI.h>
#include <Ethernet.h>

const char* ssid     = "your-ssid";
const char* password = "your-password";

// Enter a MAC address and IP address for your controller below.

byte mac[] =
{
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};

// Select the IP address according to your local network
IPAddress ip(192, 168, 2, 100);

EthernetServer server(80);

WebServer wifiServer(80);

const int led = 13;

void handleWiFiRoot() 
{
  wifiServer.send(200, "text/plain", "Hello from ESP32 WiFi!");
}

void setup(void)
{
  // Open serial communications and wait for port to open:
  Serial.begin(115200);
  delay(1000);
  Serial.println("\nStarting WiFi_Ethernet_ESP on " + String(ARDUINO_BOARD));

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

  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

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

#if defined(ESP32)
  // Use the correct pin for ESP32
  #define USE_THIS_SS_PIN   27

  #if ( USE_ETHERNET || USE_ETHERNET_LARGE || USE_ETHERNET2 || USE_ETHERNET_ENC )
    // Must use library patch for Ethernet, EthernetLarge libraries
    // ESP32 => GPIO2,4,5,13,15,21,22 OK with Ethernet, Ethernet2, EthernetLarge
    // ESP32 => GPIO2,4,5,15,21,22 OK with Ethernet3

    //Ethernet.setCsPin (USE_THIS_SS_PIN);
    Ethernet.init (USE_THIS_SS_PIN);
  #endif
#endif

  // start the ethernet connection and the server:
  //Ethernet.begin(mac, ip);
  Ethernet.begin(mac);

  server.begin();

  Serial.print(F("HTTP EthernetWebServer is @ IP : "));
  Serial.println(Ethernet.localIP());

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

  wifiServer.on("/", handleWiFiRoot);

  wifiServer.begin();

  Serial.print(F("HTTP WiFiWebServer is @ IP : "));
  Serial.println(WiFi.localIP());
}

void processClient(Client &client, bool fromWiFi = false)
{
  if (client) 
  {
    if (fromWiFi)
      Serial.println("New WiFi client");
    else
      Serial.println("New Ethernet client");

    // an http request ends with a blank line
    boolean currentLineIsBlank = true;

    while (client.connected()) 
    {
      if (client.available()) 
      {
        char c = client.read();
        Serial.write(c);
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        if (c == '\n' && currentLineIsBlank) 
        {
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connection: close");  // the connection will be closed after completion of the response
          client.println("Refresh: 5");  // refresh the page automatically every 5 sec
          client.println();
          client.println("<!DOCTYPE HTML>");
          client.println("<html>");

          if (fromWiFi)
            client.println("<h1>Hello to WiFi client</h1>");
          else
            client.println("<h1>Hello to Ethernet client</h1>");

          // output the value of each analog input pin
          for (int analogChannel = 0; analogChannel < 6; analogChannel++) 
          {
            int sensorReading = analogRead(analogChannel);
            client.print("analog input ");
            client.print(analogChannel);
            client.print(" is ");
            client.print(sensorReading);
            client.println("<br />");
          }
          client.println("</html>");
          break;
        }

        if (c == '\n') 
        {
          // you're starting a new line
          currentLineIsBlank = true;
        } else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }

    // give the web browser time to receive the data
    delay(1);
    // close the connection:
    client.stop();
    Serial.println("client disconnected");
  }
}

void loop() 
{
  // listen for incoming clients
  EthernetClient client = server.available();

  processClient(client, false);

  wifiServer.handleClient();
}

sdrshnptl commented 2 years ago

Thanks! Will check and update!

khoih-prog commented 2 years ago

Major Releases v2.0.0

  1. Make breaking changes to permit coexistence with ESP32 WebServer and ESP8266 ESP8266WebServer libraries
  2. Add and modified examples

From v2.0.0, you can use simultaneously both EthernetWebServer and ESP32 WebServer as follows

// To demonstrate the coexistence of this EthernetWebServer and ESP32 WebServer library

#define USE_ETHERNET          true

#include <WiFi.h>
#include <WebServer.h>

#include <SPI.h>
#include <EthernetWebServer.h>

const char* ssid     = "your_ssid";
const char* password = "your_password";

// Enter a MAC address and IP address for your controller below.

byte mac[] =
{
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};

// Select the IP address according to your local network
IPAddress ip(192, 168, 2, 100);

EthernetWebServer ethernetServer(80);
WebServer wifiServer(80);

const int led = 13;

void handleEthernetRoot() 
{
  ethernetServer.send(200, "text/plain", "Hello from ESP32 Ethernet!");
}

void handleWiFiRoot() 
{
  wifiServer.send(200, "text/plain", "Hello from ESP32 WiFi!");
}

void setup()
{
  // Open serial communications and wait for port to open:
  Serial.begin(115200);
  delay(1000);
  Serial.println("\nStarting WiFi_Ethernet_Complex_ESP32 on " + String(ARDUINO_BOARD));

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

  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

  // start the ethernet connection and the server:
  //Ethernet.begin(mac, ip);
  Ethernet.begin(mac);

  ethernetServer.on("/", handleEthernetRoot);

  ethernetServer.begin();

  Serial.print(F("HTTP EthernetWebServer is @ IP : "));
  Serial.println(Ethernet.localIP());

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

  wifiServer.on("/", handleWiFiRoot);

  wifiServer.begin();

  Serial.print(F("HTTP WiFiWebServer is @ IP : "));
  Serial.println(WiFi.localIP());
}

void loop() 
{
  // listen for incoming clients
  ethernetServer.handleClient();

  wifiServer.handleClient();
}
sdrshnptl commented 2 years ago

Hey @khoih-prog ! I really appreciated your work! Now I can do WIFI and Ethernet at same time! image

There is small addition Please add following to update server port in runtime in client mode httpClient.updatePort(server_port);

in "Ethernet_HttpClient.cpp"

void EthernetHttpClient::updatePort(uint16_t new_port)
{
  iServerPort = new_port;
}

in "Ethernet_HttpClient.h"

void updatePort(uint16_t new_port);
sdrshnptl commented 1 year ago

I have a problem: "ESP32 compiling error". how fix it?

Those errors have a broad range, please share the error log to fellow members in the new issue.

elektroboard commented 1 year ago

In file included from C:\Users\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6/tools/sdk/include/wifi_provisioning/wifi_provisioning/wifi_config.h:18:0, from C:\Users\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6/tools/sdk/include/wifi_provisioning/wifi_provisioning/manager.h:20, from C:\Users\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6\libraries\WiFi\src/WiFiGeneric.h:31, from C:\Users\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6\libraries\WiFi\src/WiFiSTA.h:28, from C:\Users\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6\libraries\WiFi\src/WiFi.h:32, from C:\Users\OneDrive\Belgeler\Arduino\test\test.ino:3: C:\Users\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6/tools/sdk/include/lwip/lwip/inet.h:142:58: error: expected identifier before '(' token

define inet_aton(cp, addr) ip4addr_aton(cp, (ip4_addr_t*)addr)

                                                      ^

c:\Users\OneDrive\Belgeler\Arduino\libraries\Ethernet_Generic\src/Dns.h:48:9: note: in expansion of macro 'inet_aton' int inet_aton(const char aIPAddrString, IPAddress& aResult); ^ c:\Users\OneDrive\Belgeler\Arduino\libraries\Ethernet_Generic\src/Dns.h:48:46: error: expected ',' or '...' before 'IPAddress' int inet_aton(const char aIPAddrString, IPAddress& aResult); ^ C:\Users\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6/tools/sdk/include/lwip/lwip/inet.h:142:71: note: in definition of macro 'inet_aton'

define inet_aton(cp, addr) ip4addr_aton(cp, (ip4_addr_t*)addr)

                                                                   ^

C:\Users\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6/tools/sdk/include/lwip/lwip/inet.h:142:58: error: expected identifier before '(' token

define inet_aton(cp, addr) ip4addr_aton(cp, (ip4_addr_t*)addr)

                                                      ^

c:\Users\OneDrive\Belgeler\Arduino\libraries\Ethernet_Generic\src/Dns_Impl.h:118:16: note: in expansion of macro 'inet_aton' int DNSClient::inet_aton(const char address, IPAddress& result) ^ c:\Users\OneDrive\Belgeler\Arduino\libraries\Ethernet_Generic\src/Dns_Impl.h:118:47: error: expected ',' or '...' before 'IPAddress' int DNSClient::inet_aton(const char address, IPAddress& result) ^ C:\Users\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6/tools/sdk/include/lwip/lwip/inet.h:142:71: note: in definition of macro 'inet_aton'

define inet_aton(cp, addr) ip4addr_aton(cp, (ip4_addr_t*)addr)

                                                                   ^

In file included from c:\Users\OneDrive\Belgeler\Arduino\libraries\Ethernet_Generic\src/EthernetClient_Impl.h:55:0, from c:\Users\OneDrive\Belgeler\Arduino\libraries\Ethernet_Generic\src/Ethernet_Generic_Impl.h:60, from c:\Users\OneDrive\Belgeler\Arduino\libraries\Ethernet_Generic\src/Ethernet_Generic.h:82, from c:\Users\OneDrive\Belgeler\Arduino\libraries\EthernetWebServer\src/EthernetWebServer.h:58, from C:\Users\OneDrive\Belgeler\Arduino\test\test.ino:7: c:\Users\OneDrive\Belgeler\Arduino\libraries\Ethernet_Generic\src/Dns_Impl.h: In member function 'int DNSClient::ip4addr_aton(const char, int ()(ip4_addr_t))': c:\Users\OneDrive\Belgeler\Arduino\libraries\Ethernet_Generic\src/Dns_Impl.h:145:7: error: 'result' was not declared in this scope result[dots++] = acc; ^ c:\Users\OneDrive\Belgeler\Arduino\libraries\Ethernet_Generic\src/Dns_Impl.h:161:3: error: 'result' was not declared in this scope result[3] = acc; ^ In file included from C:\Users\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6/tools/sdk/include/wifi_provisioning/wifi_provisioning/wifi_config.h:18:0, from C:\Users\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6/tools/sdk/include/wifi_provisioning/wifi_provisioning/manager.h:20, from C:\Users\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6\libraries\WiFi\src/WiFiGeneric.h:31, from C:\Users\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6\libraries\WiFi\src/WiFiSTA.h:28, from C:\Users\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6\libraries\WiFi\src/WiFi.h:32, from C:\Users\OneDrive\Belgeler\Arduino\test\test.ino:3: c:\Users\OneDrive\Belgeler\Arduino\libraries\Ethernet_Generic\src/Dns_Impl.h: In member function 'int DNSClient::getHostByName(const char, IPAddress&, uint16_t)': c:\Users\OneDrive\Belgeler\Arduino\libraries\Ethernet_Generic\src/Dns_Impl.h:173:28: error: invalid cast from type 'IPAddress' to type 'ip4_addr_t {aka ip4_addr}' if (inet_aton(aHostname, aResult)) ^ C:\Users\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6/tools/sdk/include/lwip/lwip/inet.h:142:71: note: in definition of macro 'inet_aton'

define inet_aton(cp, addr) ip4addr_aton(cp, (ip4_addr_t*)addr)

                                                                   ^

In file included from c:\Users\OneDrive\Belgeler\Arduino\libraries\Ethernet_Generic\src/EthernetClient_Impl.h:55:0, from c:\Users\OneDrive\Belgeler\Arduino\libraries\Ethernet_Generic\src/Ethernet_Generic_Impl.h:60, from c:\Users\OneDrive\Belgeler\Arduino\libraries\Ethernet_Generic\src/Ethernet_Generic.h:82, from c:\Users\OneDrive\Belgeler\Arduino\libraries\EthernetWebServer\src/EthernetWebServer.h:58, from C:\Users\OneDrive\Belgeler\Arduino\test\test.ino:7: c:\Users\OneDrive\Belgeler\Arduino\libraries\Ethernet_Generic\src/Dns_Impl.h:180:18: error: ambiguous overload for 'operator==' (operand types are 'IPAddress' and 'u32_t {aka unsigned int}') if (iDNSServer == INADDR_NONE) ^ c:\Users\OneDrive\Belgeler\Arduino\libraries\Ethernet_Generic\src/Dns_Impl.h:180:18: note: candidate: operator==(uint32_t {aka unsigned int}, u32_t {aka unsigned int}) In file included from C:\Users\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6\cores\esp32/Arduino.h:150:0, from C:\Users\AppData\Local\Temp\arduino-sketch-84DFC43EDFB58593C816EE62BC3CDF1A\sketch\test.ino.cpp:1: C:\Users\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6\cores\esp32/IPAddress.h:63:10: note: candidate: bool IPAddress::operator==(const IPAddress&) const bool operator==(const IPAddress& addr) const ^ Multiple libraries were found for "SPI.h" Used: C:\Users\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6\libraries\SPI Not used: C:\Users\OneDrive\Belgeler\Arduino\libraries\SPI exit status 1

Compilation error: exit status 1

elektroboard commented 1 year ago

Major Releases v2.0.0

  1. Make breaking changes to permit coexistence with ESP32 WebServer and ESP8266 ESP8266WebServer libraries
  2. Add and modified examples

From v2.0.0, you can use simultaneously both EthernetWebServer and ESP32 WebServer as follows

// To demonstrate the coexistence of this EthernetWebServer and ESP32 WebServer library

#define USE_ETHERNET          true

#include <WiFi.h>
#include <WebServer.h>

#include <SPI.h>
#include <EthernetWebServer.h>

const char* ssid     = "your_ssid";
const char* password = "your_password";

// Enter a MAC address and IP address for your controller below.

byte mac[] =
{
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};

// Select the IP address according to your local network
IPAddress ip(192, 168, 2, 100);

EthernetWebServer ethernetServer(80);
WebServer wifiServer(80);

const int led = 13;

void handleEthernetRoot() 
{
  ethernetServer.send(200, "text/plain", "Hello from ESP32 Ethernet!");
}

void handleWiFiRoot() 
{
  wifiServer.send(200, "text/plain", "Hello from ESP32 WiFi!");
}

void setup()
{
  // Open serial communications and wait for port to open:
  Serial.begin(115200);
  delay(1000);
  Serial.println("\nStarting WiFi_Ethernet_Complex_ESP32 on " + String(ARDUINO_BOARD));

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

  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

  // start the ethernet connection and the server:
  //Ethernet.begin(mac, ip);
  Ethernet.begin(mac);

  ethernetServer.on("/", handleEthernetRoot);

  ethernetServer.begin();

  Serial.print(F("HTTP EthernetWebServer is @ IP : "));
  Serial.println(Ethernet.localIP());

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

  wifiServer.on("/", handleWiFiRoot);

  wifiServer.begin();

  Serial.print(F("HTTP WiFiWebServer is @ IP : "));
  Serial.println(WiFi.localIP());
}

void loop() 
{
  // listen for incoming clients
  ethernetServer.handleClient();

  wifiServer.handleClient();
}

i used exactly this code but i get error like above

khoih-prog commented 1 year ago

You have to update to ESP32 core v2.0.5

packages\esp32\hardware\esp32\1.0.6

Next time when having fatal error, read the README.md again, especially Prerequisites

Selection_200

Also don't post on closed issue.