Getting IP 0.0.0.0 when directly connecting to laptop via Ethernet cable

Hi, I am using ESP32-CAM with W5500 network board, connected directly via a cross-over Ethernet cable to a laptop. My end goal is to stream video to the laptop via Ethernet instead of WiFi. For now, I'm trying to establish a connection. This is my complete wiring:

This is the code I am using for testing:

#include <SPI.h>
#include <EthernetSPI2.h>

byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; 
byte ip[] = {192, 168, 1, 15};  
byte gateway[] = {192, 168, 1, 254}; 
byte subnet[] = {255, 255, 255, 0}; 
EthernetServer server(80); 

void setup()
{
  Serial.begin(115200);
  Ethernet.init(2);
  Ethernet.begin(mac, ip, gateway, subnet);  //start Ethernet

  // Check for Ethernet hardware present
  if (Ethernet.hardwareStatus() == EthernetNoHardware) {
    Serial.println("Ethernet shield was not found.  Sorry, can't run without hardware. :(");
    while (true) {
      delay(200);
    }
  }
  while (Ethernet.linkStatus() == LinkOFF) {
    Serial.println("Ethernet cable is NOT connected.");
      delay(500); 
  }

  Serial.println("Ethernet cable is now connected.");

  Serial.print("localIP: ");
  Serial.println(Ethernet.localIP());
  Serial.print("subnetMask: ");
  Serial.println(Ethernet.subnetMask());
  Serial.print("gatewayIP: ");
  Serial.println(Ethernet.gatewayIP());
  Serial.print("dnsServerIP: ");
  Serial.println(Ethernet.dnsServerIP());
}

void loop()
{
}

After uploading the sketch, removing the boot pin jumper and rebooting ESP, I get this on the Serial Monitor:

rst:0x1 (POWERON_RESET),boot:0x1b (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:0x3fff0030,len:4832
load:0x40078000,len:16460
load:0x40080400,len:4
load:0x40080404,len:3504
entry 0x400805cc
Ethernet cable is now connected.
localIP: 0.0.0.0
subnetMask: 0.0.0.0
gatewayIP: 0.0.0.0
dnsServerIP: 192.168.1.254

As you can see, the W5500 connection checks passed, but for some reason IP is 0.0.0.0. I googled this and it always seems to be a hardware issue, but in my case I am 100% I wired everything correctly, and I checked with multimeter between ESP and W5500 pins to ensure I have continuity everywhere, no bad pins or anything. I also tried supplying 5V external power from PSU to all devices, but it didn't make any difference. I also tried supplying a different IP (192.168.2.15) so it doesn't clash with my home WiFi that the laptop is connected to, but it didn't help either.

For testing, I tried removing W5500, and then I get "can't run without hardware", and if I unplug the Ethernet cable from the laptop, I get "Ethernet cable is NOT connected"), meaning ESP can see everything up to the laptop, so it shouldn't be a hardware problem.

Like I said, I am using a cross-over Ethernet cable, although I also tried a regular one.

Please note that all examples I could find on the internet suggest using Ethernet.begin as Ethernet.begin(mac, ip, gateway, subnet) for this use case, but Ethernet library doc says that this class don't have a method matching these arguments, everything above 2 arguments requires also supplying dns. I tried supplying it as well, but it didn't change anything.

What am I doing wrong? I have been trying to solve this for a week now, and I'm completely stuck.

What happens when you instead connect the ESP to your router via Ethernet cable. Can you get an IP address via DHCP? Can you then ping the ESP from your laptop?

Unfortunately my router doesn't have LAN ports, it's WiFi only, so I can't test that...

Never heard of that. I'd never buy one.

1 Like

Sorry, it's just what I have. But with my setup (W5500 connected directly to laptop with crossover cable), I shouldn't need router in between, right? So what am I doing wrong?

Can you ping it at 192.168.1.15 even though it reports 0.0.0.0? Other than that, I got nothing. Good luck.

1 Like

Nope, I get "destination host unreachable".

Can anyone else help, please?

Two other things ... long shots.

Without a router for DHCP, how is laptop getting its IP Address? Did you set it manually?

Instead of a direct connection, try connecting both laptop and ESP via a 10/100 Ethernet swtich.

Normally my laptop is getting IP from WiFi router, but for this specific connection I tried setting up manual IPv4 settings on the laptop (IP address and subnet mask). Tried 192, 168, 1, 16 for IP and 255, 255, 255, 0 for subnet. Also tried 192, 168, 2, 16 for the laptop, and 192, 168, 2, 15 for the ESP32, so that it's not on the same subnet as the WiFi network. That didn't change anything unfortunately.

As for a switch, I don't have it either. Would preferably like to avoid buying one just for testing, because in the end I do need a direct connection between ESP32 and laptop.

If you are using this lib here..
then your begin doesn't match any provided..

// Manaul configuration
	static void begin(uint8_t *mac, IPAddress ip);
	static void begin(uint8_t *mac, IPAddress ip, IPAddress dns);
	static void begin(uint8_t *mac, IPAddress ip, IPAddress dns, IPAddress gateway);
	static void begin(uint8_t *mac, IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet);
	static void init(uint8_t sspin = 10);

did you try just mac and ip??

good luck.. ~q

1 Like

Yes, that's the library I am using. And yeah, I mentioned this discrepancy between the available Begin overloads and the examples I found on the internet. But I did try all of these options (mac, ip, then mac, ip, dns, then mac, ip, dns, gateway, and mac, ip, dns, gateway, subnet), and in all these cases I get 0.0.0.0 as my IP.

The numbers I tried were:

byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; 
byte ip[] = {192, 168, 0, 15};  
byte dns[] = {192, 168, 0, 1};  
byte gateway[] = {192, 168, 0, 254}; 
byte subnet[] = {255, 255, 255, 0};

Maybe this is incorrect?

As i understand, if I just supply mac and ip, ESP32 expects that there is a router on the other end of the cable to handle the connection. But since I'm connecting directly to a laptop, I think it makes more sense to supply dns, gateway and subnet as well, so that ESP32 acts as it's own DHCP. Correct me if I'm wrong. But in any case, I tried all options for Begin and still it doesn't work.

Is there a DHCP server provision in the W5500 lib you're using? I don't expect so.

In your p2p connection scheme of laptop - ESP without router, there is no DHCP or a gateway.

I see! So maybe that's the issue. I don't know if there is DHCP provision in that W5500 lib, I assumed there is. Okay, so what should I do then? How do I make this connection work without having to use a router/switch in between W5500 and laptop?

In your p2p connection scheme, DHCP is not a relevant factor. You assign IP addresses manually. No DHCP ever comes into play.

You could of course revert to a server-client situation (at least from an IP point of view), in which case you would have to designate either node as the server, and this would have to run a DHCP server. I would assume the W5500 library does not come with DHCP server capability (or DNS server etc.). So the logical approach would be to run a DHCP server on the laptop instead and have the ESP32/W5500 obtain its IP from that server. There are several open source DHCP server deamons available for Windows, Linux etc.

I would have expected that a manual configuration of the IP + subnet would (should) have worked, but perhaps the authors of the library didn't take into account a router-less network. In this case, I'd try the route suggested above by making the laptop the DHCP server. The laptop will have a static IP + subnet and it will be the DHCP server + router. Settings could be e.g.:
Laptop IP: 192.168.0.1
Subnet: 255.255.255.0
DHCP range e.g. 192.168.0.10 through 192.168.0.50
Gateway: 192.168.0.1
Then have your ESP32 connect to the laptop as if it's connecting to a router, e.g. by acting as a DHCP client. It should obtain an IP address from the laptop (probably .10) this way.

Understood, thank you. But it would be really great to not have to host anything laptop-side, in the end I want this to be plug-and-play. But your explanation makes a lot of sense. To try and keep things DHCP-less, I tried ENC28J60 module now instead of W5500, and this library.

And this code from the example:

/*
 Web client with enc28j60 and EthernetENC
 
 This sketch connects to a test website (httpbin.org)
 and try to do a GET request, the output is printed
 on Serial
 
 by Renzo Mischianti <www.mischianti.org>
 
 https://www.mischianti.org
 
 */
 
#include <SPI.h>
#include <EthernetENC.h>
 
// if you don't want to use DNS (and reduce your sketch size)
// use the numeric IP instead of the name for the server:
//IPAddress server(74,125,232,128);  // numeric IP for Google (no DNS)
//char server[] = "www.google.com";    // name address for Google (using DNS)
char server[] = "httpbin.org";    // name address for Google (using DNS)
 
// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
 
// Set the static IP address to use if the DHCP fails to assign
#define MYIPADDR 192,168,1,28
#define MYIPMASK 255,255,255,0
#define MYDNS 192,168,1,1
#define MYGW 192,168,1,1
 
// Initialize the Ethernet client library
// with the IP address and port of the server
// that you want to connect to (port 80 is default for HTTP):
EthernetClient client;
 
// Variables to measure the speed
unsigned long beginMicros, endMicros;
unsigned long byteCount = 0;
bool printWebData = true;  // set to false for better speed measurement
 
void setup() {
    Serial.begin(115200);
    delay(1000);
    Serial.println("Begin Ethernet");

    Ethernet.init(2); 
 
    IPAddress ip(MYIPADDR);
    IPAddress dns(MYDNS);
    IPAddress gw(MYGW);
    IPAddress sn(MYIPMASK);
    Ethernet.begin(mac, ip, dns, gw, sn);
    Serial.println("STATIC OK!");
    delay(5000); 
 
    Serial.print("Local IP : ");
    Serial.println(Ethernet.localIP());
    Serial.print("Subnet Mask : ");
    Serial.println(Ethernet.subnetMask());
    Serial.print("Gateway IP : ");
    Serial.println(Ethernet.gatewayIP());
    Serial.print("DNS Server : ");
    Serial.println(Ethernet.dnsServerIP());
 
   Serial.println("Ethernet Successfully Initialized");
  // if you get a connection, report back via serial:
  if (client.connect(server, 80)) {
    Serial.println("Connected!");
    // Make a HTTP request:
    client.println("GET /get HTTP/1.1");
    client.println("Host: httpbin.org");
    client.println("Connection: close");
    client.println();
  } else {
    // if you didn't get a connection to the server:
    Serial.println("connection failed");
  }
  beginMicros = micros();
}
 
void loop() {
  // if there are incoming bytes available
  // from the server, read them and print them:
  int len = client.available();
  if (len > 0) {
    byte buffer[80];
    if (len > 80) len = 80;
    client.read(buffer, len);
    if (printWebData) {
      Serial.write(buffer, len); // show in the serial monitor (slows some boards)
    }
    byteCount = byteCount + len;
  }
 
  // if the server's disconnected, stop the client:
  if (!client.connected()) {
    endMicros = micros();
    Serial.println();
    Serial.println("disconnecting.");
    client.stop();
    Serial.print("Received ");
    Serial.print(byteCount);
    Serial.print(" bytes in ");
    float seconds = (float)(endMicros - beginMicros) / 1000000.0;
    Serial.print(seconds, 4);
    float rate = (float)byteCount / seconds / 1000.0;
    Serial.print(", rate = ");
    Serial.print(rate);
    Serial.print(" kbytes/second");
    Serial.println();
 
    // do nothing forevermore:
    while (true) {
      delay(1);
    }
  }
}

This works much better, when ESP32 reboots, I get this on serial:

Begin Ethernet
STATIC OK!
Local IP : 192.168.1.28
Subnet Mask : 255.255.255.0
Gateway IP : 192.168.1.1
DNS Server : 192.168.1.1
Ethernet Successfully Initialized

I set my laptop IPv4 IP address to 192.168.1.20 and subnet mask to 255.255.255.0, so both devices should be on the same subnet and see each other, but for some reason I can't ping the ESP on 192.168.1.28 from the laptop, I get "destination host unreachable".

Any idea how to solve this last issue?

Not really, but have you tried without a gateway and DNS on the esp32?

Tried it just now - got the same gateway and dns assigned automatically by the library, but still not reachable from the laptop.

From that GitHUB:

First an important note: There are more suitable libraries for ENC28J60 with ESP8266, RP2040, ESP32 and Mbed Arduino platforms:

  • With ESP32 platform version 3 you can use the EthernetESP32 library which integrates with networking on the ESP32 platform.

Have you tried this?

You could try and work out how this library handles the connection in your specific use case by diving into the source code. I've had a quick look at it, but it's kind of a big library and I don't really feel like diving into it.

Okay, I followed your advice and switched to EthernetESP32 library. Tried one of the example sketches:

/**
 * BasivHttpClient example from the ESP32 HTTPClient library modified for Ethernet.
 */

#include <EthernetESP32.h>
#include <HTTPClient.h>

#define USE_SERIAL Serial
/*
const char* ca = \
"-----BEGIN CERTIFICATE-----\n" \
"MIIEkjCCA3qgAwIBAgIQCgFBQgAAAVOFc2oLheynCDANBgkqhkiG9w0BAQsFADA/\n" \
"MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT\n" \
"DkRTVCBSb290IENBIFgzMB4XDTE2MDMxNzE2NDA0NloXDTIxMDMxNzE2NDA0Nlow\n" \
"SjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUxldCdzIEVuY3J5cHQxIzAhBgNVBAMT\n" \
"GkxldCdzIEVuY3J5cHQgQXV0aG9yaXR5IFgzMIIBIjANBgkqhkiG9w0BAQEFAAOC\n" \
"AQ8AMIIBCgKCAQEAnNMM8FrlLke3cl03g7NoYzDq1zUmGSXhvb418XCSL7e4S0EF\n" \
"q6meNQhY7LEqxGiHC6PjdeTm86dicbp5gWAf15Gan/PQeGdxyGkOlZHP/uaZ6WA8\n" \
"SMx+yk13EiSdRxta67nsHjcAHJyse6cF6s5K671B5TaYucv9bTyWaN8jKkKQDIZ0\n" \
"Z8h/pZq4UmEUEz9l6YKHy9v6Dlb2honzhT+Xhq+w3Brvaw2VFn3EK6BlspkENnWA\n" \
"a6xK8xuQSXgvopZPKiAlKQTGdMDQMc2PMTiVFrqoM7hD8bEfwzB/onkxEz0tNvjj\n" \
"/PIzark5McWvxI0NHWQWM6r6hCm21AvA2H3DkwIDAQABo4IBfTCCAXkwEgYDVR0T\n" \
"AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwfwYIKwYBBQUHAQEEczBxMDIG\n" \
"CCsGAQUFBzABhiZodHRwOi8vaXNyZy50cnVzdGlkLm9jc3AuaWRlbnRydXN0LmNv\n" \
"bTA7BggrBgEFBQcwAoYvaHR0cDovL2FwcHMuaWRlbnRydXN0LmNvbS9yb290cy9k\n" \
"c3Ryb290Y2F4My5wN2MwHwYDVR0jBBgwFoAUxKexpHsscfrb4UuQdf/EFWCFiRAw\n" \
"VAYDVR0gBE0wSzAIBgZngQwBAgEwPwYLKwYBBAGC3xMBAQEwMDAuBggrBgEFBQcC\n" \
"ARYiaHR0cDovL2Nwcy5yb290LXgxLmxldHNlbmNyeXB0Lm9yZzA8BgNVHR8ENTAz\n" \
"MDGgL6AthitodHRwOi8vY3JsLmlkZW50cnVzdC5jb20vRFNUUk9PVENBWDNDUkwu\n" \
"Y3JsMB0GA1UdDgQWBBSoSmpjBH3duubRObemRWXv86jsoTANBgkqhkiG9w0BAQsF\n" \
"AAOCAQEA3TPXEfNjWDjdGBX7CVW+dla5cEilaUcne8IkCJLxWh9KEik3JHRRHGJo\n" \
"uM2VcGfl96S8TihRzZvoroed6ti6WqEBmtzw3Wodatg+VyOeph4EYpr/1wXKtx8/\n" \
"wApIvJSwtmVi4MFU5aMqrSDE6ea73Mj2tcMyo5jMd6jmeWUHK8so/joWUoHOUgwu\n" \
"X4Po1QYz+3dszkDqMp4fklxBwXRsW10KXzPMTZ+sOPAveyxindmjkW8lGy+QsRlG\n" \
"PfZ+G6Z6h7mjem0Y+iWlkYcV4PIWL1iwBi8saCbGS5jN2p8M+X+Q7UNKEkROb3N6\n" \
"KOqkqm57TH2H3eDJAkSnh6/DNFu0Qg==\n" \
"-----END CERTIFICATE-----\n";
*/

W5500Driver driver(2);

void setup() {

  USE_SERIAL.begin(115200);
  delay(500);
  while (!USE_SERIAL);

  USE_SERIAL.println();
  Ethernet.init(driver);

  USE_SERIAL.println("Initialize Ethernet with DHCP:");
  if (Ethernet.begin()) {
    USE_SERIAL.print("  DHCP assigned IP ");
    USE_SERIAL.println(Ethernet.localIP());
  } else {
    USE_SERIAL.println("Failed to configure Ethernet using DHCP");
    while (true) {
      delay(1);
    }
  }
}

void loop() {

  HTTPClient http;

  USE_SERIAL.print("[HTTP] begin...\n");
  // configure traged server and url
  //http.begin("https://www.howsmyssl.com/a/check", ca); //HTTPS
  http.begin("http://example.com/index.html");  //HTTP

  USE_SERIAL.print("[HTTP] GET...\n");
  // start connection and send HTTP header
  int httpCode = http.GET();

  // httpCode will be negative on error
  if (httpCode > 0) {
    // HTTP header has been send and Server response header has been handled
    USE_SERIAL.printf("[HTTP] GET... code: %d\n", httpCode);

    // file found at server
    if (httpCode == HTTP_CODE_OK) {
      String payload = http.getString();
      USE_SERIAL.println(payload);
    }
  } else {
    USE_SERIAL.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
  }

  http.end();

  delay(5000);
}

And got this:

Initialize Ethernet with DHCP:
E (1074) w5500.mac: W5500 version mismatched, expected 0x04, got 0x00
E (1074) w5500.mac: emac_w5500_init(825): vefiry chip ID failed
E (1075) esp_eth: esp_eth_driver_install(228): init mac failed
Failed to configure Ethernet using DHCP

Not entirely sure what does it mean by W5500 version... Scratching my head over this

This means it didn't find the module..
That lib defaults to SPI, which is used by the cam..
You need to tell the driver to use SPI1..
On the main git page, scroll down they have an example, just substitute your connections..

curious, when you got an IP using the other lib but just couldn't ping, was your firewall turned off in windows??

good luck.. ~q