简体   繁体   English

ESP8266 ESPAsyncWebServer 不会在回调中切换 GPIO

[英]ESP8266 ESPAsyncWebServer does not toggle GPIO in callback

I am simply trying to turn a pin off and on when I press a button from a webpage.当我按下网页上的按钮时,我只是想关闭和打开别针。 I know the hardware works as I am able to toggle it in a different program.我知道硬件可以工作,因为我可以在不同的程序中切换它。 I am new to using this library, so I am sure I am missing something small here.... Why will it not toggle my output in the callback.我是使用这个库的新手,所以我确定我在这里遗漏了一些小东西......为什么它不会在回调中切换我的 output。 I have executed the code to toggle that pin HIGH and LOW outside of the callback and it works.我已经执行了代码以在回调之外切换该引脚 HIGH 和 LOW 并且它可以工作。

  server.on("/door1", HTTP_GET, [] (AsyncWebServerRequest *request) {
    pinMode(5, OUTPUT);
    delay(10);
    digitalWrite(5, HIGH);
    delay(5000);
    digitalWrite(5, LOW);
    request->send(SPIFFS, "/index.html", String(), false);
  });

Full code below:完整代码如下:

// Import required libraries
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <FS.h>

// NetworkCreds
const char* ssid = "******";
const char* password = "*****";

// Create AsyncWebServer object on port 80
AsyncWebServer server(80);

void setup(){
  // Serial port for debugging purposes
  Serial.begin(115200);

  // Initialize SPIFFS
  if(!SPIFFS.begin()){
    Serial.println("An Error has occurred while mounting SPIFFS");
    return;
  }

  // Connect to Wi-Fi
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi..");
  }

  // Print ESP32 Local IP Address
  Serial.println(WiFi.localIP());

  // Route for root / web page
  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send(SPIFFS, "/index.html", String(), false);
  });
  
  // Route to load style.css file
  server.on("/style.css", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send(SPIFFS, "/style.css", "text/css");
  });

  server.on("/door1", HTTP_GET, [] (AsyncWebServerRequest *request) {
    pinMode(5, OUTPUT);
    delay(10);
    digitalWrite(5, HIGH);
    delay(5000);
    digitalWrite(5, LOW);
    request->send(SPIFFS, "/index.html", String(), false);
  });

  // Start server
  server.begin();
}

void loop(){
 
}

Don't call delay() (or yield() ) inside callbacks from the async web server.不要在异步 web 服务器的回调中调用delay() (或yield() )。 Doing so blocks the event handler task and may cause the TCP connection or HTTP protocol to fail.这样做会阻止事件处理程序任务,并可能导致 TCP 连接或 HTTP 协议失败。 The async web documentation calls this out in the "Important things to remember" section.异步 web 文档在“要记住的重要事项”部分中对此进行了说明。

Instead, set a flag that indicates that the work needs to be done and then do the work in loop() .相反,设置一个标志,指示需要完成工作,然后在loop()中完成工作。

For instance,例如,

AsyncWebServer server(80);

boolean toggle_gpio = false;

void setup(){

and

  server.on("/door1", HTTP_GET, [] (AsyncWebServerRequest *request) {
    Serial.println("requesting toggle gpio");
    toggle_gpio = true;
    request->send(SPIFFS, "/index.html", String(), false);
  });

and

void loop() {
  if(toggle_gpio) {
    Serial.println("toggling GPIO");
    pinMode(5, OUTPUT);
    delay(10);
    digitalWrite(5, HIGH);
    delay(5000);
    digitalWrite(5, LOW);
    toggle_gpio = false;
  }
}

That code includes two debugging messages;该代码包括两条调试消息; if you don't see requesting toggle gpio as output then you're not actually triggering the /door1 handler.如果您没有看到requesting toggle gpio为 output 那么您实际上并没有触发/door1处理程序。

If you're not seeing that message then I'd add this handler to setup() :如果您没有看到该消息,那么我会将此处理程序添加到setup()

server.onNotFound([](AsyncWebServerRequest *request){
  Serial.print("got unhandled request for ");
  Serial.println(request->url();
  request->send(404);
});

// Start server
server.begin();

That should show you what URL the web server thought you were requesting.这应该告诉你 web 服务器认为你在请求什么 URL。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM