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

DHT22传感器读取失败:集成菜单代码后Serial输出NaN

箱体温度监测项目DHT22读取NaN问题排查

我是嵌入式开发领域的新手,正在开发一个箱体温度监测项目。尝试使用DHT22传感器读取温度时,单独运行简单测试代码可正常获取数据,但将传感器读取逻辑集成到带菜单功能的项目代码后,Serial Monitor始终输出NaN,无法读取温度。

菜单代码(问题代码)

#include "PinChangeInterrupt.h"
#include "DHT.h"
#include "Countimer.h"
#define DHTPIN 5
#define DHTTYPE DHT22

DHT dht(DHTPIN, DHTTYPE);
Countimer timer;
// 补全未定义的变量
int buah = 0;
float set_temperature = 0.0;
int buahPilih = 0;

void setup() {
  Serial.begin(9600);
  dht.begin();
}

void loop() {
  encoder_value();
  int b = checkButton();
  if (b == 1) clickEvent();
  if (b == 2) doubleClickEvent(); 
  if (b == 3) holdEvent(); 
}

void encoder_value() {
  
}

int checkButton() {
  return 0; // 临时返回0避免编译报错
}

void clickEvent() {
 
}

void doubleClickEvent() { 
  if (buah == 1){
    set_temperature = 60;
    timer.setCounter(0,0,10, timer.COUNT_DOWN, onComplete);
    timer.setInterval(refreshClock, 1000);
    refreshClock();
    // 移除阻塞while循环,改为在主loop中处理
  }
  else if (buah == 2){
    
  }
}

void holdEvent() {

}

void refreshClock(){
  Serial.println(timer.getCurrentTime());
}

// 修改为非阻塞式读取
unsigned long lastReadTime = 0;
const long readInterval = 10000;
void PID(){
  unsigned long currentTime = millis();
  if (currentTime - lastReadTime >= readInterval) {
    lastReadTime = currentTime;
    float temperature_read = dht.readTemperature();
    Serial.print(temperature_read);
  }
  timer.run(); // 处理定时器逻辑
}

void onComplete(){

}

可正常运行的简单测试代码

#include "DHT.h"
#include "LiquidCrystal_I2C.h"
#define DHTPIN 5
#define DHTTYPE DHT22
#include "RBDdimmer.h"

DHT dht (DHTPIN, DHTTYPE);
LiquidCrystal_I2C lcd(0x27, 16, 2);
int fan = 7;

const int zeroCrossPin = 2;
const int adcPin = 3;
dimmerLamp adc(adcPin);
int power;
float set_temperature = 31.6;
float temperature_read = 0.0;
float suhu;
float PID_error = 0;
float previous_error = 0;
float elapsedTime, Time, timePrev;
float PID_value = 0;

int kp = 90;
int ki = 30;
int kd = 80;

int PID_p = 0;
int PID_i = 0;
int PID_d = 0;
float last_kp = 0;
float last_ki = 0;
float last_kd = 0;
int PID_values_fix = 0;

void setup() {
  Serial.begin(9600);
  dht.begin();
  lcd.init();
  lcd.backlight();
  lcd.clear();
  pinMode(fan, OUTPUT);
}

void loop() {
  float t = dht.readTemperature();
  float h = dht.readHumidity();
  Serial.print("Suhu : ");
  Serial.print(t);
  Serial.println(" C");
  Serial.print(" ");
  Serial.print("Kelembaban : ");
  Serial.print(h);
  Serial.println(" %");
  Serial.print(" ");
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Suhu: ");
  lcd.print(t);
  lcd.setCursor(0,1);
  lcd.print("kelem: ");
  lcd.print(h);
  
  PID_error = set_temperature - t;
  Serial.print("Error terbaca: ");
  Serial.println(PID_error);
  Serial.print(" ");
  PID_p = kp * PID_error;
  PID_i = PID_i +(ki * PID_error);
  timePrev = Time;
  Time = millis();
  elapsedTime = (Time - timePrev) / 1000;
  PID_d = kd * ((PID_error - previous_error) / elapsedTime);
  PID_value = PID_p + PID_i + PID_d;
  Serial.print("PID_value adalah ");
  Serial.println(PID_value);
  Serial.print(" ");
  previous_error = PID_error;
  
  power = PID_value;
  if (power<0){
    power = 0;
  }
  else if (power > 70){
    power = 70;
  }
  
  adc.setPower(power);
  Serial.print("lampValue -> ");
  Serial.print(adc.getPower());
  Serial.println("%");
  Serial.print(" ");
  
  if (t > 31){
    digitalWrite(fan, LOW);
  }
  delay(500);
}

问题原因分析

  1. 阻塞式delay破坏传感器时序:菜单代码中PID()函数的delay(10000)会导致程序阻塞10秒,DHT22传感器的通信对时序精度要求高,长时间阻塞会导致传感器信号读取超时,返回NaN。
  2. while循环阻塞主程序:doubleClickEvent()中的while (!timer.isCounterCompleted())会完全阻塞主loop,导致编码器、按键等其他功能无法运行,同时反复调用timer.start()会打乱定时器逻辑,进一步影响传感器读取。
  3. 未定义变量导致运行异常:代码中buah、set_temperature等变量未声明,编译时会产生警告或报错,可能导致运行时逻辑混乱。

修复方案

  1. 替换阻塞式delay为非阻塞定时:用millis()实现定时读取传感器,避免长时间阻塞程序,保证传感器通信时序正常。
  2. 移除阻塞式while循环:将定时器逻辑移到主loop中处理,采用事件驱动方式,避免阻塞主程序的其他功能。
  3. 补全所有未定义变量:确保所有使用的变量都提前声明并初始化,避免编译和运行时错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 02:06:03