【STM32项目开源】STM32单片机厨房安全监测系统

目录

一、设计背景和意义

1.1设计背景:

1.2设计意义:

二、实物展示

三、硬件功能介绍

[2.1 硬件清单:](#2.1 硬件清单:)

[2.2 功能介绍:](#2.2 功能介绍:)

四、软件设计流程图

五、硬件PCB展示

六、软件主函序展示

七、单片机实物资料

[资料获取 查看主页介绍:兆龙电子单片机设计](#资料获取 查看主页介绍:兆龙电子单片机设计)


一、设计背景和意义

1.1设计背景:

在物联网与智慧家居快速发展的当下,传统厨房安全监测方式存在诸多局限。多数家庭仍依赖人工巡检或单一功能报警器(如独立燃气报警器、烟雾报警器),缺乏多风险协同监测与智能化联动控制能力,既无法实时整合燃气泄漏、烟雾浓度、温度异常等多维度安全数据并自动响应,也难以满足厨房复杂场景下的全方位安全防护需求。随着人们对家居安全防护精度、应急响应速度要求的提升,分散式、被动式的安全监测模式已不适用。

现有厨房安全监测方案常存在功能割裂问题,远程预警、多参数联动控制、应急处置等功能未能有效整合,且部分集成化方案成本较高难以普及。基于此,本设计以 STM32F103C8T6 单片机为核心,融合燃气传感器、烟雾传感器、温度传感器与语音预警技术,构建低成本、高集成度的智能厨房安全监测系统,以解决传统厨房安全监测中智能化不足、防护维度单一、应急响应滞后的问题。

1.2设计意义:

本设计通过整合多参数监测与语音预警、智能联动控制技术,具有多重实用价值。从安全防护体验看,提供远程实时监测、本地声光预警、语音险情播报、异常自动断气(联动电磁阀)等多元防护方式,覆盖燃气泄漏、火灾隐患、高温异常等核心安全场景,尤其多参数协同分析与快速应急响应功能,大幅提升了厨房安全防护的主动性与可靠性。

从节能与安全保障角度,借助精准传感器监测实现 "按需预警、及时处置",避免因人工巡检遗漏或单一报警器误报导致的安全风险,同时减少无效能耗(如联动关闭异常运行设备),符合智慧家居的安全、节能双重理念。从技术层面,探索了 STM32 单片机与多类型传感器、语音模块的协同工作机制,为低成本智能厨房安全监测系统开发提供了可参考的集成方案,推动厨房安全监测技术从 "被动报警" 向 "主动防护" 升级,具有较好的实践应用与家庭普及价值。

**二、**实物展示

下方为实物演示视频

【开源】基于STM32单片机智能厨房安全检测系统

下方为实物展示图片

三、硬件功能介绍

2.1 硬件清单:

  • STM32F103C8T6
  • OLED显示
  • 温度传感器
  • 继电器控制电路
  • 水泵
  • 风扇
  • 火焰传感器
  • 门磁
  • 舵机
  • 烟雾传感器
  • ESP8266 WIFI模块

2.2 功能介绍:

(1)STM32单片机进行数据处理
(2)OLED液晶显示当前烟雾浓度,温度、是否发生明火
(3)MQ-2传感器检测烟雾传感器
(4)DS18B20检测当前环境温度
(5)火焰传感器检测当前厨房是否发生明火
(6)按键一:设置,按键二:加,按键三:减
(7)按键分别设置温度上限气体浓度上限
(8)温度超标,液晶闪烁提示,开启风扇进行降温
(9)气体超标液晶闪烁提示,开启风扇进行排气,降低浓度舵机旋转强制关闭燃气通道!
(10)发生明火,液晶出现火焰标志开启水泵模拟灭火舵机旋转强制关闭燃气通道!蜂鸣器 声光报警提醒
(11)通过ESP8266无线WIFI模块把数据传输到手机端进行显示
(12)手机连接WIFI后显示当前温度、烟雾浓度
(13)如果发生明火手机端会出现火焰标志
(14)通过手机端可以任意进行修改当前温度上限,浓度上限

四、软件设计流程图

五、硬件PCB展示

六、软件主函序展示

复制代码
#include "sys.h"
#include "delay.h"
#include "adc.h"
#include "gpio.h"
#include "OLED_I2C.h"
#include "ds18b20.h"
#include "timer.h"
#include "usart1.h"
#include "esp8266.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

extern const unsigned char BMP[];

char  display[16];             //显示缓存区
short temperature=0;           //温度
u8    setTempValue  = 40;     //温度上限
u8    setSmokeValue = 60;     //烟雾上限
u8    alarmFlag = 0x00;      //蜂鸣器报警标志
u16   smoke=0;               //烟雾
u8    setn=0;                //记录设置按键按下的次数

u8 PWM=5;                   //PWM调节值,用于控制舵机

bool shanshuo=0;
bool shuaxin=0;
bool sendFlag = 1;
bool flameFlag=0;

void displayInitInterface(void)    //显示初始页面
{
		u8 i;

	  for(i = 0;i < 6;i ++)OLED_ShowCN(i*16+16,0,i+0,0);    //显示中文: 厨房安全检测
	  for(i = 0;i < 2;i ++)OLED_ShowCN(i*16,4,i+6,0);       //显示中文: 温度
	  for(i = 0;i < 2;i ++)OLED_ShowCN(i*16,6,i+8,0);      //显示中文: 烟雾
	  OLED_ShowChar(32,4,':',2,0);
OLED_ShowChar(32,6,':',2,0);
}

void Get_Temperature(void)       //获取温度
{
		temperature=ReadTemperature();

	  if(temperature>=setTempValue)
		 {
if(!(alarmFlag&0x01))
				{
						alarmFlag|=0x01;
					  shanshuo = 0;
				}
		 }
		 else
		 {
				alarmFlag&=0xFE;
		 }

	  if(temperature>=setTempValue && shanshuo)
		{
OLED_ShowStr(40, 4,"      ", 2,0);

		}
else
		{
sprintf(display," %d",temperature);
OLED_ShowStr(40, 4, (u8*)display, 2,0);//显示温度
			  OLED_ShowCentigrade(68, 4);   //显示摄氏度
		}
}

void Get_Smoke(void)    //获取烟雾浓度
{
		u16 test_adc=0;

	  /* 获取烟雾浓度 */
	  test_adc = Get_Adc_Average(ADC_Channel_9,10);//读取通道9的10次AD平均值
		smoke = test_adc*99/4096;//转换成0-99百分比

	  if(smoke>=setSmokeValue)
		 {
if(!(alarmFlag&0x02))
				{
						alarmFlag|=0x02;
					  shanshuo = 0;
				}
		 }
		 else
		 {
				alarmFlag&=0xFD;
		 }

	  if(smoke>=setSmokeValue && shanshuo)
		{
OLED_ShowStr(40, 6,"      ", 2,0);
		}
else
		{
sprintf(display," %02d %%",smoke);
OLED_ShowStr(40, 6, (u8*)display, 2,0);//显示温度
		}
}

void displaySetValue(void) //显示设置值
{
	  if(setn==1)
		{
OLED_ShowChar(56,4,setTempValue%100/10+'0',2,0);//显示
OLED_ShowChar(64,4,setTempValue%10+'0',2,0);//显示
		}
if(setn==2)
		{
			  OLED_ShowChar(56,4,setSmokeValue%100/10+'0',2,0);//显示
OLED_ShowChar(64,4,setSmokeValue%10+'0',2,0);//显示
			  OLED_ShowChar(72,4,'%',2,0);  
		}	
}

void keyscan(void)   //按键扫描
{
	 u8 i;

	 if(KEY1 == 0) //设置键
	 {
delay_ms(20);
		  if(KEY1 == 0)
			{
while(KEY1 == 0);
				  setn ++;
				  if(setn == 1)
					{
OLED_CLS();//清屏
for(i = 0;i < 4;i ++)OLED_ShowCN(i*16+32,0,i+10,0);//显示中文:设置温度
						  OLED_ShowCentigrade(75, 4);   //显示摄氏度
					}
if(setn == 2)
					{
for(i = 0;i < 4;i ++)OLED_ShowCN(i*16+32,0,i+14,0);//显示中文:设置烟雾
						  OLED_ShowChar(80,4,' ',2,0);  
					}
if(setn >= 3)
					{
							setn = 0;
						  OLED_CLS();//清屏
						  displayInitInterface();
					}
displaySetValue();
			}
	 }
	 if(KEY2 == 0) //加键
	 {
delay_ms(80);
		  if(KEY2 == 0)
			{
if(setTempValue  < 99 && setn==1)setTempValue++;
				  if(setSmokeValue < 99 && setn==2)setSmokeValue++;
displaySetValue();
			}
	 }
	 if(KEY3 == 0) //减键
	 {
delay_ms(80);
		  if(KEY3 == 0)
			{
				  if(setTempValue  > 0 && setn==1)setTempValue--;
				  if(setSmokeValue > 0 && setn==2)setSmokeValue--;
displaySetValue();
			}
	 }
}

void UsartSendReceiveData(void)
{
unsigned char *dataPtr = NULL;
	  char *str1=0,i;
	  int  setValue=0;
	  char setvalue[3]={0};
	  char SEND_BUF[30];

	  dataPtr = ESP8266_GetIPD(0);   //接收数据
	  if(dataPtr != NULL)
		{
			  if(strstr((char *)dataPtr,"temp:")!=NULL)
				{
					  BEEP = 1;
delay_ms(80);
					  BEEP = 0;

						str1 = strstr((char *)dataPtr,"temp:");

					  while(*str1 < '0' || *str1 > '9')        //判断是不是0到9有效数字
						{
								str1 = str1 + 1;
delay_ms(10);
						}
						i = 0;
while(*str1 >= '0' && *str1 <= '9')        //判断是不是0到9有效数字
						{
								setvalue[i] = *str1;
								i ++; str1 ++;
if(*str1 == ',')break;            //换行符,直接退出while循环
delay_ms(10);
						}
						setvalue[i] = '\0';            //加上结尾符
						setValue = atoi(setvalue);
if(setValue>=0 && setValue<=99)
						{
								setTempValue = setValue;    //设置的温度值
							  displaySetValue();
						}
				}	

			  if(strstr((char *)dataPtr,"smoke:")!=NULL)
				{
						str1 = strstr((char *)dataPtr,"smoke:");

					  while(*str1 < '0' || *str1 > '9')        //判断是不是0到9有效数字
						{
								str1 = str1 + 1;
delay_ms(10);
						}
						i = 0;
while(*str1 >= '0' && *str1 <= '9')        //判断是不是0到9有效数字
						{
								setvalue[i] = *str1;
								i ++; str1 ++;
if(*str1 == '\r')break;            //换行符,直接退出while循环
delay_ms(10);
						}
						setvalue[i] = '\0';            //加上结尾符
						setValue = atoi(setvalue);
if(setValue>=0 && setValue<=99)
						{
								setSmokeValue = setValue;    //设置的烟雾值
							  displaySetValue();
						}
				}	

			  ESP8266_Clear();									//清空缓存
		}
if(sendFlag==1)    //1秒钟上传一次数据
		{
			  sendFlag = 0;		

memset(SEND_BUF,0,sizeof(SEND_BUF));   			//清空缓冲区
sprintf(SEND_BUF,"$temp:%d#,$smoke:%d#",temperature,smoke);

			  if(flameFlag)
				{
strcat(SEND_BUF,"flame");
				}

			  ESP8266_SendData((u8 *)SEND_BUF, strlen(SEND_BUF));
			  ESP8266_Clear();
		}
}

int main(void)
{
delay_init();	           //延时函数初始化	 
    NVIC_Configuration();	   //中断优先级配置
	  I2C_Configuration();     //IIC初始化
	  delay_ms(200); 
	  OLED_Init();             //OLED液晶初始化
	  OLED_CLS();              //清屏
	  OLED_ShowStr(0, 2, "   loading...   ", 2,0);//显示加载中
    ESP8266_Init();       //ESP8266初始化
	  Adc_Init();           //adc初始化
KEY_GPIO_Init();        //按键引脚初始化
	  MOTOR_GPIO_Init();     //舵机初始化
	  DS18B20_GPIO_Init();    //温度初始化
	  DS18B20_Init();         //初始化显示
	  OLED_CLS();              //清屏
	  displayInitInterface(); //显示初始界面
	  TIM3_Init(99,71);   //定时器初始化,定时100us
//Tout = ((arr+1)*(psc+1))/Tclk ; 
//Tclk:定时器输入频率(单位MHZ)
//Tout:定时器溢出时间(单位us)
while(1)
		{ 
			   keyscan();  //按键扫描
			   if(setn == 0)
				 {
					   if(shuaxin == 1)   //大概300ms刷新一次数据
						 {
								 Get_Temperature();   //获取温度
								 Get_Smoke();         //获取烟雾

							   shuaxin = 0;
						 }
						 if(FLAME == 0)          //检测到火焰
						 {
delay_ms(10);
if(FLAME == 0)
								{
if(flameFlag == 0)
										{
OLED_DrawBMP(88,4,120,8,(unsigned char *)BMP);  //显示火焰图片
										}
										flameFlag = 1;
										RELAY = 1;  //检测到有火,开启水泵
								}
						 }
						 else
						 {
if(flameFlag == 1)
								{
OLED_ShowStr(88, 4, "    ", 2,0);
OLED_ShowStr(88, 6, "    ", 2,0);
								}
								flameFlag = 0;
								RELAY = 0;  //关闭水泵
						 }
						 if(temperature>=setTempValue || smoke>=setSmokeValue || flameFlag)BEEP=1;else BEEP=0;  //检测到温度烟雾超标火焰蜂鸣器报警
						 if(temperature>=setTempValue || smoke>=setSmokeValue)FAN=1;else FAN=0;      //烟雾温度超标都开启风扇
						 if(smoke>=setSmokeValue || flameFlag)PWM=15;else PWM=5;                    //烟雾超标或者是检测到火焰,舵机动作,模拟关闭阀门
			   }
				 UsartSendReceiveData();
			   delay_ms(10);
		}
}

void TIM3_IRQHandler(void)//定时器3中断服务程序,用于记录时间
{ 
	  static u16 timeCount1 = 0;
	  static u16 timeCount2 = 0;
	  static u16 timeCount3 = 0;

if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源 
		{ 
TIM_ClearITPendingBit(TIM3, TIM_IT_Update); //清除中断标志位  

				timeCount1 ++;
if(timeCount1<=PWM)MOTOR=1; else MOTOR=0;
if(timeCount1>=200)   //20ms一周期
				{
						timeCount1 = 0;
				}
				timeCount2++;
if(timeCount2 >= 3000) //300ms
				{
						timeCount2 = 0;
					  shanshuo = !shanshuo;
					  shuaxin = 1;
				}
				timeCount3++;
if(timeCount3 >= 10000) //1000ms
				{
						timeCount3 = 0;
					  sendFlag = 1;
				}
	  }
}

七、单片机实物资料

资料获取 查看主页介绍:兆龙电子单片机设计

相关推荐
白鲸开源3 小时前
(二)3.1.9 生产“稳”担当:Apache DolphinScheduler Worker 服务源码全方位解析
java·大数据·开源
谁刺我心4 小时前
STM32环境配置keil5【保姆级】
stm32·keil5
pursue.dreams5 小时前
阿里云开源DeepResearch:轻量化AI推理框架技术解析与实践指南
阿里云·开源·deepresearch
anlpsonline5 小时前
AI赋能 破局重生 嬗变图强 | 安贝斯受邀参加2025第三届智能物联网与安全科技应用大会暨第七届智能化&信息化年度峰会
人工智能·物联网·安全
说私域5 小时前
基于定制开发开源AI智能名片S2B2C商城小程序的社群团购线上平台搭建研究
人工智能·小程序·开源
李白你好6 小时前
Auto_CVE - 自动化漏洞挖掘系统
运维·自动化
ajassi20007 小时前
开源 java android app 开发(十四)自定义绘图控件--波形图
android·java·开源
华普微HOPERF7 小时前
Sub-GHz射频芯片,如何降低IoT终端功耗,提升传输性能?
物联网
柱子jason7 小时前
使用IOT-Tree消息流MQTT模块节点实现监测数据推送功能
物联网·mqtt·边缘计算·iot-tree·数据推送