#include <WiFi.h>
#include <DHT.h>
// 优化编译指令
#pragma GCC optimize("Os")
#pragma GCC optimize("Ofast")
#define WOKWI_FAST_BUILD
// 引脚配置
#define DHTPIN 4 // DHT22数据线
#define MQPIN 36 // MQ135模拟输出
#define NET_LED 2 // 网络状态LED
#define BUTTON_PIN 13 // 新增按键引脚
#define DHTTYPE DHT22 // 传感器类型
DHT dht(DHTPIN, DHTTYPE);
// Wokwi配置
const char* ssid = "Wokwi-GUEST";
const char* password = "";
// 全局变量
unsigned long lastSensorRead = 0;
unsigned long lastWiFiCheck = 0;
bool wifiConnected = false;
bool alarmMuted = false; // 报警静音状态
bool manualRefresh = false; // 手动刷新标志
void setup() {
Serial.begin(115200);
// 初始化硬件
pinMode(NET_LED, OUTPUT);
pinMode(BUTTON_PIN, INPUT_PULLUP); // 按键设置为上拉输入
digitalWrite(NET_LED, LOW);
dht.begin();
// WiFi配置
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.println("\n=== 环境监测系统(按键版) ===");
Serial.println("短按按键: 立即刷新数据");
Serial.println("长按2秒: 切换报警静音");
Serial.println("----------------------");
}
void loop() {
// 1. 处理按键输入
handleButton();
// 2. WiFi状态管理(每5秒)
if (millis() - lastWiFiCheck > 5000) {
updateWiFiStatus();
lastWiFiCheck = millis();
}
// 3. 传感器读取(每2秒或手动刷新)
if (millis() - lastSensorRead > 2000 || manualRefresh) {
readAndDisplaySensors();
lastSensorRead = millis();
manualRefresh = false; // 清除手动刷新标志
}
}
// 新增按键处理函数
void handleButton() {
static unsigned long pressStart = 0;
static bool buttonActive = false;
// 检测按键按下
if (digitalRead(BUTTON_PIN) == LOW) {
if (!buttonActive) {
pressStart = millis();
buttonActive = true;
}
}
else {
if (buttonActive) {
// 短按判断(<500ms)
if (millis() - pressStart < 500) {
manualRefresh = true;
Serial.println(">> 手动刷新数据 <<");
}
buttonActive = false;
}
}
// 长按判断(>2000ms)
if (buttonActive && (millis() - pressStart > 2000)) {
alarmMuted = !alarmMuted;
Serial.print("报警静音: ");
Serial.println(alarmMuted ? "ON" : "OFF");
pressStart = millis(); // 重置计时避免重复触发
}
}
void updateWiFiStatus() {
bool currentStatus = (WiFi.status() == WL_CONNECTED);
if (currentStatus != wifiConnected) {
wifiConnected = currentStatus;
digitalWrite(NET_LED, wifiConnected ? HIGH : LOW);
Serial.print("WiFi状态: ");
Serial.println(wifiConnected ? "已连接" : "已断开");
if (wifiConnected) {
Serial.print("IP地址: ");
Serial.println(WiFi.localIP());
}
}
}
void readAndDisplaySensors() {
// 传感器读数
float temp = dht.readTemperature();
float hum = dht.readHumidity();
int air = analogRead(MQPIN);
// Wokwi仿真数据模拟
if (millis() > 30000) {
temp += random(-5, 5) / 10.0f;
hum += random(-10, 10) / 10.0f;
air += random(-50, 50);
temp = constrain(temp, 10, 40);
hum = constrain(hum, 30, 90);
air = constrain(air, 100, 1000);
}
// 数据有效性检查
if (isnan(temp) || isnan(hum)) {
Serial.println("传感器读数异常!");
return;
}
// 串口输出
Serial.printf("[%lu] 温度: %.1fC\t湿度: %.1f%%\t空气质量: %d\n",
millis()/1000, temp, hum, air);
// 报警检查(静音模式下跳过)
if (!alarmMuted) {
checkThresholds(temp, hum, air);
}
}
void checkThresholds(float temp, float hum, int air) {
const float TEMP_THRESHOLD = 30.0f;
const float HUM_THRESHOLD = 80.0f;
const int AIR_THRESHOLD = 800;
bool alert = false;
if (temp > TEMP_THRESHOLD) {
Serial.println("! 温度超过30℃");
alert = true;
}
if (hum > HUM_THRESHOLD) {
Serial.println("! 湿度过80%");
alert = true;
}
if (air > AIR_THRESHOLD) {
Serial.println("! 空气质量差");
alert = true;
}
if (alert) {
Serial.println("-------- 请处理 --------");
}
}