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

ESP32 HTTP POST响应等待及SD卡文件清空实现方法咨询

ESP32数据采集上传问题解决方案

问题1:HTTP响应等待超时误判修复

问题原因

ESP32官方HTTPClient库默认请求超时时间为1000ms(1秒),服务端响应最长可达10秒,默认超时配置下会在服务端返回结果前提前中断等待,返回负的错误码触发发送失败逻辑,但实际请求已经送达服务端并完成写入。另外现有代码存在逻辑bug:flag = true标记位设置在响应码判断之前,无论请求是否成功都会停止后续重发,容易导致数据漏发。

修复方法

  • 初始化HTTP客户端后手动设置超时时间,按服务端最长响应时间留20%冗余,设置为12000ms(12秒)即可覆盖10秒的最长响应场景
  • 响应码判断逻辑收紧,仅当返回200状态码时才认定上传成功,3xx/4xx/5xx类状态码都按失败处理
  • 错误码做区分:连接拒绝、payload发送失败类错误属于发送失败,可直接标记待重发;超时类错误建议增加简单校验逻辑,避免重复写入数据库
  • 修正flag标记位的位置,仅当上传成功、本地数据清理完成后再设置flag为true,失败时保留false状态等待下次重试
  • 所有HTTP请求处理完成后主动调用http.end()释放连接资源,避免内存泄漏

对应核心修改代码片段:

if (WiFi.status() == WL_CONNECTED && flag == false){
  HTTPClient http;
  http.begin("http://192.168.xx.xxx/xxxxxxx");
  http.setTimeout(12000); // 新增超时设置,单位为毫秒
  http.addHeader("Content-Type", "application/json");

  // 省略原有时间拼接、JSON构造、SD卡读数据逻辑
  String requestBody;
  serializeJson(doc, requestBody);

  int httpResponseCode = http.POST(requestBody);
  // 删除原位置的flag = true 赋值
  if (httpResponseCode == 200) // 原判断条件httpResponseCode > 0 改为精确匹配200状态码
  {
    String response = http.getString();
    Serial.println(httpResponseCode);
    Serial.println(response);
    // 替换原有删除文件逻辑为清空文件逻辑
    clearFile(SD, "/dataON.txt");
    clearFile(SD, "/dataOFF.txt");

    // 清空临时数组
    for (int i = 0; i < numL; i++)
    {
      timesON[i] = "0";
      timesOFF[i] = "0";
    }
    flag = true; // 上传成功、清理完成后再标记flag
  }
  else
  {
    Serial.printf("HTTP POST failed, error code: %d\n", httpResponseCode);
  }
  http.end(); // 统一释放HTTP连接资源
}

问题2:SD卡文件高效清空方案

现有方案的问题

上传成功后删除文件、下次写入时重建的逻辑存在两个明显缺陷:

  1. 删除+重建操作需要修改FAT文件系统目录项、重新分配存储块,额外增加SD卡擦写次数,长期使用会加速SD卡老化,还容易产生文件碎片
  2. 如果删除文件后设备突然掉电,下次启动时新建文件可能出现异常,稳定性差

优化方案

不需要删除文件,直接用截断模式打开文件即可将文件长度置为0,仅需1次IO操作,比删建方案效率高3~5倍,对SD卡磨损更小。封装通用清空函数如下:

void clearFile(fs::FS &fs, const char *path) {
  // FILE_WRITE模式会自动截断已有文件长度为0,文件不存在则自动创建
  File file = fs.open(path, FILE_WRITE);
  if(!file){
    Serial.printf("Failed to open file %s for clear\n", path);
    return;
  }
  file.close();
}

直接用该函数替换原有deleteFile+createFile的调用即可,原有开头的createFile()调用也可以直接替换为clearFile(),不需要单独保留创建文件逻辑。

如果后续数据量更大、需要长期不间断运行,可以进一步优化为环形文件方案:维护读写偏移指针,上传成功后只移动读指针,不需要擦除文件内容,写满后绕回文件开头覆盖已上传的旧数据,能把SD卡擦写频率降低一个数量级。

额外可靠性建议

服务端返回200时建议在响应体中带上已接收的数据条数、数据MD5校验值,ESP32端校验本地发送的数据和服务端接收的数据一致后,再清空本地SD卡文件,避免因为网络中间节点丢包、服务端部分写入导致的数据丢失。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 17:18:24