#include <Wire.h> // I2C 通信库
#include <Adafruit_GFX.h> // OLED 图形库
#include <Adafruit_SSD1306.h> // SSD1306 驱动库
#include <DHT.h> // DHT22 温湿度库
// SSD1306 OLED 参数
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// DHT22 配置
#define DHTPIN 2
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
// 模块引脚定义
const int smokePin = A0; // MQ-2 烟雾传感器
const int buzzerPin = 3; // 蜂鸣器
const int ledPin = 4; // LED 指示灯
const int stopAlarmPin = 6; // 停止报警按钮
const int setThresholdPin = 7; // 设置阈值按钮
// 报警阈值
float tempThreshold = 30.0;
float humiThreshold = 60.0;
int smokeThreshold = 300;
// 状态变量
bool isAlarmActive = false;
bool alarmManuallyDisabled = false;
bool currentButtonState = HIGH;
bool lastButtonState = HIGH;
unsigned long lastAlarmTime = 0; // 记录上次报警时间
const unsigned long ALARM_INTERVAL = 100; // 报警间隔100ms(0.1秒)
bool buzzerState = false; // 蜂鸣器当前状态
// 函数声明
String getCurrentTime();
void checkSensors();
void updateDisplay(float temp, float humi, int smoke);
void handleThresholdButton();
void handleStopAlarmButton();
void updateAlarm();
void setup() {
Serial.begin(9600);
dht.begin();
// 初始化 OLED
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 初始化失败!"));
for(;;);
}
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(1);
// 设置引脚模式
pinMode(smokePin, INPUT);
pinMode(buzzerPin, OUTPUT);
pinMode(ledPin, OUTPUT);
pinMode(stopAlarmPin, INPUT_PULLUP);
pinMode(setThresholdPin, INPUT_PULLUP);
Serial.println("环境监测系统已启动");
Serial.print("温度阈值: ");
Serial.println(tempThreshold);
Serial.print("湿度阈值: ");
Serial.println(humiThreshold);
Serial.print("烟雾阈值: ");
Serial.println(smokeThreshold);
}
void loop() {
// 读取传感器数据
float temperature = dht.readTemperature();
float humidity = dht.readHumidity();
int smokeValue = analogRead(smokePin);
// 检查传感器数据是否有效
if (isnan(temperature) || isnan(humidity)) {
Serial.println("无法从DHT传感器读取数据!");
temperature = 0;
humidity = 0;
}
// 更新显示(保持原OLED格式不变)
updateDisplay(temperature, humidity, smokeValue);
// 检查是否需要触发报警
if (!alarmManuallyDisabled) {
bool shouldAlarm = (temperature > tempThreshold ||
humidity > humiThreshold ||
smokeValue > smokeThreshold);
if (shouldAlarm != isAlarmActive) {
isAlarmActive = shouldAlarm;
lastAlarmTime = millis(); // 重置报警计时
}
}
// 处理按钮输入
handleThresholdButton();
handleStopAlarmButton();
// 更新报警状态(控制蜂鸣器脉冲)
updateAlarm();
// 短暂延时,减少CPU负载
delay(50); // 缩短延时以确保报警脉冲准确
}
void updateDisplay(float temp, float humi, int smoke) {
display.clearDisplay();
// 显示时间
display.setCursor(0, 0);
display.print("Time: ");
display.print(getCurrentTime());
// 显示温度
display.setCursor(0, 10);
display.print("Temp: ");
display.print(temp);
display.print(" C");
// 显示湿度
display.setCursor(0, 20);
display.print("Humi: ");
display.print(humi);
display.print(" %");
// 显示烟雾值
display.setCursor(0, 30);
display.print("Smoke: ");
display.print(smoke);
// 显示阈值
display.setCursor(0, 40);
display.print("Temp Th: ");
display.print(tempThreshold);
display.print(" C");
// 显示报警状态
display.setCursor(0, 50);
if (isAlarmActive) {
display.print("ALARM ACTIVE!");
} else if (alarmManuallyDisabled) {
display.print("Alarm disabled");
} else {
display.print("System OK");
}
display.display();
}
void handleThresholdButton() {
// 读取当前按钮状态
currentButtonState = digitalRead(setThresholdPin);
// 检测按钮按下(从HIGH变为LOW)
if (currentButtonState == LOW && lastButtonState == HIGH) {
// 按钮被按下,增加温度阈值
tempThreshold += 1.0;
// 检查是否超过最大值,如果超过则重置为最小值
if (tempThreshold > 50.0) {
tempThreshold = 30.0;
}
// 打印新的阈值
Serial.print("新温度阈值: ");
Serial.println(tempThreshold);
// 短暂延时以避免按键抖动
delay(200);
}
// 更新上一次按钮状态
lastButtonState = currentButtonState;
}
void handleStopAlarmButton() {
static bool lastStopButtonState = HIGH;
bool currentStopButtonState = digitalRead(stopAlarmPin);
// 检测按钮按下
if (currentStopButtonState == LOW && lastStopButtonState == HIGH) {
// 消抖处理
delay(50);
if (digitalRead(stopAlarmPin) == LOW) {
// 关闭报警状态
if (isAlarmActive) {
isAlarmActive = false;
alarmManuallyDisabled = true;
digitalWrite(buzzerPin, LOW);
digitalWrite(ledPin, LOW);
Serial.println("报警已手动关闭");
} else {
// 重置手动禁用状态
alarmManuallyDisabled = false;
Serial.println("报警检测已恢复");
}
}
}
// 更新上一次按钮状态
lastStopButtonState = currentStopButtonState;
}
void updateAlarm() {
if (isAlarmActive) {
// 每100ms切换蜂鸣器状态
unsigned long currentTime = millis();
if (currentTime - lastAlarmTime >= ALARM_INTERVAL) {
lastAlarmTime = currentTime;
buzzerState = !buzzerState;
digitalWrite(buzzerPin, buzzerState);
digitalWrite(ledPin, buzzerState); // LED同步闪烁
}
} else {
// 非报警状态时关闭蜂鸣器和LED
digitalWrite(buzzerPin, LOW);
digitalWrite(ledPin, LOW);
}
}
String getCurrentTime() {
// 这里应该添加获取当前时间的代码
// 例如:使用RTC模块或系统时间
// 模拟时间(实际应用中替换为真实时间)
unsigned long seconds = millis() / 1000;
int hours = (seconds / 3600) % 24;
int minutes = (seconds / 60) % 60;
int secs = seconds % 60;
String timeStr = "";
if (hours < 10) timeStr += "0";
timeStr += String(hours) + ":";
if (minutes < 10) timeStr += "0";
timeStr += String(minutes) + ":";
if (secs < 10) timeStr += "0";
timeStr += String(secs);
return timeStr;
}