ESP32启用WiFi后模拟传感器(光敏/土壤湿度)数据异常求助
ESP32 WiFi开启后模拟传感器(D2/D4引脚)输出异常排查
问题背景
基于ESP-WROOM-32搭建传感服务,已连接DHT22、光敏电阻、土壤湿度传感器及额外温度传感器,接线确认无误。目前已实现通过POST请求上传数字传感器数据至服务器,但开启WiFi后,连接在D2、D4引脚的模拟传感器(光敏电阻、土壤湿度传感器)输出错误/固定默认值。
ESP32通过PC供电,代码占用72%存储空间。单独使用传感器或关闭WiFi时,所有传感器工作正常。
故障排查与解决建议
1. 引脚资源冲突检查
ESP32的D2(GPIO2)、D4(GPIO4)引脚存在系统复用冲突:
- GPIO2是ESP32的启动引脚(BOOT),芯片启动时会检测该引脚电平,WiFi启动后可能被系统复用或强制拉至固定电平,导致模拟采样异常。
- GPIO4部分模块会用于Flash芯片的供电控制,WiFi通信时Flash频繁读写,会干扰该引脚的模拟采样稳定性。
- 解决方案:将模拟传感器更换到无复用冲突的ADC专用引脚,比如GPIO32、GPIO33、GPIO34、GPIO35。
2. 供电稳定性优化
WiFi启动后会增加ESP32功耗,PC供电可能出现电压波动,影响模拟传感器采样:
- 用万用表检测传感器VCC引脚电压,WiFi开启后需稳定在3.3V左右。
- 解决方案:在传感器VCC与GND之间并联100nF陶瓷电容;若PC供电不足,更换为独立3.3V电源模块。
3. 代码逻辑优化
当前代码中传感器读取与WiFi通信存在资源抢占问题:
- 移除
loop()中的delay(5000),改用非阻塞式定时器逻辑,避免系统长时间阻塞。 - 调整传感器读取时机,避免在WiFi POST请求过程中同时执行ADC采样,比如将数据读取放在WiFi通信完成后。
4. ADC采样参数配置
ESP32默认ADC配置可能无法抵御WiFi电磁干扰:
- 在
setup()中添加以下代码,提升ADC采样稳定性:analogReadResolution(12); // 显式设置12位采样精度(ESP32默认值) analogSetAttenuation(ADC_11db); // 设置11dB衰减,适配0-3.3V输入范围
5. WebServer资源调度
ESPAsyncWebServer会占用大量系统资源,可能干扰ADC采样:
- 若无需HTTP服务器功能,直接移除相关代码,仅保留WiFi与HTTPClient逻辑。
- 若必须保留服务器,可将服务器任务绑定到核心1,避免与核心0的ADC采样冲突:
// 在server.begin()前添加 server.setCore(1);
原始代码
#include <WiFi.h> #include <HTTPClient.h> #include <OneWire.h> #include <DallasTemperature.h> #include <ArduinoJson.h> #include <ESPAsyncWebSrv.h> #include "DHT.h" #define DHTPIN 21 #define KY001_Signal_PIN 5 #define DHTTYPE DHT22 // 库初始化 DHT dht(DHTPIN, DHTTYPE); OneWire oneWire(KY001_Signal_PIN); DallasTemperature sensors(&oneWire); int sensorPin = 4; // 光敏电阻(异常引脚) int soilMoistPin = 2; // 土壤湿度传感器(异常引脚) const int soilMoistLevelLow = 533; // 需根据实际情况调整 const int soilMoistLevelHigh = 258; // 需根据实际情况调整 const size_t bufferSize = JSON_OBJECT_SIZE(5); // JSON字段数量定义 const char* ssid = "ssid"; const char* password = "password"; AsyncWebServer server(80); unsigned long lastTime = 5000; unsigned long timerDelay = 30000; void setup() { Serial.begin(115200); wifiSetup(); dht.begin(); sensors.begin(); pinMode(soilMoistPin, INPUT); getRequestFunc(); } void wifiSetup(){ WiFi.begin(ssid, password); Serial.println("Connecting"); while(WiFi.status() != WL_CONNECTED) { delay(300); Serial.print("."); } Serial.println(""); Serial.print("Connected to WiFi network with IP Address: "); Serial.println(WiFi.localIP()); Serial.println(WiFi.status()); Serial.println("Timer set to 5 seconds (timerDelay variable), it will take 5 seconds before publishing the first reading."); } float getMoisture(){ int soilMoist = analogRead(soilMoistPin); Serial.print("Analog Value: "); Serial.print(soilMoist); // 土壤湿度百分比计算 int percentSoilMoist = map(soilMoist, soilMoistLevelHigh, soilMoistLevelLow, 100, 0); Serial.print(" "); Serial.print(percentSoilMoist); Serial.println(" %"); return percentSoilMoist; } float getTemperature(){ float temperature; sensors.requestTemperatures(); temperature = sensors.getTempCByIndex(0); Serial.print("Temperatur: "); Serial.print(sensors.getTempCByIndex(0)); Serial.println(" °C"); return temperature; } void getDHTData(){ delay(2000); float h = dht.readHumidity(); float t = dht.readTemperature(); float f = dht.readTemperature(true); if (isnan(h) || isnan(t) || isnan(f)) { Serial.println(F("Failed to read from DHT sensor!")); return; } float hif = dht.computeHeatIndex(f, h); float hic = dht.computeHeatIndex(t, h, false); Serial.print(F("Humidity: ")); Serial.print(h); Serial.print(F("% Temperature: ")); Serial.print(t); Serial.print(F("°C ")); Serial.print(f); Serial.print(F("°F Heat index: ")); Serial.print(hic); Serial.print(F("°C ")); Serial.print(hif); Serial.println(F("°F")); } float getFotowiderstand(){ float rawValue = analogRead(sensorPin); float voltage = ((4095 - rawValue) / 4095) * 100; Serial.print("Aktuelle Helligkeit:"); Serial.print(voltage); Serial.print(" %"); Serial.print("Eigentliche Spannung:"); Serial.print(rawValue); Serial.println("mV"); Serial.println("---------------------------------------"); return voltage; } void getRequestFunc(){ server.on("/temperature", HTTP_GET, [](AsyncWebServerRequest *request) { float temperature = getTemperature(); String temperatureString = String(temperature, 2); request->send(200, "text/plain", temperatureString); postFunction(); }); server.begin(); } void postFunction(){ HTTPClient http; http.begin("https://sensor-backend-iwillnotsharethat/sensor/post"); http.addHeader("Content-Type", "application/json"); int httpResponseCode = http.POST(mapToJson()); if(httpResponseCode>0){ String response = http.getString(); Serial.println(httpResponseCode); Serial.println(response); } else { Serial.print("Error on sending POST: "); Serial.println(httpResponseCode); } http.end(); } String mapToJson(){ StaticJsonDocument<bufferSize> jsonDocument; float fotowiderstand = getFotowiderstand(); jsonDocument["temperature"] = dht.readTemperature(); jsonDocument["sensorId"] = "100"; jsonDocument["humidity"] = dht.readHumidity(); jsonDocument["light"] = fotowiderstand; jsonDocument["moisture"] = getMoisture(); String jsonString; serializeJson(jsonDocument, jsonString); Serial.println(jsonString); return jsonString; } void loop() { checkIfAllSensorsAlive(); if ((millis() - lastTime) > timerDelay) { if(WiFi.status()== WL_CONNECTED){ postFunction(); } else { Serial.println("WiFi Disconnected"); } lastTime = millis(); } delay(5000); } void checkIfAllSensorsAlive(){ getMoisture(); getDHTData(); getFotowiderstand(); getTemperature(); }
内容的提问来源于stack exchange,提问作者PaulaK_ON
相关产品推荐
相关产品推荐

