ESP32调用InfluxDB writePoint致OTA服务无法访问排查
问题根因
冲突本质是主循环阻塞导致Web服务无法及时响应:
client.writePoint(sensor)是同步阻塞网络请求,单次调用会占用WiFi栈资源数百毫秒到数秒不等,执行期间完全无法处理其他网络任务- 原代码里
server.handleClient()仅在每次loop最开始调用1次,后续紧跟着1000ms+200ms的阻塞延时、以及同步写入操作,浏览器发送的OTA页面HTTP请求根本等不到ESP32处理就会超时 - 代码重复包含了两次
WiFi.h头文件,容易引发WiFi栈资源调度异常 - InfluxDB写入频率过高(每1.2秒写一次),进一步压缩了Web服务的可用处理窗口
修复步骤
- 移除重复的
#include <WiFi.h>引用,只保留一处头文件引入 - 在setup函数里给InfluxDB客户端设置2秒写入超时,避免网络波动时写入操作无限卡死:
// 加在client.validateConnection()调用之前 client.setWriteTimeout(2000);
- 删掉loop里所有长阻塞
delay(),改用millis()实现非阻塞定时,把InfluxDB写入间隔调整到5秒以上,降低网络占用 - 在loop的所有耗时操作间隙插入
server.handleClient()调用,保证Web请求能被及时响应
修改后可运行的核心代码
// 全局定义非阻塞定时参数 unsigned long lastInfluxWrite = 0; const long INFLUX_WRITE_INTERVAL = 5000; // 每5秒写一次时序数据 void loop() { // 每次循环优先处理Web请求 server.handleClient(); unsigned long curMillis = millis(); // 非阻塞触发InfluxDB写入 if (curMillis - lastInfluxWrite >= INFLUX_WRITE_INTERVAL) { lastInfluxWrite = curMillis; // 传感器采样 float a0 = analogRead(Aout); float v_o = a0 * 4.6 / 1023; float R_S = (4.6 - v_o) * 1000 / v_o; float R_a = R_S / R_0; float PPM = pow(R_a, -2.95) * 1000; sensor.clearFields(); sensor.addField("VOC_Sensor", a0); sensor.addField("VOC_PPM", PPM); // 串口打印 Serial.print("Sensor Voltage: "); Serial.print(v_o); Serial.println(" V"); Serial.print("VOC Concentration: "); Serial.print(PPM); Serial.println(" PPM"); Serial.print("Raw signal: "); Serial.println(a0); // 写入前再处理一次Web请求,避免采样阶段遗漏请求 server.handleClient(); // 写入时序数据 if (client.writePoint(sensor)) { Serial.println("InfluxDB write successful"); } else { Serial.print("InfluxDB write failed: "); Serial.println(client.getLastErrorMessage()); } } // 短延时喂狗,不阻塞主循环 delay(10); }
改完后InfluxDB写入和OTA服务可同时正常运行,不会再出现页面加载超时的问题。如果后续要提升固件上传阶段的稳定性,可以在OTA文件写入的回调里也插入
server.handleClient()调用,避免大固件上传过程中网络连接断开。
内容的提问来源于stack exchange,提问作者Prakhar Gupta
相关产品推荐
相关产品推荐

