STM32开发实例_基于4G无线通信的家庭电路预警系统(电路图+程序+流程图)24-32-148

一.系统概述

家庭电路智能预警系统的功能介绍如下:
1. 温湿度采集:实时监测环境温度和湿度,确保对室内气候状况的掌控。
2. 烟雾检测:持续检测空气中的烟雾浓度,及时发现火灾隐患。
3. 稳压电路设计: 将家用交流电转换为直流电,确保系统稳定供电。
4. 供电电压监测:通过ADC模数转换器采集并处理供电电压数据,监控设备电源状态。
5. 负载电流检测:配备3路负载电路,利用信号处理电路将负载电流转换为电压信号;分析模拟信号,准确计算各负载的电流值。
6. 数据实时显示:将温度、湿度、烟雾、电压及负载电流等信息显示在屏幕上,便于用户查看。
7. 4G无线通信模块: 实现数据远程传输,将采集信息上传至手机APP。
8. 阈值设定功能: 用户可在手机APP中设置烟雾浓度和负载电流的报警阈值。
9. 自动预警与断电控制:当负载电流超过设定阈值时,系统自动控制继电器切断电源;触发蜂鸣器报警,并通过无线模块向APP发送报警信息。
10. 火灾报警:烟雾浓度超标时,系统同样发送火灾报警至APP,蜂鸣器发出警报。
11. 安全保障:通过自动断电及声光报警,有效预防电气安全事故,保障家庭用电安全。

二.电路设计

电路图采用Altium Designer进行设计:
1. 通过STM32F103C8T6单片机作为系统主控,最小系统电路是整个电路的核心;
2. 通过DHT11进行温湿度检测,并通过one-wire总线与单片机的GPIO脚进行连接;
3. 通过0.96寸的OLED12864进行数据显示,采用IIC总线的形式与单片机进行通信;
4. 使用MQ-2进行烟雾浓度检测并将模块的模拟输出脚与单片机的模拟输入脚相接;
5. 通过EG8542电流传感器检测流过的电流强度,并将模块模拟输出接口接单片机的ADC接口;
6. 通过4G模块Air724将采集到的数据上传到上位机端,模块通过UART串口与单片机进行通信;
7. 通过继电器模拟设备的控制,并将继电器的数据输出脚与单片机的GPIO脚进行连接;
8. 使用蜂鸣器进行报警,蜂鸣器采用的有源蜂鸣器,使用NPN三极管进行蜂鸣器进行驱动。

三.程序设计 

#include "Control_Report_To_Police.h"

 /************************************************
版权:小常硬件
公众号:微信搜索“小常硬件“在公众号免费下载相关资料
************************************************/	

u16 Servor_CPWM_Set_Buffer[9]={1500,1500,1500,1500,1500,1500,1500,1500,1500};

void RFID_Handle()
{
	_Bool RC522_Incre_Flag=0,RC522_Dre_Flag=0;
  _Bool RC5222_Incre_Flag=0,RC5222_Dre_Flag=0;
	
	RC522_Care_Incre_Handle(&RC522_Incre_Flag);  //RC5222 是否刷卡标志位
  RC522_Care_Dre_Handle(&RC522_Dre_Flag);
	
  RC5222_Care_Incre_Handle(&RC5222_Incre_Flag);  //RC522 是否刷卡标志位
  RC5222_Care_Dre_Handle(&RC5222_Dre_Flag);
	
	Control_Port_Low_Effetive(RC522_Incre_Flag,&Beep);

	Control_Port_Low_Effetive(RC522_Dre_Flag,&Beep);
	
	Control_Port_Low_Effetive(RC5222_Incre_Flag,&Beep);
	
	Control_Port_Low_Effetive(RC5222_Dre_Flag,&Beep);

}


/************************************
OLED显示屏
************************************/
void OLED_Display_Cotrol(void)  //系统显示控制功能实现   OLED显示
{
	
	static unsigned short timeCount = 0;	//发送间隔变量
	 static u8 temperature=28,humidity=29;
	static char p1[16]=" "; 
  static u16 diany;
  static int n=0,g;
  static float yanw,dianl;
	static int wen,shi,dl,yan,a=0,b=0,c=0,d=0,flaga,flagb,yanwu,dianliu;

  
	char Test_Mqqt_Buffer[512]="";  //为了接收按钮按下后阿里云传输的数据信息
  char Test_Them_WATER_ON_Buffer[4]="999";
  char Test_Them_WATER_OFF_Buffer[4]="888";
	char Test_Them_WATER_OF_Buffer[4]="777";
	char Test_Them_WATER_O_Buffer[4]="666";
	char Test_Them_WATER_of_Buffer[4]="555";
	u16 Test_Mqqt_Num=0;	


			
  if(connectFlag == 1) 
	{ 
	   
		   g=KEY_Scan(0);
		  if(g==KEY1_PRES){n=~n;OLED_CLS();}
      if(n==0)
			{//温度
				OLED_ShowCN(0,0,0);
				OLED_ShowCN(16,0,1);		
				DHT11_Read_Data(&temperature,&humidity);
				sprintf((char*)p1,":%d  ",temperature);
				OLED_ShowStr(32,0,p1,2);		
					//湿度
				OLED_ShowCN(64,0,2);
				OLED_ShowCN(80,0,3);		
				sprintf((char*)p1,":%d ",humidity);
				OLED_ShowStr(96,0,p1,2);
					//烟雾
				OLED_ShowCN(0,2,4);
				OLED_ShowCN(16,2,5);		
				Get_adc(&yanw);
				yanwu=(int)yanw;
				sprintf((char*)p1,":%d ",yanwu);
				OLED_ShowStr(32,2,p1,2);		
					//电压
				OLED_ShowCN(64,2,6);
				OLED_ShowCN(80,2,7);	
				Get_adc1(&diany);
				sprintf((char*)p1,":%d",diany);
				OLED_ShowStr(96,2,p1,2);	
					//负载电流
				OLED_ShowCN(0,4,8);
				OLED_ShowCN(16,4,9);	
				OLED_ShowCN(32,4,6);
				OLED_ShowCN(48,4,10);	
				Get_adc2(&dianl);
				dianliu=(int)dianl;
				sprintf((char*)p1,":%dma",dianliu);
				OLED_ShowStr(64,4,p1,2);
				//温度阈值
				if(g==KEY0_PRES)a++;
				if(a==11)a=0;
				wen=a*10;
				OLED_ShowCN(0,6,0);
				OLED_ShowCN(16,6,1);
				OLED_ShowCN(32,6,11);
				OLED_ShowCN(48,6,12);
				sprintf((char*)p1,":%d ",wen);
				OLED_ShowStr(64,6,p1,2);
		}else{
			
					//湿度阈值
					if(g==KEY0_PRES)b++;
					if(b==11)b=0;
					shi=b*10;
					OLED_ShowCN(0,0,2);
					OLED_ShowCN(16,0,3);
					OLED_ShowCN(32,0,11);
					OLED_ShowCN(48,0,12);
					sprintf((char*)p1,":%d ",shi);
					OLED_ShowStr(64,0,p1,2);
					
					//烟雾阈值
					if(g==KEY2_PRES)c++;
					if(c==11)c=0;
					yan=c*3;
					OLED_ShowCN(0,2,4);
					OLED_ShowCN(16,2,5);
					OLED_ShowCN(32,2,11);
					OLED_ShowCN(48,2,12);
					sprintf((char*)p1,":%d ",yan);
					OLED_ShowStr(64,2,p1,2);
					
					//电流阈值
					if(g==KEY3_PRES)d++;
					if(d==11)d=0;
					dl=d*10;
					OLED_ShowCN(0,4,6);
					OLED_ShowCN(16,4,10);
					OLED_ShowCN(32,4,11);
					OLED_ShowCN(48,4,12);
					sprintf((char*)p1,":%d ",dl);
					OLED_ShowStr(64,4,p1,2);
					}
					if(temperature>wen||humidity>shi||yanwu>yan||dianliu>dl){Relay_1=0;}
					else {Relay_0=0;Relay_1=1;}
					
					if(dianliu>dl)Relay_0=1;
					else Relay_0=0;
					if(dianl>dl)flaga=1;
					else flaga=0;
					
					if(yanwu>yan)flagb=1;
					else flagb=0;


void Parameter_2_Compare(u8 parameter1,u16 parameter1_Limit_Value,u8 parameter2,u16 parameter2_Limit_Value,u8 *Parameter1_Compare_Result,u8 *Parameter2_Compare_Result) 
{
	if(parameter1>parameter1_Limit_Value)   //如果采集到的参数值超过设定的阈值  这部分可以根据实际需要进行调整 需要改低于的时候改低于
		*Parameter1_Compare_Result=1;
	else
		*Parameter1_Compare_Result=0;
	if(parameter2>parameter2_Limit_Value)   //如果采集到的参数值超过设定的阈值  这部分可以根据实际需要进行调整   需要改低于的时候改低于
		*Parameter2_Compare_Result=1;
	else
		*Parameter2_Compare_Result=0;
}

/***********2个参数比较子函数定义*******
以下是两个参数比较的子函数
在调用的该函数的时候需要看形参的数据类型
要根据实参的数据类型对以下函数的形参类型进行调整

返回结果信息为1   需要报警||调节
返回结构信息为0   不需要报警||调节

**************************************/

void Parameter_3_Compare(u8 parameter1,u8 parameter1_Limit_Value,float parameter2,float parameter2_Limit_Value,float parameter3,float parameter3_Limit_Value,_Bool *Parameter1_Compare_Result,_Bool *Parameter2_Compare_Result,_Bool *Parameter3_Compare_Result) 
{
	if(parameter1>parameter1_Limit_Value)   //如果采集到的参数值超过设定的阈值  这部分可以根据实际需要进行调整 需要改低于的时候改低于
		*Parameter1_Compare_Result=1;
	else
		*Parameter1_Compare_Result=0;
	if(parameter2>parameter2_Limit_Value)   //如果采集到的参数值超过设定的阈值  这部分可以根据实际需要进行调整   需要改低于的时候改低于
		*Parameter2_Compare_Result=1;
	else
		*Parameter2_Compare_Result=0;
	if(parameter3>parameter3_Limit_Value)   //如果采集到的参数值超过设定的阈值  这部分可以根据实际需要进行调整   需要改低于的时候改低于
		*Parameter3_Compare_Result=1;
	else
		*Parameter3_Compare_Result=0;
}

/************控制端口输出子函数*******
根据参数控制标志位 完成对不同端口的控制
需要完成控制动作时,低电平有效
*************************************/

void Control_Port_Low_Effetive(u8 Parameter_Compare_Result,volatile unsigned long *Port)  //  低电平有效  输出控制结果
{
	if(Parameter_Compare_Result==1)
	{
			*Port=0;
			delay_ms(100);
	    delay_ms(100);
	}	
	else
		*Port=1;
}

/************控制端口输出子函数*******
根据参数控制标志位 完成对不同端口的控制
需要完成控制动作时,高电平有效
*************************************/

void Control_Port_High_Effetive(u8 Parameter_Compare_Result,volatile unsigned long *Port)  //  高电平有效  输出控制结果
{
	if(Parameter_Compare_Result==1)
		*Port=1;
	else
		*Port=0;
}

//检测到哭  控制电机正反转   控制音乐播放   控制显示屏显示YES
void Noise_Control_Port_Adjust(u8 Parameter_Compare_Result)  //  低电平有效  输出控制结果
{
	u8 Moto_Spin_Num;
	u16 Speech_num;
	float Noise;
	char Speech_Music[]="A8:02/00001*MP3";
//  char p1[16]=" ";
	if(Parameter_Compare_Result==1)
	{
		   Speech_num++;
		
		  Get_Adc_Convert_Data(&Noise);
//			sprintf((char*)p1,":%d ",(int)Noise);
//	    OLED_ShowStr(64,4,p1,2);
			 OLED_ShowStr(40,4,"Yes",2);

		  JR6001_Uart1_Handle(Speech_Music,&Parameter_Compare_Result);
		  for(Moto_Spin_Num=0;Moto_Spin_Num<100;Moto_Spin_Num++)
			ULN2003_GPIOB_Contol_Moto_Foreward(5);
		  for(Moto_Spin_Num=0;Moto_Spin_Num<100;Moto_Spin_Num++)
		  ULN2003_GPIOB_Contol_Moto_Reversal(5);
      delay_ms(1000);
	}	
	else 
	{
		  ULN2003_GPIOB_Contol_Moto_Stop();
	    OLED_ShowStr(40,4,"NO ",2);
	}

}


//两个字符串比较   判断str 字符串中是否包含substr字符串

_Bool isSubstring(const char* str, const char* substr) {
    int i, j;
    int str_len =512;   //这个值正常是str字符串的长度   但是因为内部包含换行符  算的不准因此设定成固定的
    int substr_len = strlen(substr);

    for (i = 0; i <= str_len - substr_len; i++) {
        for (j = 0; j < substr_len; j++) {
            if (str[i + j] != substr[j])
                break;
        }
        if (j == substr_len)
            return true;
    }

    return false;
}

//两个字符串进行拼接的函数

void concatenateStrings(const char* str1, const char* str2, char* result) {
    int i = 0;
    int j = 0;

    while (str1[i] != '\0') {
        result[j] = str1[i];
        i++;
        j++;
    }

    i = 0;
    while (str2[i] != '\0') {
        result[j] = str2[i];
        i++;
        j++;
    }
    result[j] = '\0';
}





四.资料内容

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小常硬件

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值