【问题标题】:Watchdog timer errors for loops for webserver on ESP32ESP32 上网络服务器循环的看门狗定时器错误
【发布时间】:2021-05-03 16:16:17
【问题描述】:

我正在将 ESP32 CAM 模块用于线跟随机器人。而且,我正在尝试创建一个带有 3 个提交按钮的网络服务器。但是现在,我只是观察串口上的输入并且只使用一个提交栏。这些按钮指定电机的 PWM 值和一些常数。这是我的代码:

#include "Arduino.h"
#include "WiFi.h"
#include "AsyncTCP.h"
#include "ESPAsyncWebServer.h"


AsyncWebServer server(80);

// Internet ID and Password
const char* ssid = "TURKSAT-KABLONET-BC75-2.4G";
const char* password = "d942d3db";

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

// HTML web page to handle 3 input fields (input1, input2, input3)
const char index_html[] PROGMEM = R"rawliteral( // Webserver design part
<!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"> // Submit bar 1
  </form><br>
  <form action="/get">
    input2: <input type="text" name="input2">
    <input type="submit" value="Submit"> // Submit bar 2
  </form><br>
  <form action="/get">
    input3: <input type="text" name="input3">
    <input type="submit" value="Submit"> // Submit bar 3
  </form>
</body></html>)rawliteral";

void notFound(AsyncWebServerRequest *request) {
  request->send(404, "text/plain", "Not found");
}
String inputMessage;
void Setup_to_Loop(String inputMessage); // Prototype of function

void Setup_to_Loop(String inputMessage){ // Function to observe the variable
  while(1){
    Serial.print(inputMessage); // Observe submit bar on serial port of Arduino
    delay(200);
  }
}

void setup() {
  Serial.begin(115200);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  if (WiFi.waitForConnectResult() != WL_CONNECTED) {
    Serial.println("WiFi Failed!");
    return;
  }
  Serial.println();
  Serial.print("IP Address: ");
  Serial.println(WiFi.localIP());

  // Send web page with input fields to client
  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/html", index_html);
  });
// Send a GET request to <ESP_IP>/get?input1=<inputMessage>
  server.on("/get", HTTP_GET, [] (AsyncWebServerRequest *request) {
    String inputMessage;
    String inputParam;
    // GET input1 value on <ESP_IP>/get?input1=<inputMessage>
    if (request->hasParam(PARAM_INPUT_1)) { // Check for which bar is filled ( bar 1 )
      inputMessage = request->getParam(PARAM_INPUT_1)->value();
      inputParam = PARAM_INPUT_1;
    }
    // GET input2 value on <ESP_IP>/get?input2=<inputMessage>
    else if (request->hasParam(PARAM_INPUT_2)) { // Check for which bar is filled ( bar 2 )
      inputMessage = request->getParam(PARAM_INPUT_2)->value();
      inputParam = PARAM_INPUT_2;
    }
    // GET input3 value on <ESP_IP>/get?input3=<inputMessage>
    else if (request->hasParam(PARAM_INPUT_3)) { // Check for which bar is filled ( bar 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>");  // Send the values that were written on submit bars
    Setup_to_Loop(inputMessage);  // Call of function
  });
  server.onNotFound(notFound);
  server.begin();
}
void loop() {
}

收到的错误是:

(20281) task_wdt: Task watchdog got triggered. The following tasks did not reset the watchdog in time:
E (20281) task_wdt:  - async_tcp (CPU 0/1)
E (20281) task_wdt: Tasks currently running:
E (20281) task_wdt: CPU 0: IDLE0
E (20281) task_wdt: CPU 1: loopTask
E (20281) task_wdt: Aborting.
abort() was called at PC 0x400e5def on core 0

Backtrace: 0x4008efe0:0x3ffbe160 0x4008f211:0x3ffbe180 0x400e5def:0x3ffbe1a0 0x40081a15:0x3ffbe1c0 0x40147e4f:0x3ffbc170 0x400e1c53:0x3ffbc190 0x4008ce7d:0x3ffbc1b0 0x4008af7d:0x3ffbc1d0

Rebooting...

【问题讨论】:

  • 我不建议混合使用 C 和 C++,尤其是在嵌入式系统上。 C++ 语言允许函数重载,这使得与 C 语言的链接更加困难。此外,C++ 具有异常处理,这使得与 C 的混合变得困难。我建议选择一种语言并更新您的语言标签。
  • 你在Setup_to_Loop(String inputMessage)中通过无限循环阻止线程的执行
  • @ThomasMatthews 这是一个 Arduino 项目; Arduino 使用 C++。 OP 没有混合语言,他们只是错误地标记了问题。

标签: c++ webserver esp32 watchdog


【解决方案1】:

您的函数Setup_to_Loop() 调用delay()。它是从 "/get" 请求的处理程序中调用的。

ESPAsyncWebServer 文档 explicitly states 表明你不能这样做:

You can not use yield or delay or any function that uses them inside the callbacks

我不太确定你想用这个函数做什么以及为什么它使用无限循环,但你需要重写它。它应该及时返回,而不是调用delay()

【讨论】:

  • 我的目标是只从 webserver 获取一次值。之后,函数将开始一个无限循环以跟随线路并将此值设置为电机的 pwm 值。我计划编写此代码,因为无需使用编程器对设备进行编程。用户可以通过在网络服务器上编写来轻松更改变量。有没有办法在接受''inputMessage''后关闭服务器?还是您建议我停止看门狗计时器?你还有什么推荐的?
  • 在处理程序中设置一个标志,在loop() 中检查它并完成您的工作,包括关闭服务器或您需要做的任何事情。
  • 当我删除延迟时,程序运行在 11500 左右(3-4 秒),然后它再次带来错误。有没有办法将 inputMessage 从 void setup() 转移到 void loop ?
  • 如果您只是删除delay() 调用,那么您将处于无限循环中,当然看门狗定时器会触发。这就是它的用途。
  • 将消息存储在变量中,设置标志,检查loop()中的标志,然后输出消息。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多