HTTP_GET не уточняется в области применения

Я пытаюсь сделать асинхронный веб-сервер с точкой доступа, используя ESP32.

Это немного похоже на смесь между этим учебником для AP и async и этим учебником, так как он также работает с асинхронным веб-сервером и использует входные данные, которые мне отчаянно нужны.

Часть, которую я не понимаю, заключается в том, что я включил все необходимые библиотеки, и я все равно получил эту ошибку. Если я скопирую код в один блок,все будет хорошо. Никогда не было необходимости объявлять HTTP_GET, так как это должна быть переменная из библиотеки.

Так в чем же дело?

Вот мои ошибки:

    In file included from C:\..\Arduino\libraries\ESPAsyncWebServer-master\src/ESPAsyncWebServer.h:467:0,
                     from C:\..\AppData\Local\Temp\arduino_build_497972\sketch\webserver.h:5,
                     from C:\..\Async Webserver ESP32\main\main.ino:3:
    C:\..\Arduino\libraries\ESPAsyncWebServer-master\src/WebHandlerImpl.h: In constructor 'AsyncCallbackWebHandler::AsyncCallbackWebHandler()':
    C:\..\Arduino\libraries\ESPAsyncWebServer-master\src/WebHandlerImpl.h:76:49: error: 'HTTP_ANY' was not declared in this scope
         AsyncCallbackWebHandler() : _uri(), _method(HTTP_ANY), _onRequest(NULL), _onUpload(NULL), _onBody(NULL), _isRegex(false) {}
                                                     ^
    In file included from C:\..\Arduino\libraries\ESPAsyncWebServer-master\src/ESPAsyncWebServer.h:467:0,
                     from C:\..\AppData\Local\Temp\arduino_build_497972\sketch\webserver.h:5,
                     from C:\..\AppData\Local\Temp\arduino_build_497972\sketch\webserver.cpp:1:
    C:\..\Arduino\libraries\ESPAsyncWebServer-master\src/WebHandlerImpl.h: In constructor 'AsyncCallbackWebHandler::AsyncCallbackWebHandler()':
    C:\..\Arduino\libraries\ESPAsyncWebServer-master\src/WebHandlerImpl.h:76:49: error: 'HTTP_ANY' was not declared in this scope
         AsyncCallbackWebHandler() : _uri(), _method(HTTP_ANY), _onRequest(NULL), _onUpload(NULL), _onBody(NULL), _isRegex(false) {}
                                                     ^
    C:\Users\Valentin\AppData\Local\Temp\arduino_build_497972\sketch\webserver.cpp: In function 'void setup_server(AsyncWebServer)':
    webserver.cpp:6:18: error: 'HTTP_GET' was not declared in this scope
       server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
                      ^
    Multiple libraries were found for "WiFi.h"
     Used: C:\..\Arduino15\packages\firebeetle32\hardware\esp32\0.1.1\libraries\WiFi
     Not used: C:\Program Files (x86)\Arduino\libraries\WiFi
    Using library ESPAsyncWebServer-master at version 1.2.3 in folder: C:\..\Arduino\libraries\ESPAsyncWebServer-master 
    Using library FS at version 1.0 in folder: C:\..\Arduino15\packages\firebeetle32\hardware\esp32\0.1.1\libraries\FS 
    Using library WiFi at version 1.0 in folder: C:\..\Arduino15\packages\firebeetle32\hardware\esp32\0.1.1\libraries\WiFi 
    Using library AsyncTCP-master at version 1.1.1 in folder: C:\..\Arduino\libraries\AsyncTCP-master 
    exit status 1
    'HTTP_GET' was not declared in this scope

Я уже пытался использовать стандартную библиотеку Arduino WiFi, что привело к большему количеству ошибок, поэтому я переключил ее обратно.

Я разделил код на три части для лучшей видимости.

главная.ино

#include <Arduino.h>
#include "webserver.h"
    
// ЗАМЕНИТЬ СЕТЕВЫМИ УЧЕТНЫМИ ДАННЫМИ
const char* ssid = "blabla";
const char* password = "blabla";
    
void setup() {
  Serial.begin(115200);
  WiFi.softAP(ssid, password);
  IP = WiFi.softAPIP();
    
  Serial.println();
  Serial.print("IP Address: ");
  Serial.println(IP);
      
  setup_server(server);
}

void loop() {}

webserver.cpp

#include "webserver.h"
    
void setup_server(AsyncWebServer server) {
  // Отправить веб-страницу с полями ввода на клиентский
  server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
    request->send_P(200, "text/html", index_html);
  });
    
  // Отправить запрос GET в <ESP_IP>/get?input1=<inputMessage>
  server.on("/get", HTTP_GET, [] (AsyncWebServerRequest * request) {
    // ПОЛУЧИТЬ значение input1 в <ESP_IP>/получить?input1=<inputMessage>
    if (request->hasParam(PARAM_INPUT_1)) {
      inputMessage = request->getParam(PARAM_INPUT_1)->value();
      inputParam = PARAM_INPUT_1;
    }
    // ПОЛУЧИТЬ значение input2 в <ESP_IP>/получить?input2=<inputMessage>
    else if (request->hasParam(PARAM_INPUT_2)) {
      inputMessage = request->getParam(PARAM_INPUT_2)->value();
      inputParam = PARAM_INPUT_2;
    }
    // ПОЛУЧИТЬ значение input3 в <ESP_IP>/получить?input3=<inputMessage>
    else if (request->hasParam(PARAM_INPUT_3)) {
      inputMessage = request->getParam(PARAM_INPUT_3)->value();
      inputParam = PARAM_INPUT_3;
    }
    else {
      inputMessage = "No message sent";
      inputParam = "none";
    }
    Serial.println(inputMessage);
    request->send(200, "text/html", "HTTP GET request sent to your ESP on input field ("
      + inputParam + ") with value: " + inputMessage +
      "<br><a href=\"/\">Return to Home Page</a>");
    });
    server.onNotFound(notFound);
    server.begin();
  }
    
void notFound(AsyncWebServerRequest *request) {
  request->send(404, "text/plain", "Not found");
}

webserver.h

#ifndef WEBSERVER_H
#define WEBSERVER_H
    
#include "Arduino.h"
#include "ESPAsyncWebServer.h"
#include "AsyncTCP.h"
#include <WiFi.h>
    
const char* PARAM_INPUT_1 = "input1";
const char* PARAM_INPUT_2 = "input2";
const char* PARAM_INPUT_3 = "input3";
  
AsyncWebServer server(80);
    
String music_state;
IPAddress IP;
    
String inputMessage;
String inputParam;
    
// HTML web page to handle 3 input fields (input1, input2, input3)
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html><head>
  <title>ESP Input Form</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  </head><body>
  <form action="/get">
    input1: <input type="text" name="input1">
    <input type="submit" value="Submit">
  </form><br>
  <form action="/get">
    input2: <input type="text" name="input2">
    <input type="submit" value="Submit">
  </form><br>
  <form action="/get">
    input3: <input type="text" name="input3">
    <input type="submit" value="Submit">
  </form>
</body></html>)rawliteral";

void setup_server(AsyncWebServer server);
    
void notFound(AsyncWebServerRequest *request);
    
#endif

Спасибо за информацию, я вернусь завтра, отвечу на все вопросы и проверю каждое предложение.

, 👍0


1 ответ


Лучший ответ:

2

Макроконфликт

Здесь у вас есть две основные проблемы. Более важным является то, что вы используете SERVER_H в своем include guard:

#ifndef WEBSERVER_H
#define WEBSERVER_H

конфликты с использованием в ESPAsyncWebServer.h:

#ifndef WEBSERVER_H
typedef enum {
  HTTP_GET     = 0b00000001,
  HTTP_POST    = 0b00000010,
  HTTP_DELETE  = 0b00000100,
  HTTP_PUT     = 0b00001000,
  HTTP_PATCH   = 0b00010000,
  HTTP_HEAD    = 0b00100000,
  HTTP_OPTIONS = 0b01000000,
  HTTP_ANY     = 0b01111111,
} WebRequestMethod;
#endif

и это объясняет, почему ваш HTTP_GET и т. Д. Не найдены. Они не определяются из-за вашего макроса include guard.

Изменение кода на:

#ifndef XENOSHELL_WEBSERVER_H
#define XENOSHELL_WEBSERVER_H

или что-то подобное поможет вам преодолеть эту проблему.

Умножение определенных переменных

У вас также есть некоторые нестатические переменные, определенные в вашем webserver.h, которые также должны быть каким-то образом изменены. Простое изменение просто для того, чтобы сделать их статичными:

static const char* PARAM_INPUT_1 = "input1";
static const char* PARAM_INPUT_2 = "input2";
static const char* PARAM_INPUT_3 = "input3";

IPAddress IP; используется только в main.ino и должен быть перемещен туда как локальная константа IPAddress IP = WiFi.softAPIP(); Если вы оставите его в заголовке, вы получите несколько определений из-за этого.

String inputMessage; и String inputParam; Та же проблема, только они принадлежат внутри вашего лямбда-выражения в server.on("/get", HTTP_GET, [] (AsyncWebServerRequest * request) {

Я тоже не знаю, почему ваша серверная переменная находится в заголовке. Самое простое, что можно сделать, - это положить его в webserver.cpp вместо этого и не передавайте его в setup_server, другими словами, удалите параметр и используйте переменную, определенную в том же файле, что и функция.


Сделав это, ваш код компилируется нормально. Работает это или нет - другой вопрос. Я не могу это проверить.

,

привет @timemage спасибо за ваш очень подробный ответ. Я тоже получил код для компиляции, но когда я попытался подключиться к Wi-Fi из ESP, IP-адрес недоступен. Вывод, который я получаю от последовательного монитора, - " dhcps: send_offer>>udp_sendto result 0 ". Может быть, вы знаете, в чем может быть проблема?, @Xenoshell

На данный момент у меня нет платы ESP32, поэтому у меня нет возможности устранить эту проблему. То, о чем вы спрашиваете, кажется совершенно новым вопросом. Я бы сказал, сократите свою программу до минимума, необходимого для демонстрации проблемы. Учитывая сообщение, которое вы цитируете, ваша демо-программа вообще не должна содержать "#include"ESPAsyncWebServer.h" или "#include "AsyncTCP.h". Если вы не обнаружите проблему в ходе создания демо-версии, опубликуйте ее как часть нового вопроса., @timemage

Хорошо еще спасибо за ваши ответы, прямо сейчас я останавливаюсь на версии, которая работает, и если у меня будет достаточно времени, я вернусь к этой проблеме, @Xenoshell

Благодарю вас! Это очень полезный ответ с экспертным анализом., @Sun Bee