#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <DHT.h>
// 定义引脚连接
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
#define DHTPIN 3 // Digital pin connected to the DHT sensor
#define DHTTYPE DHT22 // DHT 22 (AM2302)
DHT dht(DHTPIN, DHTTYPE);
#define MQ2_A_PIN A0 // MQ2模拟输出引脚
#define MQ2_D_PIN 2 // MQ2数字输出引脚
#define LED_PIN 4 // LED引脚
#define BUZZER_PIN 5 // 蜂鸣器引脚
#define SWITCH_PIN 6 // 开关引脚
#define TEMP_THRESHOLD_PIN A1 // 温度阈值调节电位器
#define SMOKE_THRESHOLD_PIN A2 // 烟雾阈值调节电位器
// 全局变量
float temperature = 0;
float humidity = 0;
float smokeLevel = 0;
float tempThreshold = 30.0; // 默认温度阈值(°C)
float smokeThreshold = 300; // 默认烟雾阈值(模拟值)
bool alarmActive = false;
unsigned long alarmStartTime = 0;
float maxTemp = 0;
float maxHumidity = 0;
void setup() {
Serial.begin(9600);
// 初始化OLED显示屏
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;);
}
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("Fire Alarm System");
display.println("Initializing...");
display.display();
// 初始化传感器和外设
dht.begin();
pinMode(LED_PIN, OUTPUT);
pinMode(BUZZER_PIN, OUTPUT);
pinMode(SWITCH_PIN, INPUT_PULLUP);
pinMode(MQ2_D_PIN, INPUT);
// 初始化蜂鸣器和LED
digitalWrite(LED_PIN, LOW);
digitalWrite(BUZZER_PIN, LOW);
delay(2000); // 初始化延时
}
void loop() {
// 读取传感器数据
readSensors();
// 读取阈值设置
readThresholds();
// 检查是否需要触发报警
checkAlarm();
// 处理手动解除报警
handleSwitch();
// 更新显示
updateDisplay();
delay(1000); // 主循环延时
}
void readSensors() {
// 读取DHT22传感器数据
humidity = dht.readHumidity();
temperature = dht.readTemperature();
// 检查读取是否成功
if (isnan(humidity) || isnan(temperature)) {
Serial.println("Failed to read from DHT sensor!");
return;
}
// 更新历史最高值
if (temperature > maxTemp) maxTemp = temperature;
if (humidity > maxHumidity) maxHumidity = humidity;
// 读取MQ2传感器数据
smokeLevel = analogRead(MQ2_A_PIN);
}
void readThresholds() {
// 读取温度阈值(0-50°C)
int tempValue = analogRead(TEMP_THRESHOLD_PIN);
tempThreshold = map(tempValue, 0, 1023, 10, 60);
// 读取烟雾阈值(0-1023)
int smokeValue = analogRead(SMOKE_THRESHOLD_PIN);
smokeThreshold = map(smokeValue, 0, 1023, 100, 800);
}
void checkAlarm() {
// 检查是否超过阈值
bool tempAlarm = temperature > tempThreshold;
bool smokeAlarm = smokeLevel > smokeThreshold;
if (tempAlarm || smokeAlarm) {
if (!alarmActive) {
// 启动报警
alarmActive = true;
alarmStartTime = millis();
Serial.println("ALARM TRIGGERED!");
}
// 执行报警动作
triggerAlarm();
} else {
// 关闭报警
alarmActive = false;
digitalWrite(LED_PIN, LOW);
digitalWrite(BUZZER_PIN, LOW);
}
}
void triggerAlarm() {
// 声光报警逻辑
unsigned long currentTime = millis();
unsigned long alarmDuration = currentTime - alarmStartTime;
// 每500ms切换LED状态
if ((alarmDuration % 500) < 250) {
digitalWrite(LED_PIN, HIGH);
} else {
digitalWrite(LED_PIN, LOW);
}
// 蜂鸣器发出警笛声
if ((alarmDuration % 1000) < 500) {
// 高音
tone(BUZZER_PIN, 1000);
} else {
// 低音
tone(BUZZER_PIN, 500);
}
}
void handleSwitch() {
// 检查开关状态(低电平表示按下)
if (digitalRead(SWITCH_PIN) == LOW) {
// 延时去抖
delay(50);
if (digitalRead(SWITCH_PIN) == LOW) {
// 手动关闭报警
alarmActive = false;
digitalWrite(LED_PIN, LOW);
noTone(BUZZER_PIN);
Serial.println("Alarm manually disabled");
// 等待开关释放
while (digitalRead(SWITCH_PIN) == LOW);
}
}
}
void updateDisplay() {
display.clearDisplay();
display.setCursor(0, 0);
// 显示标题
display.setTextSize(1);
display.println("Fire Alarm System");
// 显示温度和湿度
display.setTextSize(2);
display.print("Temp: ");
display.print(temperature);
display.print(" C");
display.setCursor(0, 20);
display.print("Humi: ");
display.print(humidity);
display.println(" %");
// 显示烟雾浓度
display.setTextSize(1);
display.print("Smoke: ");
display.print(smokeLevel);
display.println(" ppm");
// 显示阈值
display.print("Temp Threshold: ");
display.print(tempThreshold);
display.println(" C");
display.print("Smoke Threshold: ");
display.print(smokeThreshold);
display.println(" ppm");
// 显示历史最高值
display.print("Max Temp: ");
display.print(maxTemp);
display.print(" C ");
display.print("Max Humi: ");
display.print(maxHumidity);
display.println(" %");
// 显示报警状态
display.setTextSize(2);
display.setCursor(0, 50);
if (alarmActive) {
display.setTextColor(SSD1306_BLACK, SSD1306_WHITE); // 反色显示
display.println("ALARM!");
display.setTextColor(SSD1306_WHITE);
} else {
display.println("Normal");
}
display.display();
}