ESP32AsyncWebServer example will compile in Arduino but not in PlatformIO

I develop new bits of code in Arduino IDE and when they’re working, I bake them into my final project in PIO.

The target is a Waveshare ESP32-P4-ETH and I use esp32-p4 as the board identifier

I slightly modified an ESP-DashboardPlus example which compiles and runs in Arduino IDE, but I can’t get it to compile in PIO.

I have used the same libraries and the latest ESP32 framework, but no luck. I’ve tried the various fixes I’ve found in the forums , again no luck.

Currently the first error I get is

Compiling .pio\build\esp32-p4\lib40c\WebServer\middleware\MiddlewareChain.cpp.o fatal error: NetworkServer.h: No such file or directory

My PlatformIO.ini looks like this

[env:esp32-p4] platform = https://github.com/pioarduino/platform-espressif32/releases/download/stable/platform-espressif32.zip board = esp32-p4 framework = arduino

monitor_speed = 115200

lib_deps = ESP-DashboardPlus

ESP32Async/ESPAsyncWebServer

ArduinoJson

This is my main.cpp

#include <arduino.h>

#include <ETH.h>

#include <ESPAsyncWebServer.h>

#include "ESPDashboardPlus.h"

#include "dashboard_html.h"



#define ETH_PHY_TYPE ETH_PHY_TLK110

#define ETH_PHY_ADDR  1

#define ETH_PHY_MDC   31

#define ETH_PHY_MDIO  52

#define ETH_PHY_POWER 51

#define ETH_CLK_MODE  EMAC_CLK_EXT_IN

#define greenLED 8

#define redLED 46



AsyncWebServer server(80);

ESPDashboardPlus dashboard("My Device");



void setup() 

{

  Serial.begin(115200);

  IPAddress ip(192, 168, 1, 177);

  IPAddress gateway(192, 168, 0, 1);

  IPAddress subnet(255, 255, 254, 0);

  IPAddress dns(192, 168, 0, 1); 



  ETH.begin(ETH_PHY_TYPE, ETH_PHY_ADDR, ETH_PHY_MDC, ETH_PHY_MDIO, ETH_PHY_POWER, ETH_CLK_MODE);

  ETH.config(ip, gateway, subnet, dns); //Must be AFTER ETH.begin() !!!

  Serial.println(ETH.localIP());

    

    // Initialize dashboard with pre-compressed HTML

    dashboard.begin(&server, DASHBOARD_HTML_DATA, DASHBOARD_HTML_SIZE);

    

    // Add a stat card

    dashboard.addStatCard("temp", "Temperature", "23.5", "°C");

    pinMode(greenLED, OUTPUT);

    digitalWrite(greenLED, HIGH);

    pinMode(redLED, OUTPUT);

    digitalWrite(redLED, HIGH);

    // Add a toggle with callback

    ToggleCard* greenled = dashboard.addToggleCard("greenled", "Green LED", "Status", false);

    greenled->onChange = [](bool state) {

        digitalWrite(greenLED, !state);

    };

    ToggleCard* redled = dashboard.addToggleCard("redled", "Red LED", "Status", false);

    redled->onChange = [](bool state) {

        digitalWrite(redLED, !state);

    };

    server.begin();

}



void loop() {

    dashboard.loop();

    // Update values periodically

    static unsigned long lastUpdate = 0;

    if (millis() - lastUpdate > 2000) {

        lastUpdate = millis();

        dashboard.updateStatCard("temp", String(random(20, 30)));

    }

}

Any thoughts?

PlatformIO might think this is installed, when the same URL has been used in the past. I would use a direct URL to a specific version. E.g., set

platform = https://github.com/pioarduino/platform-espressif32/releases/download/55.03.39/platform-espressif32.zip

Thanks for the suggestion. Unfortunately it hasn’t made any difference.

I’ll try clearing the cache and compile again, but not looking hopeful.

I’d heard somewhere that there are incompatibilities between Arduino core releases and the AsyncWebServer, but don’t know how that might relate or what the fix might be….?

If a library doesn’t find its dependency, additionally try all lib_ldf_mode values. Setting the platform was just the base step to ensure that header file exists in the core at all.

See https://docs.platformio.org/en/latest/projectconf/sections/env/options/library/lib_ldf_mode.html

e.g.

lib_ldf_mode = chain+
lib_ldf_mode = deep
lib_ldf_mode = deep+

lib_ldf_mode = chain results in a first error of

.platformio/packages/framework-arduinoespressif32/libraries/WebServer/src/WebServer.h:28:10: fatal error: FS.h: No such file or directory

lib_ldf_mode = chain+ results in a first error of

Compiling .pio\build\esp32-p4\lib750\WiFi\WiFiSTA.cpp.o
.pio/libdeps/esp32-p4/AsyncTCP@3.3.2/src/AsyncTCP.cpp:41:12: fatal error: NetworkInterface.h: No such file or directory (I’m using Ethernet not WiFi, so puzzling…)

lib_ldf_mode = deep compiles much deeper and then results in a first error of

.pio/libdeps/esp32-p4/ESPAsyncWebServer/src/ESPAsyncWebServer.h: In member function ‘tcp_state AsyncWebServer::state() const’:
.pio/libdeps/esp32-p4/ESPAsyncWebServer/src/ESPAsyncWebServer.h:1691:49: error: passing ‘const AsyncServer’ as ‘this’ argument discards qualifiers [-fpermissive]

lib_ldf_mode = deep+ fails quickly and results in a first error of

.platformio/packages/framework-arduinoespressif32/libraries/WiFi/src/STA.cpp:6:
C:/Users/ChrisSaich/.platformio/packages/framework-arduinoespressif32/libraries/WiFi/src/WiFiGeneric.h:44:10: fatal error: Network.h: No such file or directory

This looks best, “just” a compile error instead of a straight “Library not found”.

All of these expressions don’t include any versioning info, this is important to keep the compilation stable. Also, the discussion at https://github.com/ESP32Async/ESPAsyncWebServer/discussions/443 hints at the subdependency AsynTCP needing an update.

Can you explicitly say

lib_deps =
  aaronbeckmann/ESP-DashboardPlus@^1.1.0
  esp32async/ESPAsyncWebServer@^3.11.2
  esp32async/AsyncTCP@^3.5.0
  bblanchon/ArduinoJson@^7.4.3

and retry?

Or not, try changing the AsyncTcp line to

  AsyncTCP=esp32async/AsyncTCP@^3.5.0

Thanks@maxgerhardt. I made all lib_deps release specific and that went further, but came across a compile error relating to ESPDashboardPlus unable to find Update.h.

I’m away from my PC for a while but will look into this later.

Mh yes, since the library does a conditional include

It needs a lib_ldf_mode that evaluates these macros, which are the + ones.. the non-plus ones include it unconditionally..

I’ve tried with both deep+ and chain+ and both result in

Compiling .pio\build\esp32-p4\lib7bd\FS\vfs_api.cpp.o
.pio/libdeps/esp32-p4/AsyncTCP@3.3.2/src/AsyncTCP.cpp:41:12: fatal error: NetworkInterface.h: No such file or directory

I just checked myself that

[env:esp32-p4]
platform = https://github.com/pioarduino/platform-espressif32/releases/download/55.03.39/platform-espressif32.zip
board = esp32-p4
framework = arduino
monitor_speed = 115200
lib_deps =
  aaronbeckmann/ESP-DashboardPlus@^1.1.0

compiles the reference sketch (ESP-DashboardPlus/examples/basic/main.cpp at 1.1.0 · aaronbeckmann/ESP-DashboardPlus · GitHub) fine.

The library already explicitly lists its dependencies, no need to add more.

Delete any C:\users\<user>\.platformio\packages\framework-arduinoespressif32* folders and C:\users\<user>\.platformio\platforms\epsressif32* before that.

RAM:   [=         ]   9.5% (used 31092 bytes from 327680 bytes)
Flash: [=======   ]  72.8% (used 954256 bytes from 1310720 bytes)
Building .pio\build\esp32-p4\firmware.bin
esptool v5.3.0
Creating ESP32-P4 image...
Merged 4 ELF sections.
Successfully created ESP32-P4 image.
Creating binary "firmware.factory.bin" with:
    Offset   | File
 -  0x2000   | bootloader.bin
 -  0x8000   | partitions.bin
 -  0xe000   | boot_app0.bin
 -  0x10000  | firmware.bin
Successfully created combined binary image.
============================================ [SUCCESS] Took 493.79 seconds ============================================

That has built and uploaded for me too!

Thanks for your help, I really appreciate it, you put in a lot of effort for me.

Glad it is working. This confirms the problem was caused by stale/mixed PlatformIO framework packages and duplicate dependency resolution, rather than ESPAsyncWebServer or Ethernet itself.

For future builds, I would keep the tested platform release pinned and declare only the top-level dependency:

platform = https://github.com/pioarduino/platform-espressif32/releases/download/55.03.39/platform-espressif32.zip

lib_deps =
    aaronbeckmann/ESP-DashboardPlus@^1.1.0

ESP-DashboardPlus already declares ESPAsyncWebServer and AsyncTCP, so adding them separately can cause PlatformIO to select incompatible versions. It may also be worth documenting the working configuration, since changing stable later could silently introduce a different Arduino core.

Keeping library versions explicit is useful for reproducible PlatformIO builds. This PlatformIO-based ESP32 example also demonstrates declaring versioned dependencies through lib_deps. In this case, however, only ESP-DashboardPlus should be declared because it already specifies its own ESPAsyncWebServer and AsyncTCP dependencies.