首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何让我这个代码在运行过程中更稳定可靠?

如何让我这个代码在运行过程中更稳定可靠?

提问于 2026-05-03 22:01:08
回答 0关注 0查看 2

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("微信推送已发送");

}

回答

和开发者交流更多问题细节吧,去 写回答
相关文章

相似问题

相关问答用户
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档