#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <DHT.h>
#include <Wire.h>
// --- 引脚定义 ---
#define DHTPIN PA5
#define DHTTYPE DHT22
#define MQ2_PIN PA0
#define BUZZER PB0 // 蜂鸣器正极连 PB0 (高电平响)
#define LED_PIN PB1 // LED 正极连 PB1 (高电平亮)
// --- 报警阈值设定 ---
const float TEMP_MAX = 45.0;
const float HUMI_MIN = 40.0;
const int GAS_MAX = 2500;
Adafruit_SSD1306 display(128, 64, &Wire, -1);
DHT dht(DHTPIN, DHTTYPE);
unsigned long lastUpdate = 0;
unsigned long lastToggle = 0;
bool isAlarm = false;
bool ledState = false;
void setup() {
pinMode(BUZZER, OUTPUT);
pinMode(LED_PIN, OUTPUT);
analogReadResolution(12); // STM32 ADC 12位精度
dht.begin();
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
// 开机初始化显示
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(1);
display.setCursor(10, 25);
display.println("Initializing System...");
display.display();
delay(1500);
}
void loop() {
// 每2秒采样一次数据并刷新屏幕
if (millis() - lastUpdate >= 2000) {
float t = dht.readTemperature();
float h = dht.readHumidity();
int gas = analogRead(MQ2_PIN);
if (!isnan(t) && !isnan(h)) {
// 核心判定逻辑
if (t > TEMP_MAX || h < HUMI_MIN || gas > GAS_MAX) {
isAlarm = true;
} else {
isAlarm = false;
}
// --- OLED 界面显示 (严格对齐实物格式) ---
display.clearDisplay();
display.setTextSize(1); // 保持文字大小适中
// 第一行:温度 T: xx.xx C (使用2位小数显示)
display.setCursor(0, 5);
display.print("T: ");
display.print(t, 2);
display.print(" C");
// 第二行:湿度 H: xx.xx %
display.setCursor(0, 25);
display.print("H: ");
display.print(h, 2);
display.print(" %");
// 第三行:烟雾 SMOKE: xxxx
display.setCursor(0, 45);
display.print("SMOKE: ");
display.print(gas);
display.display();
}
lastUpdate = millis();
}
// --- 报警执行模块 (物理声光逻辑) ---
if (isAlarm) {
digitalWrite(BUZZER, HIGH); // 蜂鸣器开启
if (millis() - lastToggle >= 300) { // LED 300ms 频率闪烁
ledState = !ledState;
digitalWrite(LED_PIN, ledState ? HIGH : LOW);
lastToggle = millis();
}
} else {
// 恢复安全状态
digitalWrite(BUZZER, LOW);
digitalWrite(LED_PIN, LOW);
}
}