#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <DHT.h>
// 传感器与引脚定义
#define DHT_PIN 2 // DHT22数据脚
#define DHT_TYPE DHT22 // 传感器类型
DHT dht(DHT_PIN, DHT_TYPE);
// LCD配置(I2C接口,地址0x27,16列2行)
LiquidCrystal_I2C lcd(0x27, 16, 2);
// 继电器与按钮引脚
#define RELAY_PIN 12 // 继电器控制脚
#define BTN_UP 32 // 温度增加按钮
#define BTN_DOWN 33 // 温度减少按钮
// 全局变量
int set_temp = 25; // 初始设定温度(10~40℃)
bool relay_state = false; // 继电器状态
unsigned long last_debounce = 0; // 防抖计时
const int debounce_delay = 50; // 防抖延时(ms)
// 按钮中断函数:增加温度(带防抖)
void IRAM_ATTR onBtnUp() {
if (millis() - last_debounce > debounce_delay) {
if (set_temp < 40) set_temp++;
last_debounce = millis();
}
}
// 按钮中断函数:减少温度(带防抖)
void IRAM_ATTR onBtnDown() {
if (millis() - last_debounce > debounce_delay) {
if (set_temp > 10) set_temp--;
last_debounce = millis();
}
}
void setup() {
Serial.begin(115200);
dht.begin(); // 初始化DHT22
lcd.init(); // 初始化LCD
lcd.backlight(); // 开启背光
// 配置引脚模式
pinMode(RELAY_PIN, OUTPUT);
digitalWrite(RELAY_PIN, LOW); // 初始关闭继电器
pinMode(BTN_UP, INPUT_PULLUP); // 上拉输入(按钮接GND)
pinMode(BTN_DOWN, INPUT_PULLUP);
// 附加中断(下降沿触发,因上拉输入按下为LOW)
attachInterrupt(digitalPinToInterrupt(BTN_UP), onBtnUp, FALLING);
attachInterrupt(digitalPinToInterrupt(BTN_DOWN), onBtnDown, FALLING);
}
void loop() {
// 读取当前温度(处理读取失败)
float current_temp = dht.readTemperature();
if (isnan(current_temp)) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Temp Err!");
delay(1000);
return;
}
// 控制继电器:设定温度 > 当前温度 → 加热
if (set_temp > current_temp) {
digitalWrite(RELAY_PIN, HIGH);
relay_state = true;
} else {
digitalWrite(RELAY_PIN, LOW);
relay_state = false;
}
// LCD显示:第一行当前温度,第二行设定温度+状态
lcd.setCursor(0, 0);
lcd.print("Cur: ");
lcd.print(current_temp, 1); // 保留1位小数
lcd.print(" C ");
lcd.setCursor(0, 1);
lcd.print("Set: ");
lcd.print(set_temp);
lcd.print(" C ");
// 右上角显示继电器状态
lcd.setCursor(13, 1);
lcd.print(relay_state ? "ON" : "OFF");
delay(1000); // 每秒更新一次
}