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卡文件高效清空方案
现有方案的问题
上传成功后删除文件、下次写入时重建的逻辑存在两个明显缺陷:
- 删除+重建操作需要修改FAT文件系统目录项、重新分配存储块,额外增加SD卡擦写次数,长期使用会加速SD卡老化,还容易产生文件碎片
- 如果删除文件后设备突然掉电,下次启动时新建文件可能出现异常,稳定性差
优化方案
不需要删除文件,直接用截断模式打开文件即可将文件长度置为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
相关产品推荐
相关产品推荐

