#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <DHT.h>
// 定义引脚
#define DHTPIN 2 // DHT传感器数据引脚
#define DHTTYPE DHT11 // DHT11温湿度传感器
#define MQ2PIN A0 // MQ-2传感器模拟输入引脚
#define BUZZERPIN 3 // 蜂鸣器控制引脚
#define LEDPIN 4 // LED控制引脚
#define BUTTON_PIN1 5 // 报警关闭按钮
#define BUTTON_PIN2 6 // 阈值设置按钮
#define BUTTON_PIN3 7 // 阈值增加按钮
#define BUTTON_PIN4 8 // 阈值减少按钮
// OLED显示屏定义
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// 传感器对象
DHT dht(DHTPIN, DHTTYPE);
// 全局变量
float temperature = 0;
float humidity = 0;
int gasValue = 0;
int gasThreshold = 500; // 烟雾浓度阈值,可调整
int tempThreshold = 40; // 温度阈值,单位℃,可调整
bool alarmOn = false;
unsigned long previousMillis = 0;
unsigned long previousMillisBlink = 0;
const long interval = 2000; // 传感器读取间隔(毫秒)
const long blinkInterval = 250; // LED闪烁间隔(毫秒),加快闪烁频率
bool ledState = LOW;
bool settingMode = false; // 设置模式标志
int settingIndex = 0; // 0:温度阈值 1:气体阈值
int buttonState1, buttonState2, buttonState3, buttonState4;
int lastButtonState1 = HIGH, lastButtonState2 = HIGH, lastButtonState3 = HIGH, lastButtonState4 = HIGH;
unsigned long lastDebounceTime1 = 0, lastDebounceTime2 = 0, lastDebounceTime3 = 0, lastDebounceTime4 = 0;
unsigned long debounceDelay = 50; // 消抖延迟
// 实时时钟模拟
int hour = 12, minute = 0, second = 0;
unsigned long previousMillisTime = 0;
const long intervalTime = 1000; // 1秒更新一次时间
void setup() {
Serial.begin(9600);
// 初始化传感器
dht.begin();
// 初始化OLED
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306显示屏初始化失败"));
for(;;);
}
display.clearDisplay();
// 显示初始化信息
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("System Initializing...");
display.display();
// 初始化引脚模式
pinMode(BUZZERPIN, OUTPUT);
pinMode(LEDPIN, OUTPUT);
pinMode(BUTTON_PIN1, INPUT_PULLUP);
pinMode(BUTTON_PIN2, INPUT_PULLUP);
pinMode(BUTTON_PIN3, INPUT_PULLUP);
pinMode(BUTTON_PIN4, INPUT_PULLUP);
// 初始状态:蜂鸣器和LED关闭
digitalWrite(BUZZERPIN, LOW);
digitalWrite(LEDPIN, HIGH); // 测试LED是否正常工作
delay(1000);
digitalWrite(LEDPIN, LOW);
delay(2000);
}
void loop() {
// 更新实时时钟
updateTime();
// 读取按钮状态
readButtons();
// 读取传感器数据
if (millis() - previousMillis >= interval) {
previousMillis = millis();
readSensors();
checkAlarm();
}
// 控制LED闪烁 - 修改为持续闪烁,不受settingMode限制
if (alarmOn) {
if (millis() - previousMillisBlink >= blinkInterval) {
previousMillisBlink = millis();
ledState = !ledState;
digitalWrite(LEDPIN, ledState);
}
} else {
digitalWrite(LEDPIN, LOW);
digitalWrite(BUZZERPIN, LOW);
}
// 显示信息
displayInfo();
}
// 读取传感器数据
void readSensors() {
// 读取温湿度
humidity = dht.readHumidity();
temperature = dht.readTemperature();
// 读取MQ-2烟雾传感器数据
gasValue = analogRead(MQ2PIN);
// 检查是否读取失败
if (isnan(humidity) || isnan(temperature)) {
Serial.println("Failed to read DHT sensor data!");
}
}
// 检查是否触发报警
void checkAlarm() {
if (temperature >= tempThreshold || gasValue >= gasThreshold) {
alarmOn = true;
digitalWrite(BUZZERPIN, HIGH); // 打开蜂鸣器
} else {
alarmOn = false;
digitalWrite(BUZZERPIN, LOW); // 关闭蜂鸣器
}
}
// 显示信息到OLED屏幕 - 英语显示
void displayInfo() {
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
// 显示时间
display.print("Time: ");
display.print(hour < 10 ? "0" : "");
display.print(hour);
display.print(":");
display.print(minute < 10 ? "0" : "");
display.print(minute);
display.print(":");
display.print(second < 10 ? "0" : "");
display.println(second);
// 显示温湿度
display.print("Temp: ");
display.print(temperature);
display.print(" C (Threshold: ");
display.print(tempThreshold);
display.println(")");
display.print("Humidity: ");
display.print(humidity);
display.println(" %");
// 显示气体浓度
display.print("Gas: ");
display.print(gasValue);
display.print(" (Threshold: ");
display.print(gasThreshold);
display.println(")");
// 显示报警状态
display.print("Alarm: ");
display.println(alarmOn ? "ON" : "OFF");
// 显示设置模式状态
if (settingMode) {
display.print("Setting: ");
display.println(settingIndex == 0 ? "Temperature Threshold" : "Gas Threshold");
}
display.display();
}
// 更新实时时钟
void updateTime() {
if (millis() - previousMillisTime >= intervalTime) {
previousMillisTime = millis();
second++;
if (second >= 60) {
second = 0;
minute++;
if (minute >= 60) {
minute = 0;
hour++;
if (hour >= 24) {
hour = 0;
}
}
}
}
}
// 读取按钮状态并处理
void readButtons() {
// 读取按钮1(报警关闭)
int reading1 = digitalRead(BUTTON_PIN1);
if (reading1 != lastButtonState1) {
lastDebounceTime1 = millis();
}
if ((millis() - lastDebounceTime1) > debounceDelay) {
if (reading1 != buttonState1) {
buttonState1 = reading1;
if (buttonState1 == LOW) { // 按钮被按下
if (alarmOn) {
alarmOn = false;
digitalWrite(BUZZERPIN, LOW);
digitalWrite(LEDPIN, LOW);
}
}
}
}
lastButtonState1 = reading1;
// 读取按钮2(设置模式切换)
int reading2 = digitalRead(BUTTON_PIN2);
if (reading2 != lastButtonState2) {
lastDebounceTime2 = millis();
}
if ((millis() - lastDebounceTime2) > debounceDelay) {
if (reading2 != buttonState2) {
buttonState2 = reading2;
if (buttonState2 == LOW) { // 按钮被按下
settingMode = !settingMode;
if (!settingMode) { // 退出设置模式时检查报警
checkAlarm();
} else {
alarmOn = false; // 设置模式下关闭报警
digitalWrite(BUZZERPIN, LOW);
digitalWrite(LEDPIN, LOW);
}
}
}
}
lastButtonState2 = reading2;
// 读取按钮3(阈值增加)
if (settingMode) {
int reading3 = digitalRead(BUTTON_PIN3);
if (reading3 != lastButtonState3) {
lastDebounceTime3 = millis();
}
if ((millis() - lastDebounceTime3) > debounceDelay) {
if (reading3 != buttonState3) {
buttonState3 = reading3;
if (buttonState3 == LOW) { // 按钮被按下
if (settingIndex == 0) { // 调整温度阈值
tempThreshold++;
} else { // 调整气体阈值
gasThreshold++;
}
}
}
}
lastButtonState3 = reading3;
// 读取按钮4(阈值减少)
int reading4 = digitalRead(BUTTON_PIN4);
if (reading4 != lastButtonState4) {
lastDebounceTime4 = millis();
}
if ((millis() - lastDebounceTime4) > debounceDelay) {
if (reading4 != buttonState4) {
buttonState4 = reading4;
if (buttonState4 == LOW) { // 按钮被按下
if (settingIndex == 0 && tempThreshold > 0) { // 调整温度阈值
tempThreshold--;
} else if (settingIndex == 1 && gasThreshold > 0) { // 调整气体阈值
gasThreshold--;
}
}
}
}
lastButtonState4 = reading4;
// 长按按钮2切换设置项
static unsigned long pressStartTime2 = 0;
static bool isLongPress2 = false;
if (digitalRead(BUTTON_PIN2) == LOW) {
if (!isLongPress2) {
pressStartTime2 = millis();
isLongPress2 = true;
} else if (millis() - pressStartTime2 > 1000) { // 长按1秒
settingIndex = (settingIndex + 1) % 2;
isLongPress2 = false;
delay(200); // 防止连续切换
}
} else {
isLongPress2 = false;
}
}
}