PlatformIO Community

Fatal error: ESPAsyncTCP.h: No Such File


#1

I am trying to implement the ESP Async Webserver for the ESP32. When trying to use the example code for this library, one of the dependencies is ESPAsyncTCP.h. I keep getting: Compiling .pioenvs\esp-wrover-kit\libaa2\WiFi\WiFiAP.cpp.o
src\main.cpp:6:26: fatal error: ESPAsyncTCP.h: No such file or directory.
Even though I see the the library under .piolibdeps, where I installed it along with the other libraries required for the example code. All the libraries seems to be visible to the program except for the ESPAsync.h header. I have no idea what to do to change this.
One interesting note: After installing libraries that were not visible to the project and were stopping the project from compiling I notice while researching that Under POI Home, I am seeing some of these libraries install under global storage, even though I thought I only installed them with project visibility.
Do I need to uninstall the local libraries?
If so, how to I get the project to recognize the global libraries?]
Thanks


#2

I would try an uninstall the global library that you have previously installed. There seem to be two AsyncTCP libraries.

The one which has the ESPAsyncTCP.h header file is however the ESP8266 version and not the ESP32 version?

https://github.com/me-no-dev/ESPAsyncTCP/tree/master/src has ESPAsyncTCP.h and is for ESP8266.

https://github.com/me-no-dev/AsyncTCP/tree/master/src has AsyncTCP.h and is for ESP32.

Maybe you confused the libraries?

Anyway if you are sure which library (and thus example code) you want to use you can also just declare them in lib_deps = ... per-project


#3

@maxgerhardt
Thank you for your quick response.
I did like you suggested and removed all libs excepts for the ones in my project. But after restarting VS the IDE put the ESPAsyncTCP.h back, and I still get the error of “No such file”
Also the first time I built after restarting I got:
C* [.pioenvs\esp-gateway\src\main.cpp.o] Error 1ompiling .pioenvs\esp-gateway\lib458\SHA-1 Hash_ID1828\Hash.cpp.o.
But the second time I built, the SHA error went away and was replaced with the ESPAsyncTCP error.
I’m stuck


#4

So what’s your platformio.ini and which example code do you want to compile?


#5

[env:esp-gateway]
platform = espressif32
board = esp32-gateway
framework = arduino
lib_deps =

Using a library name

ESP Async WebServer
ESPAsyncTCP
DNSServer
SHA-1 Hash

The program I am trying to implement is:

While going back and looking for the link, I found a simpler example that I missed.
While I do need to send some large VueJS files using the SD file system. Maybe I could get the simpler example up and going. But this would not explain the problems I am having and I would probably be right back asking how to manage library #includes.
Thanks for your help


#6

But judging from the includes

#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <ArduinoOTA.h>
#include <FS.h>
#include <Hash.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <SPIFFSEditor.h>

This is for the ESP8266?

Please use code-listing markdown with three backticks to format the code, otherwise I might not reconstruct the same platformio.ini you have.


#7

Please forgive me, I’m not sure of your request, are you asking for the platformio.ini file or the program file. Below is the ini file. The program file is unaltered from git.

[env:esp-gateway]
platform = espressif32
board = esp32-gateway
framework = arduino
lib_deps =
  # Using a library name
  ESP Async WebServer
  ESPAsyncTCP
  DNSServer
  SHA-1 Hash
  #FS

While looking to find your previous requests, I stumbled accross this note @
https://github.com/me-no-dev/ESPAsyncWebServer

Async HTTP and WebSocket Server for ESP8266 Arduino

For ESP8266 it requires ESPAsyncTCP To use this library you might need to have the latest git versions of ESP8266 Arduino Core

For ESP32 it requires AsyncTCP to work To use this library you might need to have the latest git versions of ESP32 Arduino Core

So maybe I am asking you to solve an issues cause, not by ignorance of the IDE but of how to implement the proper libraries. This is why I hate forums, it only points out what I might have missed.
Again, thanks,


#8

The three … did not do as expected. I don’t do forums often. Sorry


#9

No problem.

You can compile the AsyncWebServer simpleserver.ino by using the following platformio.ini and main.cpp code

[env:esp-gateway]
platform = espressif32
board =  esp32-gateway
framework = arduino
lib_deps = 
	AsyncTCP
	SHA-1 Hash

For the main.cpp you just have to switch out the library headers to the ESP32 version (ESPAsyncTyp.h -> AsyncTCP.h and ESP8266WiFi.h to WiFi.h) and correct WiFi.hostname() to WiFi.getHostname():

//
// A simple server implementation showing how to:
//  * serve static messages
//  * read GET and POST parameters
//  * handle missing pages / 404s
//

#include <Arduino.h>
#include <WiFi.h>
#include <Hash.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>

AsyncWebServer server(80);

const char* ssid = "YOUR_SSID";
const char* password = "YOUR_PASSWORD";

const char* PARAM_MESSAGE = "message";

void notFound(AsyncWebServerRequest *request) {
    request->send(404, "text/plain", "Not found");
}

void setup() {

    Serial.begin(115200);
    WiFi.mode(WIFI_STA);
    WiFi.begin(ssid, password);
    if (WiFi.waitForConnectResult() != WL_CONNECTED) {
        Serial.printf("WiFi Failed!\n");
        return;
    }

    Serial.print("IP Address: ");
    Serial.println(WiFi.localIP());
    Serial.print("Hostname: ");
    Serial.println(WiFi.getHostname ());

    server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
        request->send(200, "text/plain", "Hello, world");
    });

    // Send a GET request to <IP>/get?message=<message>
    server.on("/get", HTTP_GET, [] (AsyncWebServerRequest *request) {
        String message;
        if (request->hasParam(PARAM_MESSAGE)) {
            message = request->getParam(PARAM_MESSAGE)->value();
        } else {
            message = "No message sent";
        }
        request->send(200, "text/plain", "Hello, GET: " + message);
    });

    // Send a POST request to <IP>/post with a form field message set to <message>
    server.on("/post", HTTP_POST, [](AsyncWebServerRequest *request){
        String message;
        if (request->hasParam(PARAM_MESSAGE, true)) {
            message = request->getParam(PARAM_MESSAGE, true)->value();
        } else {
            message = "No message sent";
        }
        request->send(200, "text/plain", "Hello, POST: " + message);
    });

    server.onNotFound(notFound);

    server.begin();
}

void loop() {
}

By doing similiar modifications I presume you can get the ESP_AsyncFSBrowser working.


#10

You can also compile the ESP_AsyncFSBrowser.ino by modifying the source code to use the ESP32 libraries and the SPIFFS filesystem (along with the correction of a few SPIFFS API calls)

main.cpp

#include <WiFi.h>
#include <ESPmDNS.h>
#include <ArduinoOTA.h>
#include <FS.h>
#include <Hash.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <SPIFFSEditor.h>
#include <SPIFFS.h>

// SKETCH BEGIN
AsyncWebServer server(80);
AsyncWebSocket ws("/ws");
AsyncEventSource events("/events");

void onWsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len){
  if(type == WS_EVT_CONNECT){
    Serial.printf("ws[%s][%u] connect\n", server->url(), client->id());
    client->printf("Hello Client %u :)", client->id());
    client->ping();
  } else if(type == WS_EVT_DISCONNECT){
    Serial.printf("ws[%s][%u] disconnect: %u\n", server->url(), client->id());
  } else if(type == WS_EVT_ERROR){
    Serial.printf("ws[%s][%u] error(%u): %s\n", server->url(), client->id(), *((uint16_t*)arg), (char*)data);
  } else if(type == WS_EVT_PONG){
    Serial.printf("ws[%s][%u] pong[%u]: %s\n", server->url(), client->id(), len, (len)?(char*)data:"");
  } else if(type == WS_EVT_DATA){
    AwsFrameInfo * info = (AwsFrameInfo*)arg;
    String msg = "";
    if(info->final && info->index == 0 && info->len == len){
      //the whole message is in a single frame and we got all of it's data
      Serial.printf("ws[%s][%u] %s-message[%llu]: ", server->url(), client->id(), (info->opcode == WS_TEXT)?"text":"binary", info->len);

      if(info->opcode == WS_TEXT){
        for(size_t i=0; i < info->len; i++) {
          msg += (char) data[i];
        }
      } else {
        char buff[3];
        for(size_t i=0; i < info->len; i++) {
          sprintf(buff, "%02x ", (uint8_t) data[i]);
          msg += buff ;
        }
      }
      Serial.printf("%s\n",msg.c_str());

      if(info->opcode == WS_TEXT)
        client->text("I got your text message");
      else
        client->binary("I got your binary message");
    } else {
      //message is comprised of multiple frames or the frame is split into multiple packets
      if(info->index == 0){
        if(info->num == 0)
          Serial.printf("ws[%s][%u] %s-message start\n", server->url(), client->id(), (info->message_opcode == WS_TEXT)?"text":"binary");
        Serial.printf("ws[%s][%u] frame[%u] start[%llu]\n", server->url(), client->id(), info->num, info->len);
      }

      Serial.printf("ws[%s][%u] frame[%u] %s[%llu - %llu]: ", server->url(), client->id(), info->num, (info->message_opcode == WS_TEXT)?"text":"binary", info->index, info->index + len);

      if(info->opcode == WS_TEXT){
        for(size_t i=0; i < info->len; i++) {
          msg += (char) data[i];
        }
      } else {
        char buff[3];
        for(size_t i=0; i < info->len; i++) {
          sprintf(buff, "%02x ", (uint8_t) data[i]);
          msg += buff ;
        }
      }
      Serial.printf("%s\n",msg.c_str());

      if((info->index + len) == info->len){
        Serial.printf("ws[%s][%u] frame[%u] end[%llu]\n", server->url(), client->id(), info->num, info->len);
        if(info->final){
          Serial.printf("ws[%s][%u] %s-message end\n", server->url(), client->id(), (info->message_opcode == WS_TEXT)?"text":"binary");
          if(info->message_opcode == WS_TEXT)
            client->text("I got your text message");
          else
            client->binary("I got your binary message");
        }
      }
    }
  }
}


const char* ssid = "*******";
const char* password = "*******";
const char * hostName = "esp-async";
const char* http_username = "admin";
const char* http_password = "admin";

void setup(){
  Serial.begin(115200);
  Serial.setDebugOutput(true);
  WiFi.setHostname(hostName);
  WiFi.mode(WIFI_AP_STA);
  WiFi.softAP(hostName);
  WiFi.begin(ssid, password);
  if (WiFi.waitForConnectResult() != WL_CONNECTED) {
    Serial.printf("STA: Failed!\n");
    WiFi.disconnect(false);
    delay(1000);
    WiFi.begin(ssid, password);
  }

  //Send OTA events to the browser
  ArduinoOTA.onStart([]() { events.send("Update Start", "ota"); });
  ArduinoOTA.onEnd([]() { events.send("Update End", "ota"); });
  ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
    char p[32];
    sprintf(p, "Progress: %u%%\n", (progress/(total/100)));
    events.send(p, "ota");
  });
  ArduinoOTA.onError([](ota_error_t error) {
    if(error == OTA_AUTH_ERROR) events.send("Auth Failed", "ota");
    else if(error == OTA_BEGIN_ERROR) events.send("Begin Failed", "ota");
    else if(error == OTA_CONNECT_ERROR) events.send("Connect Failed", "ota");
    else if(error == OTA_RECEIVE_ERROR) events.send("Recieve Failed", "ota");
    else if(error == OTA_END_ERROR) events.send("End Failed", "ota");
  });
  ArduinoOTA.setHostname(hostName);
  ArduinoOTA.begin();

  MDNS.addService("http","tcp",80);

  SPIFFS.begin();

  ws.onEvent(onWsEvent);
  server.addHandler(&ws);

  events.onConnect([](AsyncEventSourceClient *client){
    client->send("hello!",NULL,millis(),1000);
  });
  server.addHandler(&events);

  server.addHandler(new SPIFFSEditor(SPIFFS, http_username,http_password));

  server.on("/heap", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send(200, "text/plain", String(ESP.getFreeHeap()));
  });

  server.serveStatic("/", SPIFFS, "/").setDefaultFile("index.htm");

  server.onNotFound([](AsyncWebServerRequest *request){
    Serial.printf("NOT_FOUND: ");
    if(request->method() == HTTP_GET)
      Serial.printf("GET");
    else if(request->method() == HTTP_POST)
      Serial.printf("POST");
    else if(request->method() == HTTP_DELETE)
      Serial.printf("DELETE");
    else if(request->method() == HTTP_PUT)
      Serial.printf("PUT");
    else if(request->method() == HTTP_PATCH)
      Serial.printf("PATCH");
    else if(request->method() == HTTP_HEAD)
      Serial.printf("HEAD");
    else if(request->method() == HTTP_OPTIONS)
      Serial.printf("OPTIONS");
    else
      Serial.printf("UNKNOWN");
    Serial.printf(" http://%s%s\n", request->host().c_str(), request->url().c_str());

    if(request->contentLength()){
      Serial.printf("_CONTENT_TYPE: %s\n", request->contentType().c_str());
      Serial.printf("_CONTENT_LENGTH: %u\n", request->contentLength());
    }

    int headers = request->headers();
    int i;
    for(i=0;i<headers;i++){
      AsyncWebHeader* h = request->getHeader(i);
      Serial.printf("_HEADER[%s]: %s\n", h->name().c_str(), h->value().c_str());
    }

    int params = request->params();
    for(i=0;i<params;i++){
      AsyncWebParameter* p = request->getParam(i);
      if(p->isFile()){
        Serial.printf("_FILE[%s]: %s, size: %u\n", p->name().c_str(), p->value().c_str(), p->size());
      } else if(p->isPost()){
        Serial.printf("_POST[%s]: %s\n", p->name().c_str(), p->value().c_str());
      } else {
        Serial.printf("_GET[%s]: %s\n", p->name().c_str(), p->value().c_str());
      }
    }

    request->send(404);
  });
  server.onFileUpload([](AsyncWebServerRequest *request, const String& filename, size_t index, uint8_t *data, size_t len, bool final){
    if(!index)
      Serial.printf("UploadStart: %s\n", filename.c_str());
    Serial.printf("%s", (const char*)data);
    if(final)
      Serial.printf("UploadEnd: %s (%u)\n", filename.c_str(), index+len);
  });
  server.onRequestBody([](AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total){
    if(!index)
      Serial.printf("BodyStart: %u\n", total);
    Serial.printf("%s", (const char*)data);
    if(index + len == total)
      Serial.printf("BodyEnd: %u\n", total);
  });
  server.begin();
}

void loop(){
  ArduinoOTA.handle();
}

Remember to copy the data dir from the repo into your project and use the Upload SPIFFS image to upload it :slight_smile:


#11

@maxgerhardt,
Thank you, I need to slow down and digest all the help you have given. It will probably be tomorrow before I can go though all the tries and re-tries to make sure I have properly understood and implemented your suggestions. I will report back, but if you are not available or busy, I just want to say thanks. I usually have to wait days for help on other forums, but this was a nice change. Hopefully I don’t get spoiled and use it as a crutch. :slight_smile:


#12

@maxgerhardt,
You are awesome. It compiles. The problem, which you already know, is that I was calling the wrong libs. I had already changed some of them because I could find the ESP32 alternatives. But I had become stuck. But you found it very quickly. I had a problem with what would satisfy the c++ signature of the SPIFFSEditor(const fs::FS& fs,… so I just remmed it out. I will go back tomorrow and finish with the data and upload you suggested. Thanks, thanks, thanks.
Hopefully you are around when I try and circumvent the FreeRTOS critical mutex limit in the ESP32 SPI module that is keeping me from acquiring the 100 KSmpls/Sec from an external ADC in the future. :slight_smile: