#include <DHT.h>
#include <LiquidCrystal_I2C.h>
// 引脚与报警阈值定义
#define DHTPIN 4
#define DHTTYPE DHT22
#define LED_PIN 7
const float ALARM_TEMP = 32.0;
// I2C LCD 1602对象
LiquidCrystal_I2C lcd(0x27, 16, 2);
DHT dht(DHTPIN, DHTTYPE);
// 标准热指数计算公式(截图内置函数)
float calculateHeatIndex(float tempC, float humidity)
{
float tempF = tempC * 1.8 + 32;
float hiF = -42.379 +
2.04901523 * tempF +
10.14331237 * humidity -
0.22475541 * tempF * humidity -
6.83783e-3 * tempF * tempF -
5.481717e-2 * humidity * humidity +
1.22874e-3 * tempF * tempF * humidity +
8.5282e-4 * tempF * humidity * humidity -
1.99e-6 * tempF * tempF * humidity * humidity;
return (hiF - 32) / 1.8;
}
void setup()
{
Serial.begin(9600);
delay(200);
dht.begin();
lcd.init();
lcd.backlight();
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, LOW);
// 开机串口打印信息
Serial.println("------ 温湿度监测系统 ------");
Serial.println("恩施职业技术学院");
Serial.println("温湿度系统启动成功!");
Serial.println("24110306 陈傲琪");
Serial.println("----------------------------");
}
void loop()
{
float humidity = dht.readHumidity();
float tempC = dht.readTemperature();
// DHT数据读取失败校验
if (isnan(humidity) || isnan(tempC))
{
Serial.println(F("无法读取DHT22数据 请检查接线"));
digitalWrite(LED_PIN, LOW);
lcd.clear();
lcd.print("DHT22 ERROR");
delay(2000);
return;
}
// 计算华氏温度、热指数
float tempF = tempC * 1.8 + 32;
float heatIndexC = calculateHeatIndex(tempC, humidity);
float heatIndexF = heatIndexC * 1.8 + 32;
// 串口打印(和仿真底部输出完全一致)
Serial.print(F("湿度: "));
Serial.print(humidity, 1);
Serial.print(F(" %RH | 温度: "));
Serial.print(tempC, 1);
Serial.print(F(" ℃ / "));
Serial.print(tempF, 1);
Serial.print(F(" °F | 热指数: "));
Serial.print(heatIndexC, 1);
Serial.print(F(" ℃ / "));
Serial.print(heatIndexF, 1);
Serial.print(F(" °F | 报警: "));
// 高温报警逻辑
if (heatIndexC > ALARM_TEMP)
{
Serial.println(F("ALARM"));
digitalWrite(LED_PIN, HIGH);
}
else
{
Serial.println(F("OK"));
digitalWrite(LED_PIN, LOW);
}
// LCD屏幕显示(和仿真图文字、格式完全对应)
lcd.clear();
// 第一行 T:xx.x℃ H:xx.x%
lcd.setCursor(0, 0);
lcd.print("T:");
lcd.print(tempC, 1);
lcd.print((char)223);
lcd.print("C H:");
lcd.print(humidity, 1);
lcd.print("%");
// 第二行 HI:xx.x℃ ALARM!
lcd.setCursor(0, 1);
lcd.print("HI:");
lcd.print(heatIndexC, 1);
lcd.print((char)223);
lcd.print("C ");
if (heatIndexC > ALARM_TEMP)
{
lcd.print("ALARM!");
}
else
{
lcd.print("OK");
}
delay(2000);
}