简体   繁体   中英

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. I have executed the code to toggle that pin HIGH and LOW outside of the callback and it works.

  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. Doing so blocks the event handler task and may cause the TCP connection or HTTP protocol to fail. The async web documentation calls this out in the "Important things to remember" section.

Instead, set a flag that indicates that the work needs to be done and then do the work in 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.

If you're not seeing that message then I'd add this handler to 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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