c厨房燃气泄露警报装置代码
/*
* 厨房干烧+燃气泄漏
*/
//=====================【可修改配置区】=====================
// WiFi配置(家里的2.4G WiFi,不支持5G WiFi)
const char* WIFI_SSID = "你家的WiFi名称";
const char* WIFI_PASS = "你家的WiFi密码";
// 巴法云配置(填你复制的私钥UID,主题不用改)
const char* UID = "你的巴法云私钥UID";
const char* TOPIC = "kitchen001";
// 安全阈值配置(可根据实际情况微调)
const float DRY_BURN_TEMP = 280.0; // 干烧温度阈值,单位℃,超过触发告警
const int GAS_THRESHOLD = 300; // 燃气浓度阈值,干净空气约100,超过触发告警
const int NOBODY_ALERT_TIME = 300; // 无人警戒超时时间,单位秒,默认5分钟
const int SENSOR_REFRESH_RATE = 1000; // 传感器刷新间隔,单位毫秒,默认1秒
// 舵机角度配置(装完后根据你的阀门/旋钮微调,0-180°)
const int VALVE_OPEN_ANGLE = 90; // 燃气球阀打开角度
const int VALVE_CLOSE_ANGLE = 0; // 燃气球阀关闭角度
const int STOVE_OPEN_ANGLE = 90; // 燃气灶旋钮打开角度
const int STOVE_CLOSE_ANGLE = 0; // 燃气灶旋钮关闭角度
// 引脚定义(照着接线表接了就不用改)
const int GAS_PIN = A0;
const int HUMAN_PIN = 2;
const int SERVO_VALVE_PIN = 3;
const int SERVO_STOVE_PIN = 5;
const int ALARM_PIN = 6;
const int RESET_PIN = 7;
const int ESP_TX_PIN = 10;
const int ESP_RX_PIN = 11;
//===========================================================================
// 库引入
#include <Wire.h>
#include <Adafruit_MLX90614.h>
#include <Servo.h>
#include <RTClib.h>
#include <SoftwareSerial.h>
// 器件初始化
Adafruit_MLX90614 mlx = Adafruit_MLX90614();
Servo servoValve; // 燃气球阀舵机
Servo servoStove; // 燃气灶旋钮舵机
RTC_DS3231 rtc;
SoftwareSerial espSerial(ESP_RX_PIN, ESP_TX_PIN); // 软串口接WiFi模块
// 全局状态变量(不用改)
bool isAlert = false; // 告警状态标志
bool isNobodyMode = false; // 无人警戒模式标志
unsigned long nobodyStartTime = 0; // 无人状态开始计时
unsigned long lastRefreshTime = 0; // 传感器上次刷新时间
int gasValue = 0; // 燃气浓度实时值
float objTemp = 0.0; // 锅底温度实时值
bool hasHuman = false; // 人体检测状态
DateTime now; // 实时时间
void setup() {
// 串口初始化(调试用)
Serial.begin(9600);
espSerial.begin(9600);
// 引脚模式设置
pinMode(HUMAN_PIN, INPUT);
pinMode(ALARM_PIN, OUTPUT);
pinMode(RESET_PIN, INPUT_PULLUP); // 内部上拉,按键按下为低电平
digitalWrite(ALARM_PIN, LOW); // 初始化关闭报警
// 舵机初始化,默认打开状态
servoValve.attach(SERVO_VALVE_PIN);
servoStove.attach(SERVO_STOVE_PIN);
servoValve.write(VALVE_OPEN_ANGLE);
servoStove.write(STOVE_OPEN_ANGLE);
delay(500);
// 红外测温模块初始化
if (!mlx.begin()) {
Serial.println("红外测温模块初始化失败!请检查接线");
while (1); // 卡住,方便排查问题
}
Serial.println("红外测温模块初始化成功");
// 实时时钟初始化
if (!rtc.begin()) {
Serial.println("时钟模块初始化失败!请检查接线");
while (1);
}
if (rtc.lostPower()) {
Serial.println("时钟断电,正在同步编译时间");
rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // 自动同步电脑时间
}
Serial.println("时钟模块初始化成功");
// WiFi模块初始化
Serial.println("正在连接WiFi...");
espSerial.println("AT+CWMODE=1"); // 设置WiFi为STA模式
delay(1000);
String wifiCmd = "AT+CWJAP=\"" + String(WIFI_SSID) + "\",\"" + String(WIFI_PASS) + "\"";
espSerial.println(wifiCmd);
delay(5000);
// MQ-9传感器预热提示(必须预热,否则读数不准)
Serial.println("=====================");
Serial.println("燃气传感器预热中,请勿操作...");
for(int i=180; i>0; i--){
Serial.print("预热剩余时间:");
Serial.print(i);
Serial.println(" 秒");
delay(1000);
}
Serial.println("预热完成!系统正式启动");
Serial.println("=====================");
}
void loop() {
// 手动复位检测(按下按键立即复位系统)
if(digitalRead(RESET_PIN) == LOW){
systemReset();
delay(500); // 防抖
}
// 已经触发告警,直接锁定状态,不执行检测,直到复位
if(isAlert){
digitalWrite(ALARM_PIN, HIGH); // 持续声光报警
return;
}
// 按设定间隔刷新传感器数据,避免频繁读取
if(millis() - lastRefreshTime >= SENSOR_REFRESH_RATE){
lastRefreshTime = millis();
now = rtc.now(); // 获取当前时间
// 1. 读取所有传感器数据
gasValue = analogRead(GAS_PIN);
objTemp = mlx.readObjectTempC();
hasHuman = digitalRead(HUMAN_PIN) == HIGH;
// 2. 串口打印调试信息(打开串口监视器可看所有实时数据)
Serial.println("---------------------");
Serial.print("当前时间:");
Serial.print(now.year());
Serial.print("-");
Serial.print(now.month());
Serial.print("-");
Serial.print(now.day());
Serial.print(" ");
Serial.print(now.hour());
Serial.print(":");
Serial.print(now.minute());
Serial.print(":");
Serial.println(now.second());
Serial.print("锅底温度:");
Serial.print(objTemp);
Serial.println(" ℃");
Serial.print("燃气浓度:");
Serial.println(gasValue);
Serial.print("厨房有人:");
Serial.println(hasHuman ? "是" : "否");
Serial.print("当前模式:");
Serial.println(isNobodyMode ? "无人警戒模式" : "有人正常模式");
Serial.println("---------------------");
// 3. 人体存在状态判断,更新无人计时
if(hasHuman){
nobodyStartTime = millis(); // 有人,重置计时
isNobodyMode = false; // 退出警戒模式
}else{
// 无人,计算超时时间
unsigned long nobodyDuration = (millis() - nobodyStartTime) / 1000;
Serial.print("无人持续时长:");
Serial.print(nobodyDuration);
Serial.print(" / ");
Serial.println(NOBODY_ALERT_TIME);
// 无人超时,进入警戒模式
if(nobodyDuration >= NOBODY_ALERT_TIME){
isNobodyMode = true;
}
}
// 4. 危险条件判断
bool isDryBurn = objTemp >= DRY_BURN_TEMP;
bool isGasLeak = gasValue >= GAS_THRESHOLD;
// 5. 告警逻辑处理(核心防误触:有人只报警不关阀,无人警戒模式直接关阀+推送)
if(isDryBurn || isGasLeak){
// 拼接告警消息
String alertMsg = "";
if(isDryBurn) alertMsg += "【干烧告警】锅底温度超过" + String(DRY_BURN_TEMP) + "℃!";
if(isGasLeak) alertMsg += "【燃气泄漏告警】燃气浓度超标!";
alertMsg += "触发时间:" + String(now.year()) + "年" + String(now.month()) + "月" + String(now.day()) + "日 " + String(now.hour()) + ":" + String(now.minute());
Serial.println("!!!触发告警:" + alertMsg);
if(isNobodyMode){
// 无人警戒模式:执行关阀+关火+报警+微信推送
isAlert = true;
triggerProtection(alertMsg);
}else{
// 有人模式:仅声光报警,不关闭阀门,避免爆炒误触
digitalWrite(ALARM_PIN, HIGH);
delay(2000);
digitalWrite(ALARM_PIN, LOW);
}
}else{
// 无危险,关闭报警
digitalWrite(ALARM_PIN, LOW);
}
}
}
//===================== 功能函数=====================
// 触发保护动作:关阀+关火+微信推送
void triggerProtection(String msg){
// 1. 关闭燃气球阀
servoValve.write(VALVE_CLOSE_ANGLE);
delay(500);
// 2. 关闭燃气灶旋钮
servoStove.write(STOVE_CLOSE_ANGLE);
delay(500);
// 3. 开启持续声光报警
digitalWrite(ALARM_PIN, HIGH);
// 4. 推送微信告警消息
sendWechatMsg(msg);
Serial.println("保护动作已执行:已关阀+关火+推送告警消息");
}
// 系统复位函数:恢复正常状态
void systemReset(){
Serial.println("系统正在复位...");
// 关闭报警
digitalWrite(ALARM_PIN, LOW);
// 舵机恢复打开状态
servoValve.write(VALVE_OPEN_ANGLE);
servoStove.write(STOVE_OPEN_ANGLE);
delay(500);
// 重置所有状态标志
isAlert = false;
isNobodyMode = false;
nobodyStartTime = millis();
Serial.println("复位完成!恢复正常监测");
}
// 微信消息推送函数(对接巴法云,不用改)
void sendWechatMsg(String msg){
// 拼接巴法云MQTT推送指令
String cmd = "AT+CIPSTART=\"TCP\",\"bemfa.com\",8344\r\n";
espSerial.println(cmd);
delay(1000);
String mqttMsg = "cmd=1&uid=" + String(UID) + "&topic=" + String(TOPIC) + "&msg=" + msg + "\r\n";
String sendCmd = "AT+CIPSEND=" + String(mqttMsg.length()) + "\r\n";
espSerial.println(sendCmd);
delay(500);
espSerial.print(mqttMsg);
delay(1000);
espSerial.println("AT+CIPCLOSE");
delay(500);
Serial.println("微信推送已发送");
}
相似问题