You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ESP32提交Web参数后WiFi关闭触发LoadProhibited重启问题

ESP32 AsyncWebServer关闭WiFi后触发LoadProhibited重启问题解决

问题现象

提交Web服务器参数后,WiFi成功关闭,但随即触发Guru Meditation Error: Core 0 panic'ed (LoadProhibited)未处理异常,导致ESP32重启并从头执行程序。

问题分析

从错误栈回溯可以明确,异常发生在AsyncTCP的异步接收任务中,核心原因是关闭WiFi的时机错误:在POST请求的回调函数里直接调用disableWifi()时,AsyncWebServer尚未完成HTTP响应的完整发送流程,TCP连接的底层资源仍在被使用。此时强制关闭WiFi会导致TCP栈尝试访问已释放的WiFi相关内存,触发非法内存访问错误。

同时代码存在几个隐性隐患:

  • 在异步请求回调中直接修改全局状态并操作硬件资源,违背异步服务器的事件处理逻辑
  • wifiResult()函数每次loop循环都重复执行pinMode(TOUCH_PIN,INPUT_PULLUP),属于冗余操作
  • 多次启动WiFi时可能重复初始化AsyncWebServer,引发资源冲突

解决方案

核心修复思路

确保HTTP响应完全发送完成后,再停止AsyncWebServer并关闭WiFi,通过延迟执行或标志位触发的方式,避免底层资源冲突。

具体代码修改

1. 调整POST回调的WiFi关闭逻辑

移除回调中直接关闭WiFi的代码,改为设置延迟关闭标志,确保响应发送完成:

// 在wifiModule.cpp中新增全局变量
bool needDisableWifi = false;
unsigned long disableWifiDelay = 0;
const unsigned long waitResponseTime = 1000; // 预留1秒确保响应发送完成

void ESPAsyncWebServer()
{
  server.on("/submit", HTTP_POST, [](AsyncWebServerRequest *request) {
    String dateTime="", timezone="";
    if (request->hasParam("time", true) && request->hasParam("timezone", true)) {
      dateTime = request->getParam("time", true)->value();
      timezone = request->getParam("timezone", true)->value();
      globalDateTime= dateTime;
      globalTimezone= timezone;
      Serial.print("Date & Time: ");
      Serial.println(globalDateTime);
      Serial.print("Timezone: ");
      Serial.println(globalTimezone);

      int year,month, day, hour, minute,second;
      parseDateTime(year,month,day, hour, minute, second);
    }
    request->send(200, "text/plain", "Submitted! Date & Time: " + dateTime + " Timezone: " + timezone);
    // 设置延迟关闭标志,不在回调中直接操作硬件
    needDisableWifi = true;
    disableWifiDelay = millis();
  });
      
  server.begin();
  Serial.println("Wi-Fi enabled and AP started.");
}

2. 在Loop中处理延迟关闭逻辑

新增专门的检查函数,在主循环中处理WiFi关闭:

// 在wifiModule.cpp中新增处理函数
void checkWifiDisable() {
  if (needDisableWifi && millis() - disableWifiDelay >= waitResponseTime) {
    server.end(); // 先停止AsyncWebServer,释放TCP资源
    disableWifi();
    wifiEnabled = false;
    needDisableWifi = false;
    Serial.println("Wi-Fi disabled after waiting for response completion.");
  }
}

// 修改main.cpp中的loop函数,新增检查调用
void loop() {
  Serial.print("Free heap memory: ");
  Serial.println(ESP.getFreeHeap());
  wifiResult();
  checkWifiDisable(); // 新增延迟关闭检查
  spa_result();
  delay(500);
}

3. 修复冗余的Pin初始化

修改wifiResult(),将Pin模式初始化改为只执行一次:

void wifiResult()
{
  static bool pinInitialized = false;
  if (!pinInitialized) {
    pinMode(TOUCH_PIN, INPUT_PULLUP);
    pinInitialized = true;
  }
  
  int buttonState = digitalRead(TOUCH_PIN);
  Serial.print("Button State: ");
  Serial.println(buttonState);
  if (buttonState != lastButtonState) {
    if(buttonState == LOW )
    {
      if(millis()-lastDebounceTime > debounceDelay){
        wifiEnabled = !wifiEnabled;
        if(wifiEnabled)
        {
          WifiStart();
          Serial.println("Wi-Fi is ON");
        }
        else{
          server.end(); // 按钮关闭时先停止服务器
          disableWifi();
          Serial.println("Wi-Fi is OFF");
        }
        lastDebounceTime=millis();
      }
    }
  }
  lastButtonState=buttonState;
}

4. 避免重复初始化服务器

修改WifiStart(),确保服务器只初始化一次:

void WifiStart()
{
  if(wifiEnabled)
  {
    WiFi.softAPdisconnect(true);
    WiFi.mode(WIFI_AP);
    if (WiFi.softAP(ssid, password)) {
      IPAddress myIP = WiFi.softAPIP();
      Serial.print("AP IP address: ");
      Serial.println(myIP);
      // 避免重复初始化服务器
      static bool serverInitialized = false;
      if (!serverInitialized) {
        ESPAsyncWebServer();
        serverInitialized = true;
      } else {
        server.begin(); // 若之前停止过,重新启动服务器
      }
    }
    else
    {
      Serial.println("Failed to start AP");
    }
  }
  else{
    server.end();
    disableWifi();
  }
}

验证效果

修改后,提交参数后服务器会先完成响应发送,等待1秒确保TCP连接资源释放后,再停止服务器并关闭WiFi,不会再触发LoadProhibited异常,同时时间设置逻辑可正常运行。

内容的提问来源于stack exchange,提问作者Charan kalidindi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 00:00:15