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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 15:28:09