当前位置: 首页 > ops >正文

STM32项目分享:智能厨房安全系统(机智云)

目录

一、前言

二、项目简介

1.功能详解

2.主要器件

三、原理图设计

四、PCB硬件设计

PCB图 

五、程序设计 

六、实验效果 

七、资料内容

项目分享


一、前言

项目成品图片:

哔哩哔哩视频链接:

STM32智能厨房安全系统(机智云)

(资料分享见文末) 

二、项目简介

1.功能详解

基于STM32的智能厨房安全系统(机智云)

功能如下:

  1. STM32F103C8T6单片机作为主控芯片
  2. 检测功能:检测环境温湿度、烟雾浓度、一氧化碳、火焰信号和人体信号
  3. 显示功能:OLED显示环境参数
  4. 手动控制:通过手机APP控制水泵、风扇、LED灯和阀门(舵机模拟)的开关
  5. 自动模式:系统检测到有人开启LED,温度高于阈值开启风扇,烟雾和一氧化碳超过阈值开启风扇并关闭阀门,发生火灾时关闭阀门、开启水泵
  6. 模式切换:可以在APP上切换模式
  7. 阈值调节:按键可调节阈值
  8. 机智云APP:接入机智云APP查看数据与控制下发

2.主要器件

  • STM32F103C8T6单片机
  • OLED 屏幕
  • DHT11温湿度传感器
  • MQ2烟雾传感器
  • MQ7一氧化碳传感器
  • 火焰传感器
  • 光电红外传感器
  • ESP8266模块(WIFI)
  • 继电器
  • 有源蜂鸣器
  • 水泵
  • 风扇模块
  • 舵机

三、原理图设计

四、PCB硬件设计

PCB图 

五、程序设计 

#include "stm32f10x.h"                  // Device header
#include "iwdg.h"
#include "adcx.h"
#include "oled.h"
#include "dht11.h"
#include "led.h"
#include "key.h"
#include "tim2.h"   
#include "tim3.h"   
#include "usart3.h"   
#include "usart.h"
#include "sensormodules.h"
#include "gizwits_product.h"
#include "flash.h"
#include "hc_sr501.h"
#include "servo.h"
#include "pwm.h"#define KEY_1	1
#define KEY_2	2
#define KEY_3	3
#define KEY_4	4#define FLASH_START_ADDR	0x0801f000	//写入的起始地址SystemState	systemState;			//声明系统状态结构体变量
SensorModules sensorData;	//声明传感器数据结构体变量
SensorThresholdValue Sensorthreshold;	//声明传感器阈值结构体变量uint8_t menu = 1;	//显示菜单变量
uint8_t OLED_Clear_Flag;	//阈值设置界面的清屏标志位
uint8_t mode = 0;	//系统模式uint8_t displayPageNum;	//主页面显示页面uint8_t valveLockFlag;	//阀门自锁标志位enum 
{display_page1 = 1,display_page2,settingsPage}MenuPages;/*** @brief  显示菜单1的固定内容* @param  无* @retval 无*/
void OLED_Menu1(void)
{//显示“温度:  C”OLED_ShowChinese(1, 1, 0);OLED_ShowChinese(1, 2, 1);OLED_ShowChar(1, 5, ':');OLED_ShowChar(1, 8, 'C');//显示“湿度:   %”OLED_ShowChinese(1, 5, 2);OLED_ShowChinese(1, 6, 3);OLED_ShowChar(1, 13, ':');	OLED_ShowChar(1, 16, '%');	//显示“烟雾浓度: ”OLED_ShowChinese(2, 1, 6);OLED_ShowChinese(2, 2, 7);OLED_ShowChinese(2, 3, 32);OLED_ShowChinese(2, 4, 33);OLED_ShowChar(2, 9, ':');OLED_ShowString(2, 14, "ppm");//显示“一氧化碳: ”OLED_ShowChinese(3, 1, 42);OLED_ShowChinese(3, 2, 43);OLED_ShowChinese(3, 3, 44);OLED_ShowChinese(3, 4, 45);OLED_ShowChar(3, 9, ':');OLED_ShowString(3, 14, "ppm");//显示“系统模式:”OLED_ShowChinese(4, 1, 24);OLED_ShowChinese(4, 2, 25);OLED_ShowChinese(4, 3, 26);OLED_ShowChinese(4, 4, 27);	OLED_ShowChar(4, 9, ':');
}/*** @brief  显示菜单2的固定内容* @param  无* @retval 无*/
void OLED_Menu2(void)
{//显示“火焰信号:”OLED_ShowChinese(1, 1, 8);OLED_ShowChinese(1, 2, 9);OLED_ShowChinese(1, 3, 10);OLED_ShowChinese(1, 4, 11);	OLED_ShowChar(1, 9, ':');//显示“人体信号:%”OLED_ShowChinese(2, 1, 12);OLED_ShowChinese(2, 2, 13);OLED_ShowChinese(2, 3, 14);OLED_ShowChinese(2, 4, 15);	OLED_ShowChar(2, 9, ':');}/*** @brief  显示菜单1的传感器数据* @param  无* @retval 无*/
void SensorDataDisplay1(void)
{//显示温度数据OLED_ShowNum(1, 6, sensorData.temp, 2);//显示湿度数据OLED_ShowNum(1, 14, sensorData.humi, 2);//显示烟雾浓度数据OLED_ShowNum(2, 10, sensorData.smog, 4);//显示甲烷浓度数据OLED_ShowNum(3, 10, sensorData.methane, 4);//显示系统状态数据if (!mode){OLED_ShowChinese(4, 6, 30);OLED_ShowChinese(4, 7, 31);		}else{OLED_ShowChinese(4, 6, 28);OLED_ShowChinese(4, 7, 29);			}
}/*** @brief  显示菜单2的传感器数据* @param  无* @retval 无*/
void SensorDataDisplay2(void)
{if (!sensorData.flame){OLED_ShowChinese(1, 6, 36);OLED_ShowChinese(1, 7, 37);	}else{OLED_ShowChinese(1, 6, 34);OLED_ShowChinese(1, 7, 35);		}if (!sensorData.people){OLED_ShowChinese(2, 6, 40);OLED_ShowChinese(2, 7, 41);		}else{OLED_ShowChinese(2, 6, 38);OLED_ShowChinese(2, 7, 39);		}	
}/*** @brief  显示阈值设置界面1的固定内容* @param  无* @retval 无*/
void OLED_settingsPage1(void)
{//显示“温度阈值:”OLED_ShowChinese(1, 2, 0);OLED_ShowChinese(1, 3, 1);OLED_ShowChinese(1, 4, 18);OLED_ShowChinese(1, 5, 19);	OLED_ShowChar(1, 11, ':');//显示“火焰阈值:”OLED_ShowChinese(2, 2, 8);OLED_ShowChinese(2, 3, 9);OLED_ShowChinese(2, 4, 18);OLED_ShowChinese(2, 5, 19);	OLED_ShowChar(2, 11, ':');//显示“烟雾阈值:”OLED_ShowChinese(3, 2, 6);OLED_ShowChinese(3, 3, 7);OLED_ShowChinese(3, 4, 18);OLED_ShowChinese(3, 5, 19);	OLED_ShowChar(3, 11, ':');//显示“一氧阈值:”OLED_ShowChinese(4, 2, 42);OLED_ShowChinese(4, 3, 43);OLED_ShowChinese(4, 4, 18);OLED_ShowChinese(4, 5, 19);	OLED_ShowChar(4, 11, ':');
}/*** @brief  显示阈值界面1的传感器数据* @param  无* @retval 无*/
void settingsThresholdDisplay1(void)
{//显示温度阈值数据OLED_ShowNum(1, 13, Sensorthreshold.tempValue, 2);//显示火焰阈值数据OLED_ShowNum(2, 13, Sensorthreshold.flameValue, 2);//显示烟雾阈值数据OLED_ShowNum(3, 13, Sensorthreshold.smogValue, 3);//显示甲烷阈值数据OLED_ShowNum(4, 13, Sensorthreshold.methaneValue, 3);
}/*** @brief  显示阈值界面的选择符号* @param  num 为显示的位置* @retval 无*/
void OLED_Option(uint8_t num)
{switch(num){case 1:	OLED_ShowChar(1,1,'>');OLED_ShowChar(2,1,' ');OLED_ShowChar(3,1,' ');OLED_ShowChar(4,1,' ');break;case 2:	OLED_ShowChar(1,1,' ');OLED_ShowChar(2,1,'>');OLED_ShowChar(3,1,' ');OLED_ShowChar(4,1,' ');break;case 3:	OLED_ShowChar(1,1,' ');OLED_ShowChar(2,1,' ');OLED_ShowChar(3,1,'>');OLED_ShowChar(4,1,' ');break;case 4:	OLED_ShowChar(1,1,' ');OLED_ShowChar(2,1,' ');OLED_ShowChar(3,1,' ');OLED_ShowChar(4,1,'>');break;default: break;}
}/*** @brief  记录阈值界面下按KEY1的次数* @param  无* @retval 返回次数*/
uint8_t SetSelection(void)
{static uint8_t count = 1;if(KeyNum == KEY_1){KeyNum = 0;count++;if (count > 4){count = 1;}}return count;
}/*** @brief  对阈值界面的传感器阈值进行修改* @param  num 为当前用户需要更改的传感器阈值位置* @retval 无*/
void ThresholdModification(uint8_t num)
{switch (num){case 1:if (KeyNum == 3){KeyNum = 0;Sensorthreshold.tempValue++;if (Sensorthreshold.tempValue > 99){Sensorthreshold.tempValue = 0;}}else if (KeyNum == 4){KeyNum = 0;Sensorthreshold.tempValue--;if (Sensorthreshold.tempValue > 99){Sensorthreshold.tempValue = 99;}				}break;case 2:if (KeyNum == 3){KeyNum = 0;Sensorthreshold.flameValue++;if (Sensorthreshold.flameValue > 99){Sensorthreshold.flameValue = 0;}}else if (KeyNum == 4){KeyNum = 0;Sensorthreshold.flameValue--;if (Sensorthreshold.flameValue > 99){Sensorthreshold.flameValue = 99;}				}			break;case 3:if (KeyNum == 3){KeyNum = 0;Sensorthreshold.smogValue++;if (Sensorthreshold.smogValue > 500){Sensorthreshold.smogValue = 0;}}else if (KeyNum == 4){KeyNum = 0;Sensorthreshold.smogValue--;if (Sensorthreshold.smogValue > 500){Sensorthreshold.smogValue = 500;}				}break;case 4:if (KeyNum == 3){KeyNum = 0;Sensorthreshold.methaneValue++;if (Sensorthreshold.methaneValue > 500){Sensorthreshold.methaneValue = 0;}}else if (KeyNum == 4){KeyNum = 0;Sensorthreshold.methaneValue--;if (Sensorthreshold.methaneValue > 500){Sensorthreshold.methaneValue = 500;}				}break;default: break;		}
}/*** @brief  系统自动模式下的运行* @param  无* @retval 无*/
void AutomaticMode()
{if (mode){/*当系统检测到有人时会开启LED灯,没人时自动关闭*/if (sensorData.people){currentDataPoint.valueLED = 1;LED_ON();}else{currentDataPoint.valueLED = 0;LED_OFF();}/*系统检测到温度高于阈值时会自动开启风扇*/if (sensorData.temp > Sensorthreshold.tempValue){currentDataPoint.valuefan = 1;Relay_ON(1);Buzzer_ON();}/*系统检测到火焰时,会自动开启水泵进行灭火并且关闭阀门*/if (sensorData.flame){Relay_ON(0);currentDataPoint.valuevalve = 1;currentDataPoint.valuewaterPump = 1;systemState.flameAlarm = 1;Buzzer_ON();}else{systemState.flameAlarm = 0;currentDataPoint.valuewaterPump = 0;currentDataPoint.valuevalve = 0;}/*系统检测到烟雾浓度高于阈值,会自动开启风扇并且关闭阀门*/if (sensorData.smog > Sensorthreshold.smogValue){currentDataPoint.valuefan = 1;systemState.smogAlarm = 1;Relay_ON(1);			currentDataPoint.valuevalve = 1;Buzzer_ON();}else{systemState.smogAlarm = 0;}/*系统检测到甲烷浓度高于阈值,会自动开启风扇并且关闭阀门*/if (sensorData.methane > Sensorthreshold.methaneValue){currentDataPoint.valuefan = 1;systemState.methaneAlarm = 1;Relay_ON(1);currentDataPoint.valuevalve = 1;	Buzzer_ON();}else{systemState.methaneAlarm = 0;}/*控制舵机运行*/if ((sensorData.flame || sensorData.smog > Sensorthreshold.smogValue || sensorData.methane > Sensorthreshold.methaneValue)&& valveLockFlag == 0){valveLockFlag = 1;Servo_SetAngle(90);}else if (valveLockFlag && !sensorData.flame && (sensorData.smog ) < Sensorthreshold.smogValue && (sensorData.methane ) < Sensorthreshold.methaneValue){valveLockFlag = 0;Relay_OFF(1);Relay_OFF(0);currentDataPoint.valuevalve = 0;Servo_SetAngle(0);}			/*控制风扇停止*/if (sensorData.temp < Sensorthreshold.tempValue && (sensorData.smog ) < Sensorthreshold.smogValue && (sensorData.methane ) < Sensorthreshold.methaneValue){currentDataPoint.valuefan = 0;Relay_OFF(1);}/*控制蜂鸣器停止*/if (sensorData.temp < Sensorthreshold.tempValue && !sensorData.flame && (sensorData.smog ) < Sensorthreshold.smogValue && (sensorData.methane ) < Sensorthreshold.methaneValue){Buzzer_OFF();}}
}/*** @brief  传感器数据扫描* @param  无* @retval 无*/
void SensorScan(void)
{DHT11_Read_Data(&sensorData.humi, &sensorData.temp);HC_SR501_Input(&sensorData.people);Get_Average_MQ2_PPM(&sensorData.smog);Get_Average_MQ4_PPM(&sensorData.methane);if (Get_Average_Flame_Percent() < Sensorthreshold.flameValue){sensorData.flame = 0;}else{sensorData.flame = 1;}
}int main(void)
{ADCX_Init();Timer2_Init(9,14398);Uart2_Init(9600);Uart1_Init(115200);Uart3_Init();IWDG_Init();	//初始化看门狗PWM_Init();OLED_Init();DHT11_Init();LED_Init();Buzzer_Init();Relay_Init();Key_Init();HC_SR501_Init();Servo_Init();Sensorthreshold.tempValue = FLASH_R(FLASH_START_ADDR);		//从指定页的地址读FLASHSensorthreshold.flameValue = FLASH_R(FLASH_START_ADDR+2);	//从指定页的地址读FLASHSensorthreshold.smogValue = FLASH_R(FLASH_START_ADDR+4);	//从指定页的地址读FLASHSensorthreshold.methaneValue = FLASH_R(FLASH_START_ADDR+6);	GENERAL_TIM_Init();userInit();		//完成机智云初始赋值gizwitsInit();	//开辟一个环形缓冲区gizwitsSetMode(WIFI_AIRLINK_MODE);Delay_ms(1000);Servo_SetAngle(135);Buzzer_ON();Delay_ms(1000);Buzzer_OFF();Servo_SetAngle(45);KeyNum = 0;gizwitsSetMode(WIFI_AIRLINK_MODE);Delay_ms(1000);while (1){/*阈值上传至机智云云平台*/do{currentDataPoint.valuetempValue = Sensorthreshold.tempValue;currentDataPoint.valueflameValue = Sensorthreshold.flameValue;currentDataPoint.valuesmogValue = Sensorthreshold.smogValue;currentDataPoint.valuemethaneValue = Sensorthreshold.methaneValue;}while(0);IWDG_ReloadCounter(); switch (menu){case display_page1:SensorScan();	//获取传感器数据if (!displayPageNum){SensorDataDisplay1();	//显示传感器1数据OLED_Menu1();	//显示主页面1固定信息					}else{SensorDataDisplay2();	//显示传感器2数据		OLED_Menu2();	//显示主页面2固定信息			}AutomaticMode();if (KeyNum == KEY_1){Delay_ms(10);if(KeyNum == 1){KeyNum = 0;OLED_Clear();	//清屏menu = settingsPage;}}if (KeyNum == KEY_2)	//是否按下按键2{KeyNum = 0;OLED_Clear();	//清屏displayPageNum = !displayPageNum;	}break;case settingsPage:settingsThresholdDisplay1();	//显示传感器阈值1数据	OLED_settingsPage1();	//显示阈值设置界面1固定信息ThresholdModification(SetSelection());	//调节传感器阈值OLED_Option(SetSelection());	//获取按键次数,从而判断“>”显示位置if (KeyNum == KEY_2)	//判断用户是否按下退出按键{KeyNum = 0;OLED_Clear();	//清屏menu = display_page1;	//回到主页面1//存储修改的传感器阈值至flash内FLASH_W(FLASH_START_ADDR, Sensorthreshold.tempValue, Sensorthreshold.flameValue,Sensorthreshold.smogValue, Sensorthreshold.methaneValue);currentDataPoint.valuetempValue = Sensorthreshold.tempValue;currentDataPoint.valueflameValue = Sensorthreshold.flameValue;currentDataPoint.valuesmogValue = Sensorthreshold.smogValue;currentDataPoint.valuemethaneValue = Sensorthreshold.methaneValue;}break;default: break;}/*机智云阈值更改后保存至Flash*/if (valueFlashFlag){valueFlashFlag = 0;FLASH_W(FLASH_START_ADDR, Sensorthreshold.tempValue, Sensorthreshold.flameValue,Sensorthreshold.smogValue, Sensorthreshold.methaneValue);			}userHandle();	//更新机智云数据点变量存储的值gizwitsHandle((dataPoint_t *)&currentDataPoint);	//数据上传至机智云					}
}

六、实验效果 

七、资料内容

项目分享

http://www.xdnf.cn/news/16511.html

相关文章:

  • day064-kodbox接入对象存储与配置负载均衡
  • 并发安全之锁机制一
  • LLM Landscape:2025年大语言模型概览
  • 电子电路原理学习笔记---第4章二极管电路---第3天
  • Python全栈项目--基于深度学习的视频内容分析系统
  • Python与Mysql
  • C++算法实例精讲
  • 分布式微服务--核心组件与架构关系(一)
  • 深度研究——OpenAI Researcher Agent(使用OpenAI Agents SDK)
  • Mac查看本机ip地址
  • Leetcode_242.有效的字母异位词
  • Windows 11 下 Anaconda 命令修复指南及常见问题解决
  • linux du、df命令使用教程
  • node后端-JWT认证
  • Java面试宝典:MySQL事务和事务的隔离级别
  • 《中国棒球》cba球队有哪些球队·棒球1号位
  • qt 心跳包
  • ICPC 2024 网络赛(I)
  • 2.DRF 序列化器-Serializer
  • 如何规范化项目执行
  • 学习Python中Selenium模块的基本用法(2:下载浏览器驱动)
  • Solidity基础(教程④-ERC-4626收益金库)
  • 机器学习sklearn:不纯度与决策树构建
  • Python Pandas.merge_ordered函数解析与实战教程
  • 网络编程概述与UDP编程
  • Faiss 向量数据库详解
  • Redis反弹Shell
  • 【Java基础面试题】Java特点,八种基本数据类型
  • 《Java 程序设计》第 8 章 - Java 常用核心类详解
  • 用了Flutter包体积增大就弃用Flutter吗?包体积与开发效率,这两者之间如何权衡?