STM32项目开源:智能安防与燃气监测系统(代码+原理图+仿真)

文章目录


一、前言

实物项目成品:

仿真项目成品:

哔哩哔哩开源视频链接(复制浏览器打开):

https://www.bilibili.com/video/BV185YX6JEfL/?vd_source=10da4d04d580bd6b34f7298120737c50

(资料分享见文末)

二、项目功能简介

【开源】STM32单片机智能安防与燃气监测系统(代码+原理图+仿真)-编号:CY26017

硬件:STM32+OLED+蜂鸣器+门磁+可燃气体传感器+排风+舵机阀门+温湿度传感器+WIFI+火焰传感器

功能介绍:

  1. 防盗模式切换功能:系统可切换防盗开启、防盗关闭两种工作模式。
  2. 入侵检测报警功能:防盗模式开启时,门磁检测到开门判定为非法闯入;防盗关闭时,门磁触发为正常出入,不报警。
  3. 可燃气体泄漏监测功能:实时采集可燃气体浓度,浓度超标触发蜂鸣器声光报警。
  4. 险情联动控制功能:燃气泄漏或者检测到火焰时,自动启动排风设备,舵机动作关闭燃气阀门;支持手动控制阀门开关。
  5. 火灾探测报警功能:火焰传感器检测到火情,触发声光报警,联动排风与燃气切断动作。
  6. 环境参数采集显示功能:实时采集室内温湿度,OLED 屏幕显示温湿度数据,数据异常时报警提示。
  7. WiFi 远程数据查看功能:通过 WiFi 模块上传各项监测数据,手机 APP 可远程查看系统实时状态。
  8. APP 远程报警推送功能:出现入侵、燃气泄漏、火灾险情时,报警消息推送至手机 APP 提醒用户。

三、PCB设计

四、原理图设计

五、程序设计

代码如下():

c 复制代码
#include "sys.h"
#include "delay.h"
#include "oled.h"
#include "usart.h"
#include "dht11.h"
#include "key.h"
#include "adc.h"
#include "gpio.h"
#include "usart3.h"
#include "..\\HARDWARE\\ONENET\\cloud_onenet.h"
#include "..\\HARDWARE\\ONENET\\onenet_app_state.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include "math.h"

/**********************************
鍙橀噺瀹氫箟
**********************************/
char display_buf[50];
uint8_t key_num = 0;            // 鎸夐敭鎵弿鏍囧織浣?
uint8_t flag_display = 0;       // 鏄剧ず鐣岄潰鏍囧織浣?
uint8_t set_count = 0;          // 闃堝€艰缃爣蹇椾綅
uint8_t flag_mode = 0;          // 0:鑷姩 1:鎵嬪姩
uint8_t shuaxing = 0;
uint8_t beepflag = 0, sendyu_flag = 0;
uint8_t smart_config = 0;

uint8_t yanwu_value = 0;        // 鐏劙鐘舵€?
uint8_t yanwu_max = 20;         // 鐏劙鎶ヨ闃堝€?
uint8_t MQ_value = 0;           // 鍙噧姘斾綋娴撳害
uint8_t gas_leak_th = 20;       // 婕忔皵闃堝€?(%)
uint8_t gas_over_th = 40;       // 瓒呮爣闃堝€?(%)
uint8_t gas_level = 0;          // 0姝e父 1婕忔皵 2瓒呮爣
uint8_t temp = 0;               // 鐜娓╁害
uint8_t temp_max = 35;          // 娓╁害涓婇檺
uint8_t humi = 0;               // 鐜婀垮害
uint8_t humi_max = 70;          // 婀垮害涓婇檺
uint8_t humi_min = 30;          // 婀垮害涓嬮檺

uint8_t smoke_detected = 0;     // 鍙噧姘斾綋鐘舵€?
uint8_t fire_detected = 0;      // 鐏劙杈撳叆鐘舵€?
uint8_t door_opened = 0;        // 闂ㄧ杈撳叆鐘舵€?
uint8_t security_enabled = 0;   // 闃茬洍妯″紡
uint8_t intrusion_alarm = 0;    // 鍏ヤ镜鎶ヨ
uint8_t gas_alarm = 0;          // 鍙噧姘斾綋鎶ヨ
uint8_t fire_alarm = 0;         // 鐏伨鎶ヨ
uint8_t gas_alarm_type = 0;     // 0鏃?1婕忔皵 2瓒呮爣
uint8_t manual_fan_on = 0;      // 鎵嬪姩鎺掗
uint8_t auto_valve_locked = 0;  // 鑷姩妯″紡閿侀榾鏍囧織
uint16_t gas_alarm_hold_ms = 0; // 鍙噧姘斾綋鎶ヨ淇濇寔鏃堕棿
uint16_t fire_alarm_hold_ms = 0;// 鐏伨鎶ヨ淇濇寔鏃堕棿

uint16_t CO2 = 0;
uint16_t CO2_max = 2000;
u8 sendbuff[30];

/**********************************
鍑芥暟澹版槑
**********************************/
void Key_function(void);
void Monitor_function(void);
void Display_function(void);
void Manage_function(void);
void Move_function(uint8_t num);
void Update_Valve_Output(uint8_t closed);

/****
******* 瀹氭椂鍣ㄥ垵濮嬪寲鍑芥暟
*****/
void TIM4_Init(u16 arr, u16 psc)
{
	TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
	NVIC_InitTypeDef NVIC_InitStructure;

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);

	TIM_TimeBaseStructure.TIM_Period = arr;
	TIM_TimeBaseStructure.TIM_Prescaler = psc;
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);

	TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);

	NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);

	TIM_Cmd(TIM4, ENABLE);
}

/****
******* 涓诲嚱鏁?*****/
int main(void)
{
	delay_init();
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	BEEP_Init();
	Key_Init();
	Usart1_Init(9600);
	Usart2_Init(9600);
	USART3_Config();
	DHT11_Init();
	Adc_Init();
	TIM4_Init(1000, 72);
	Oled_Init();
	Oled_Clear_All();
	Cloud_StartupUI();

	while(1)
	{
		Key_function();
		Monitor_function();
		Display_function();
		Manage_function();
		Cloud_Task();
	}
}

/****
******* 鎸夐敭鍑芥暟
*****/
void Key_function(void)
{
	key_num = Chiclet_Keyboard_Scan(0);
	if(key_num != 0)
	{
		switch(key_num)
		{
			case 1:
				flag_display++;
				if(flag_display >= 3)
					flag_display = 0;
				if(flag_display == 2)
				{
					set_count = 1;
				}
				else
				{
					set_count = 0;
				}
				Oled_Clear_All();
				break;

			case 2:
				if(flag_display == 2)
				{
					set_count++;
					if(set_count > 4)
						set_count = 1;
				}
				else
				{
					flag_mode++;
					if(flag_mode > 1)
						flag_mode = 0;
					if(flag_mode == 0)
					{
						manual_fan_on = 0;
					}
				}
				break;

			case 3:
				if(flag_display == 0)
				{
					security_enabled = !security_enabled;
				}
				else if(flag_display == 1 && flag_mode == 1)
				{
					manual_fan_on = !manual_fan_on;
					ExhaustFan_Set(manual_fan_on);
				}
				else if(flag_display == 2)
				{
					switch(set_count)
					{
						case 1:
							if(temp_max < 99) temp_max++;
							break;
						case 2:
							if(humi_max < 99) humi_max++;
							break;
						case 3:
							if(gas_leak_th < (uint8_t)(gas_over_th - 1)) gas_leak_th++;
							break;
						case 4:
							if(gas_over_th < 99) gas_over_th++;
							break;
						default:
							break;
					}
				}
				break;

			case 4:
				if(flag_display == 1 && flag_mode == 1)
				{
					Update_Valve_Output(!ServoValve_IsClosed());
				}
				else if(flag_display == 2)
				{
					switch(set_count)
					{
						case 1:
							if(temp_max > 0) temp_max--;
							break;
						case 2:
							if(humi_max > 0) humi_max--;
							break;
						case 3:
							if(gas_leak_th > 0) gas_leak_th--;
							break;
						case 4:
							if(gas_over_th > (uint8_t)(gas_leak_th + 1)) gas_over_th--;
							break;
						default:
							break;
					}
				}
				break;

			default:
				break;
		}
	}
}

/****
******* 鍏夋爣鍑芥暟
*****/
void Move_function(uint8_t num)
{
	(void)num;
}

void Update_Valve_Output(uint8_t closed)
{
	if(closed)
	{
		ServoValve_Close();
	}
	else
	{
		ServoValve_Open();
	}
}

/****
******* 鐩戞祴鍑芥暟
*****/
void Monitor_function(void)
{
	uint16_t mq_adc_raw = 0;
	uint8_t gas_alarm_now = 0;
	uint8_t fire_alarm_now = 0;

	DHT11_Read_Data(&humi, &temp);
	mq_adc_raw = Get_Adc_Average(1, 1);  // PA1瀵瑰簲ADC1_IN1
	MQ_value = (uint8_t)((mq_adc_raw * 100U) / 4095U);
	if(MQ_value > 100)
	{
		MQ_value = 100;
	}

	if(MQ_value >= gas_over_th)
	{
		gas_level = 2;
	}
	else if(MQ_value >= gas_leak_th)
	{
		gas_level = 1;
	}
	else
	{
		gas_level = 0;
	}

	smoke_detected = (gas_level > 0) ? 1 : 0;
	fire_detected = Fire_IsDetected();
	door_opened = Door_IsOpen();

	yanwu_value = fire_detected ? 100 : 0;
	gas_alarm_now = (gas_level > 0) ? 1 : 0;
	fire_alarm_now = (yanwu_value >= yanwu_max) ? 1 : 0;

	if(gas_alarm_now)
	{
		gas_alarm_hold_ms = 3000;
		gas_alarm_type = gas_level;
		auto_valve_locked = 1;
	}
	if(fire_alarm_now)
	{
		fire_alarm_hold_ms = 3000;
		auto_valve_locked = 1;
	}

	gas_alarm = (gas_alarm_now || (gas_alarm_hold_ms > 0)) ? 1 : 0;
	fire_alarm = (fire_alarm_now || (fire_alarm_hold_ms > 0)) ? 1 : 0;
	intrusion_alarm = (security_enabled && door_opened) ? 1 : 0;

	if(!gas_alarm)
	{
		gas_alarm_type = 0;
	}
}

/****
******* 鏄剧ず鍑芥暟
*****/
void Display_function(void)
{
	static uint8_t door_display_state = 0xFF;
	static uint8_t fire_display_state = 0xFF;
	static uint8_t last_display_page = 0xFF;
	uint8_t current_door_state = 0;
	uint8_t current_fire_state = 0;

	if(last_display_page != flag_display)
	{
		door_display_state = 0xFF;
		fire_display_state = 0xFF;
		last_display_page = flag_display;
	}

	switch(flag_display)
	{
		case 0:
			Oled_ShowCHinese(1, 0, "温度");
			sprintf(display_buf, ":%2dC", temp);
			Oled_ShowString(1, 4, display_buf);

			Oled_ShowCHinese(2, 0, "湿度");
			sprintf(display_buf, ":%2d%%", humi);
			Oled_ShowString(2, 4, display_buf);

			Oled_ShowCHinese(3, 0, "防盗模式");
			if(security_enabled)
			{
				Oled_ShowCHinese(3, 4, "开");
			}
			else
			{
				Oled_ShowCHinese(3, 4, "关");
			}

			if(intrusion_alarm)
			{
				Oled_ShowCHinese(4, 0, "入侵报警");
			}
			else if(fire_alarm)
			{
				Oled_ShowCHinese(4, 0, "火灾报警");
			}
			else
			{
				Oled_ShowCHinese(4, 0, "可燃气体");
				sprintf(display_buf, ":%2d%%", MQ_value);
				Oled_ShowString(4, 8, display_buf);
				if(gas_alarm_type >= 2)
				{
					Oled_ShowCHinese(4, 6, "超标");
				}
				else if(gas_alarm_type == 1)
				{
					Oled_ShowCHinese(4, 6, "漏气");
				}
				else
				{
					Oled_ShowCHinese(4, 6, "正常");
				}
			}
			break;

		case 1:
			Oled_ShowCHinese(1, 0, "排风");
			if(ExhaustFan_Get())
			{
				Oled_ShowCHinese(1, 2, "开");
			}
			else
			{
				Oled_ShowCHinese(1, 2, "关");
			}

			if(flag_mode == 0)
			{
				Oled_ShowCHinese(1, 6, "自动");
			}
			else
			{
				Oled_ShowCHinese(1, 6, "手动");
			}

			Oled_ShowCHinese(2, 0, "燃气阀");
			if(ServoValve_IsClosed())
			{
				Oled_ShowCHinese(2, 3, "关");
			}
			else
			{
				Oled_ShowCHinese(2, 3, "开");
			}

			current_door_state = door_opened ? (security_enabled ? 2 : 1) : 0;
			if(door_display_state != current_door_state)
			{
				if(current_door_state == 2)
				{
					Oled_ShowCHinese(3, 0, "门磁入侵报警");
				}
				else if(current_door_state == 1)
				{
					Oled_ShowCHinese(3, 0, "门磁正常出入");
				}
				else
				{
					Oled_ShowCHinese(3, 0, "门磁关");
					Oled_ShowString(3, 6, "      ");
				}
				door_display_state = current_door_state;
			}

			current_fire_state = fire_alarm ? 1 : 0;
			if(fire_display_state != current_fire_state)
			{
				if(current_fire_state)
				{
					Oled_ShowCHinese(4, 0, "火灾报警");
				}
				else
				{
					Oled_ShowCHinese(4, 0, "火焰正常");
				}
				fire_display_state = current_fire_state;
			}
			break;

		case 2:
			Oled_ShowCHineseMode(1, 0, "温度阈值", set_count == 1);
			sprintf(display_buf, ":%2d", temp_max);
			Oled_ShowStringMode(1, 8, display_buf, set_count == 1);

			Oled_ShowCHineseMode(2, 0, "湿度阈值", set_count == 2);
			sprintf(display_buf, ":%2d", humi_max);
			Oled_ShowStringMode(2, 8, display_buf, set_count == 2);

			Oled_ShowCHineseMode(3, 0, "漏气阈值", set_count == 3);
			sprintf(display_buf, ":%2d", gas_leak_th);
			Oled_ShowStringMode(3, 8, display_buf, set_count == 3);

			Oled_ShowCHineseMode(4, 0, "超标阈值", set_count == 4);
			sprintf(display_buf, ":%2d", gas_over_th);
			Oled_ShowStringMode(4, 8, display_buf, set_count == 4);
			break;

		default:
			break;
	}
}

/****
******* 绠$悊鍑芥暟
*****/
void Manage_function(void)
{
	if(gas_alarm || fire_alarm)
	{
		ExhaustFan_Set(1);
		Update_Valve_Output(1);
		auto_valve_locked = 1;
	}
	else
	{
		if(flag_mode == 0)
		{
			ExhaustFan_Set(0);
			if(auto_valve_locked)
			{
				Update_Valve_Output(1);
			}
			else
			{
				Update_Valve_Output(0);
			}
		}
		else
		{
			ExhaustFan_Set(manual_fan_on);
		}
	}

	if(intrusion_alarm || gas_alarm || fire_alarm || temp > temp_max || humi > humi_max || humi < humi_min)
	{
		BEEP = !BEEP;
		beepflag = 1;
	}
	else
	{
		BEEP = 0;
		beepflag = 0;
	}
}

/****
******* 瀹氭椂鍣ㄤ腑鏂湇鍔″嚱鏁?*****/
void TIM4_IRQHandler(void)
{
	static uint16_t count = 0, count1 = 0;

	if(TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)
	{
		TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
		g_tick_ms++;

		if(gas_alarm_hold_ms > 0)
		{
			gas_alarm_hold_ms--;
		}
		if(fire_alarm_hold_ms > 0)
		{
			fire_alarm_hold_ms--;
		}

		if(count++ > 500)
		{
			count = 0;
			shuaxing = 1;
		}

		if(count1++ > 2000)
		{
			count1 = 0;
			sendyu_flag = 1;
		}
		if((g_tick_ms % 5000u) == 0u)
		{
			g_report_5s_flag = 1;
		}
	}
}

六、包含内容

七、资料分享

资料获取:请查看主页介绍搜索或观看开源视频获取

相关推荐
服务器硬件项目经理1 小时前
第14篇_服务器主板上MOSFET的三大应用
运维·服务器·人工智能·单片机·硬件工程·硬件
SamChan901 小时前
Python批量处理PDF踩坑实录:中文编码、字体内嵌、多栏排版与内存占用
python·单片机·ai·pdf·机器翻译
ZStack开发者社区1 小时前
ZSvirt 迁移实战:从 VMware 迁移虚拟机的三种方式
开源·vmware·虚拟化·云迁移
HUI-4742 小时前
EG1170|SSOP‑10 外置 MOS 200V 异步降压控制器,快充 / 电池充电大电流降压优选
嵌入式硬件·硬件工程
阡陌数智2 小时前
LiteLLM 开源网关实践:能力边界与生产环境改造要点
大数据·人工智能·开源·prompt·软件工程
zcmodeltech2 小时前
能源电力沙盘模型控制系统设计——基于STM32与Modbus RTU的“发—输—变—配—用”全链条动态展示方案
数据库·stm32·单片机·嵌入式硬件·能源
高斯的手稿08012 小时前
丽萨单片机固件升级,裁剪hex文件
单片机·嵌入式硬件
昌原的儿子LEO2 小时前
【单片机入门】UART 串行异步通信核心考点梳理
linux·单片机·51单片机
狗凯之家源码网2 小时前
开源商城系统 1.8.1 版本核心能力与实战效果展示
开源·商城系统