I can't get this program to run on ESP32 with PlatformIO

This has me very confused!

I can run the following example on Arduino IDE for connecting my custom esp32 board with ethernet, and it connects to the test client, google.com, as expected :

#include <ETH.h>

static bool eth_connected = false;

void WiFiEvent(WiFiEvent_t event) {
  switch (event) {
    case SYSTEM_EVENT_ETH_START:
      Serial.println("ETH Started");
      //set eth hostname here
      ETH.setHostname("esp32-ethernet");
      break;
    case SYSTEM_EVENT_ETH_CONNECTED:
      Serial.println("ETH Connected");
      break;
    case SYSTEM_EVENT_ETH_GOT_IP:
      Serial.print("ETH MAC: ");
      Serial.print(ETH.macAddress());
      Serial.print(", IPv4: ");
      Serial.print(ETH.localIP());
      if (ETH.fullDuplex()) {
        Serial.print(", FULL_DUPLEX");
      }
      Serial.print(", ");
      Serial.print(ETH.linkSpeed());
      Serial.println("Mbps");
      eth_connected = true;
      break;
    case SYSTEM_EVENT_ETH_DISCONNECTED:
      Serial.println("ETH Disconnected");
      eth_connected = false;
      break;
    case SYSTEM_EVENT_ETH_STOP:
      Serial.println("ETH Stopped");
      eth_connected = false;
      break;
    default:
      break;
  }
}

void testClient(const char * host, uint16_t port) {
  Serial.println("starting testclient");
  Serial.print("\nconnecting to ");
  Serial.println(host);

  WiFiClient client;
  if (!client.connect(host, port)) {
    Serial.println("connection failed");
    return;
  }
  client.printf("GET / HTTP/1.1\r\nHost: %s\r\n\r\n", host);
  while (client.connected() && !client.available());
  while (client.available()) {
    Serial.write(client.read());
  }

  Serial.println("closing connection\n");
  client.stop();
}

void setup() {
  Serial.begin(115200);
  Serial.println("starting wifi onevent");
  WiFi.onEvent(WiFiEvent);
  Serial.println("ending wifi onevent");
  //ETH.begin(ETH_ADDR, ETH_POWER_PIN, ETH_MDC_PIN, ETH_MDIO_PIN, ETH_TYPE, ETH_CLK_MODE);
  Serial.println("starting eth begin");
  ETH.begin(0, 2, 23, 18, ETH_PHY_LAN8720, ETH_CLOCK_GPIO17_OUT);
  Serial.println("ending eth begin");
}


void loop() {
  Serial.println("starting loop");
  if (eth_connected) {
    testClient("<website address>", 80);
  }
  delay(10000);
}

This same code also compiles with no issues in PlatformIO, but after writing to the board it doesn’t connect at all to ethernet.

By adding print statements to debug, I was able to see that it fails with PlatformIO in void loop():

if (eth_connected) {

The only thing I can think of is that the platformio.ini file is missing something, or that the ETH library its using is somehow different to the one arduino finds.

Here is my platformio.ino (I have tested that this board type works with my custom board on other projects):

[env:eth]
platform = espressif32
board = esp32dev
framework = arduino
monitor_speed = 115200
build_unflags = -Werror=reorder

Any help would be very appreciated!

Which exact board do you have selected in the Arduino IDE, which exact Arduino-ESP32 core version are you running in the Arduino IDE (Tools->Board->Board Manager → esp32)?

Thanks, here are my Arduino board settings:

And I am running the esp32 1.0.6 board version (as found in board manager)

If you run the latest platform-espressif32 version in PlatformIO, you’re getting Arduino-ESP32 2.0.6. So that’s a whole major version in between.

Let’s try heavily downgrading the PlatformIO installation to that ancient bespoke 1.0.6 core. In the platformio.ini, use

platform = espressif32@3.5.0

instead of platform = espressif32 (releases). Save the file and wait until it’s relaoded completely. Then try uploading again.

oh wow, that works!!! thanks @maxgerhardt !!

Are there additional risks to using this ancient version of Platformio for esp32 ?

For risk of breakage with future PlatformIO core versions, you really don’t want to be on such an old platform-espressif32. Yes, only could also go the route of using the most recent platform-espressif32 but modifying the used framework-espressif32 version through platform_packages declarations, let’s not go this way.

I don’t see a reason why hardware that was working in 1.0.6 shouldn’t work with 2.0.6 (or 2.0.7 most recently). Something in the most recent core or library versions must be at fault. Maybe a changed default setting in regards to the used Ethernet PHY chip. Or maybe your used Ethernet chip was deactivated in the config. The Ethernet library’s development history hasn’t stood still, after all.

Please do the following:

  • As the documentation says, activate the most verbose debug level by adding build_flags = -DCORE_DEBUG_LEVEL=5. The Arduino-ESP32 core and/or Ethernet library might then output very helpful error messages in the serial monitor that might be the smoking gun as to why it’s not working.
  • Provide details on what Ethernet chip is used, which interface it uses (SPI, RMII, MII?), onto which pins it is connected to the ESP32 and how it’s clocked (if applicable).

Thanks again. I activated the verbose serial level, and interestingly it seems that it does connect to the router:

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:0x3fff0030,len:1184
load:0x40078000,len:13104
load:0x40080400,len:3036
entry 0x400805e4
[     6][D][esp32-hal-cpu.c:244] setCpuFrequencyMhz(): PLL: 480 / 2 = 240 Mhz, APB: 80000000 Hz
starting wifi onevent
ending wifi onevent
starting eth begin
[  1996][V][WiFiGeneric.cpp:437] _arduino_event_cb(): Ethernet Started
[  1997][D][WiFiGeneric.cpp:931] _eventCallback(): Arduino Event: 18 - ETH_START
[  1999][V][WiFiGeneric.cpp:430] _arduino_event_cb(): Ethernet Link Up
[  2005][D][WiFiGeneric.cpp:931] _eventCallback(): Arduino Event: 20 - ETH_CONNECTED
[  2009][V][WiFiGeneric.cpp:445] _arduino_event_cb(): Ethernet got newip:192.168.0.107
[  2020][D][WiFiGeneric.cpp:931] _eventCallback(): Arduino Event: 22 - ETH_GOT_IP
[  2027][D][WiFiGeneric.cpp:1032] _eventCallback(): ETH IP: 192.168.0.107, MASK: 255.255.255.0, GW: 192.168.0.1
ending eth begin
starting loop
starting loop

However then it has issues with the google.com connection. I also tried this with an MQTT library and it doesn’t connect there either. I wonder if there could be some issue with understanding the DNS endpoint ?

The board uses an ESP32 module with a LAN8720 PHY chip connected by RMII using the following pins:

#define ETH_CLK_MODE ETH_CLOCK_GPIO17_OUT
#define ETH_POWER_PIN 2
#define ETH_ADDR 0
#define ETH_MDC_PIN 23
#define ETH_MDIO_PIN 18

I will try with a local ip address to see if its a DNS read issue.

Same with IP addresses, I tried the cloudflare dns server and it doesn’t connect either.

As you can see in my last post, thanks to the verbose serial output, it does appear it connects to the router and receives an IP address. I don’t know why then it doesn’t connect to a site on the internet or an mqtt server (when using pubsub client library)

hmm my messages above seem to be hidden and marked as spam because I referred to the very popular website that I was using as a test for connection.

Yeah I just restored the messages, they were all automatically flagged by the system because of “multiple links to the same domain”.

Did you this example sketch?

Would also be interesting what IP it returns when you query ETH.dnsIP(); and print it.

Yes, thanks, this sketch is the same as mine, except I added different pins for the PHY.

So is the DNS IP it rerturns correct?

What is the exact verbose log when it tries to connect to google?

Using the latest espressif platform (6.0.1), the program never actually gets to the testclient() function because it fails at eth_connected:

It does manage to get an IP from the router however, so eth is working.

So… the WiFiEvent() function is never called at all since I don’t see those outputs at all, but internally it does see those events.

There might be something going on here with weak function linking in the library or core that prevents this from working. Can you add

lib_archive = no

in the platformio.ini and retry?

Or, your output is cutoff and the problem is actually the non-volatility of that check variable. Can you change it to

static volatile bool eth_connected = false;

if that doesn’t help?

I tried both suggestions independently and also together, but unfortunately they didn’t work.

adding lib_archive = no to the ini file, or volatile to the bool statement, didn’t make a difference.

just wanted to make sure I wasn’t missing something here.

When I revert the espressif platform in the ini, then clean the project, build and upload, it seems to pass eth_connected every time: