【毕业设计项目】基于STM32智能窗户 电子信息 物联网等 可以手机APP控制

项目视频

哔哩哔哩视频链接:


1项目介绍


2原理图绘制


3程序讲解


4成品展示

一、项目简介

本设计是一款基于STM32单片机的智能窗户系统,使用STM32F103C8T6单片机作为核心控制部分,使用DH11温湿度传感器来采集环境温湿度,使用红外对射传感器来检测是否有人入侵,使用雨滴传感器来检测是否下雨,使用独立按键来切换模式与开关窗,使用OLED显示屏来作为显示部分,使用蜂鸣器用来警报,使用ULN2003步进电机驱动板和步进电机来模拟窗户,使用ESP8266_WIFI模块来进行网络传输,将数据上传到ONENET云平台,同时使用APP inventor2制作APP获取传输到ONENET云平台的数据进行手机远程监控功能。

1.功能组成概括


在这里插入图片描述

2.本项目主要使用到的技术

1.单总线-DHT11温湿度传感器
2.ADC-YL69雨滴传感器
3.串口-ESP8266_WIFI模块
4.定时器
5.SPI -OLED显示屏

二、项目组成

在这里插入图片描述

三、原理图设计

在这里插入图片描述

四、源码设计

部分截图
在这里插入图片描述
main.c

//单片机头文件
#include "stm32f10x.h"

//网络协议层
#include "onenet.h"

//网络设备
#include "net_device.h"

//硬件驱动
#include "led.h"
#include "oled.h"
#include "delay.h"
#include "usart.h"
#include "hwtimer.h"
#include "SysTick.h"
#include "system.h"
#include "iwdg.h"
#include "fault.h"
#include "selfcheck.h"
#include "info.h"
#include "dht11.h"
#include "adc.h"
#include "lsens.h"
#include "hwds.h"
#include "key.h"
//C库
#include <string.h>

#define Z1 GPIO_ResetBits(GPIOB,B1);GPIO_SetBits(GPIOB,B2);GPIO_SetBits(GPIOB,B3);GPIO_SetBits(GPIOB,B4);	
#define Z2 GPIO_SetBits(GPIOB,B1);GPIO_ResetBits(GPIOB,B2);GPIO_SetBits(GPIOB,B3);GPIO_SetBits(GPIOB,B4);	
#define Z3 GPIO_SetBits(GPIOB,B1);GPIO_SetBits(GPIOB,B2);GPIO_ResetBits(GPIOB,B3);GPIO_SetBits(GPIOB,B4);	
#define Z4 GPIO_SetBits(GPIOB,B1);GPIO_SetBits(GPIOB,B2);GPIO_SetBits(GPIOB,B3);GPIO_ResetBits(GPIOB,B4);	
#define ZZ Z1;delay_ms(t);Z2;delay_ms(t);Z3;delay_ms(t);Z4;delay_ms(t);//正转

#define F1 GPIO_ResetBits(GPIOB,B4);GPIO_SetBits(GPIOB,B3);GPIO_SetBits(GPIOB,B2);GPIO_SetBits(GPIOB,B1);	
#define F2 GPIO_SetBits(GPIOB,B4);GPIO_ResetBits(GPIOB,B3);GPIO_SetBits(GPIOB,B2);GPIO_SetBits(GPIOB,B1);	
#define F3 GPIO_SetBits(GPIOB,B4);GPIO_SetBits(GPIOB,B3);GPIO_ResetBits(GPIOB,B2);GPIO_SetBits(GPIOB,B1);	
#define F4 GPIO_SetBits(GPIOB,B4);GPIO_SetBits(GPIOB,B3);GPIO_SetBits(GPIOB,B2);GPIO_ResetBits(GPIOB,B1);	
#define FZ F1;delay_ms(t);F2;delay_ms(t);F3;delay_ms(t);F4;delay_ms(t);//反转

#define TZ GPIO_ResetBits(GPIOB,B4);GPIO_ResetBits(GPIOB,B3);GPIO_ResetBits(GPIOB,B2);GPIO_ResetBits(GPIOB,B1);	

u8 temperature;
u8 humidity;
u8 shuidi;
_Bool W_M=0;//0窗户关   1窗户开
_Bool C_M=0; //0儿童模式关 1儿童模式开
_Bool M_S=0;//0自动模式 1手动模式
_Bool R=0;//0无人     1有人 
_Bool RAIN=0;//0没下雨     1下雨 

//数据流
DATA_STREAM dataStream[] = {
								{"wendu", &temperature, TYPE_UCHAR, 1},
								{"shidu", &humidity, TYPE_UCHAR, 1},
								{"RAIN", &RAIN, TYPE_BOOL, 1},
								{"R", &R, TYPE_BOOL, 1},
								{"W_M", &W_M, TYPE_BOOL, 1},
								{"C_M", &C_M, TYPE_BOOL, 1},
								{"moshi", &M_S, TYPE_BOOL, 1},
							};
unsigned char dataStreamLen = sizeof(dataStream) / sizeof(dataStream[0]);





/*
************************************************************
*	函数名称:	Hardware_Init
*
*	函数功能:	硬件初始化
*
*	入口参数:	无
*
*	返回参数:	无
*
*	说明:		初始化单片机功能以及外接设备
************************************************************
*/
void Hardware_Init(void)
{
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);								//中断控制器分组设置
	Delay_Init();																//systick初始化	
	Led_Init();																	//LED初始化	
	B_Init();
	Usart1_Init(115200); 														//初始化串口   115200bps
	netDeviceInfo.reboot = 0;
	TIM2_Int_Init(49, 35999);												//72MHz,36000分频-500us,50重载值。则中断周期为500us * 50 = 25ms
	TIM3_Int_Init(1999, 35999);											//72MHz,36000分频-500us,2000重载值。则中断周期为500us * 2000 = 1s																			//定时检查网络状态标志位
	UsartPrintf(USART_DEBUG, "3.Hardware init OK\r\n");							//提示初始化完成
}

/*
************************************************************
*	函数名称:	main
*
*	函数功能:	
*
*	入口参数:	无
*
*	返回参数:	0
*
*	说明:		
************************************************************
*/
int main(void)
{
	u16 i;
	u8 k;
	unsigned char *dataPtr;
	unsigned int runTime = 0;
	u8 t=3;
	_Bool sendFlag = 0;
	SysTick_Init(72);
	Hardware_Init();									//硬件初始化
	NET_DEVICE_IO_Init();								//网络设备IO初始化
	NET_DEVICE_Reset();									//网络设备复位
	NET_DEVICE_Set_DataMode(DEVICE_CMD_MODE);			//设置为命令收发模式(例如ESP8266要区分AT的返回还是平台下发数据的返回)
	OLED_Init();
	DHT11_Init();	
	Adc_Init();
	Lsens_Init();
	KEY_Init();
	Hwds_Init();
	OLED_ShowCHinese(0,0,0);
	OLED_ShowCHinese(15,0,2);
	OLED_ShowCHinese(60,0,1);
	OLED_ShowCHinese(75,0,2);
	OLED_ShowCHinese(0,2,3);
	OLED_ShowCHinese(15,2,4);
	OLED_ShowCHinese(30,2,5);
	OLED_ShowCHinese(45,2,6);
	OLED_ShowCHinese(0,4,7);
	OLED_ShowCHinese(15,4,8);
	OLED_ShowCHinese(30,4,9);
	OLED_ShowCHinese(45,4,10);
	OLED_ShowCHinese(80,4,12);
	OLED_ShowCHinese(0,6,13);
	OLED_ShowCHinese(15,6,14);
	OLED_ShowCHinese(30,6,15);
	OLED_ShowCHinese(45,6,16);
	OLED_ShowCHinese(80,6,17);
	while(1)
	{
		DHT11_Read_Data(&temperature,&humidity);	//读取温湿度值
		shuidi=Shuidi_Get_Val();
		//OLED_ShowNum(100,2,shuidi,3,16);
		OLED_ShowNum(35,0,temperature,3,16);
		OLED_ShowNum(90,0,humidity,3,16);
		//非儿童保护模式
		if(C_M==0)
		{
			//如果是自动模式
			if(M_S==0)//自动模式
			{
				if(shuidi>60) //表示下雨
				{
					RAIN=1;
					OLED_ShowCHinese(80,2,3);
					//如果窗户是开的,则关窗
					if(W_M==1)
					{
						for(i=0;i<150;i++)
						{
							ZZ;
						}
						TZ;
						W_M=0;
					}
					else
					{}
				
				}
				else         //表示不下雨
				{
					RAIN=0;
					OLED_ShowCHinese(80,2,4);
					//如果窗户是关的,则开窗
					if(W_M==0)
					{
						for(i=0;i<150;i++)
						{
							FZ;
						}
						TZ;
						W_M=1;
					}
					else
					{}
					
				}
			}
			else
			{
				//如果是手动模式
			}
		}
		else//儿童保护模式下窗户一直是关的
		{
			if(W_M==1)
			{
				//关窗
				for(i=0;i<150;i++)
				{
					ZZ;
				}
				TZ;
				W_M=0;
			}
			else
			{}
		}
		if(W_M==1)
		{
				OLED_ShowCHinese(80,4,11);
		}
		else
		{
				OLED_ShowCHinese(80,4,12);	
		}
		k=KEY_Scan(0);
		switch(k)
		{
			case KEY0_PRES:
				//切换手自动模式  如果是自动模式,则切换为手动模式,否则切换为自动模式
			if(M_S==0)
			{
				OLED_ShowCHinese(80,6,18);
				M_S=1;
			}
			else
			{
				OLED_ShowCHinese(80,6,17);
				M_S=0;
			}
			break;
			case KEY1_PRES:
				//手动模式下开关窗,自动模式无反应
			if(C_M==0)
			{
				if(M_S==1)
				{
					if(W_M==0)
					{
						for(i=0;i<150;i++)
						{
							FZ;
						}
						TZ;
						W_M=1;
					}
					else
					{
						for(i=0;i<150;i++)
						{
							ZZ;
						}
						TZ;
						W_M=0;
					}	
				}
			}
			break;
		}

		if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_7)==0)
		{
			R=1;//有人
			Led1_Set(0);//报警
		}
		else
		{
			R=0;//无人
			Led1_Set(1);
		}

		delay_ms(100);		
		if(oneNetInfo.netWork == 1)
		{
		OLED_ShowNum(110,6,1,1,16);
/******************************************************************************
			数据与心跳
******************************************************************************/
			if(timInfo.timer6Out - runTime >= 100)									//25s一次(25ms中断)
			{
				runTime = timInfo.timer6Out;
				
				if(sendFlag)
				{
					TIM_Cmd(OS_TIMER, DISABLE);
					OneNet_HeartBeat();												//心跳连接
					TIM_Cmd(OS_TIMER, ENABLE);
				}
				else
				{
					TIM_Cmd(OS_TIMER, DISABLE);
					OneNet_SendData(kTypeSimpleJsonWithoutTime, dataStreamLen);		//数据发送
					TIM_Cmd(OS_TIMER, ENABLE);
				}
		
				sendFlag = !sendFlag;
			}
			

/******************************************************************************
			平台下发命令解析
******************************************************************************/
			if(oneNetInfo.netWork && NET_DEVICE_Get_DataMode() == DEVICE_DATA_MODE)	//当有网络 且 在命令接收模式时
			{
				dataPtr = NET_DEVICE_GetIPD(0);										//不等待,获取平台下发的数据
				if(dataPtr != NULL)													//如果数据指针不为空,则代表收到了数据
				{
					OneNet_App(dataPtr);											//集中处理
				}
			}
			
/******************************************************************************
			错误处理
******************************************************************************/
			if(faultType != FAULT_NONE)												//如果错误标志被设置
			{
				UsartPrintf(USART_DEBUG, "WARN:	Fault Process\r\n");
				Fault_Process();													//进入错误处理函数
			}
			
/******************************************************************************
			数据反馈
******************************************************************************/
			if(oneNetInfo.sendData)
			{
				oneNetInfo.sendData = OneNet_SendData(kTypeSimpleJsonWithoutTime, dataStreamLen);
			}
		}
		else
		{
		OLED_ShowNum(110,6,0,1,16);
/******************************************************************************
			初始化网络设备、接入平台
******************************************************************************/
			if(!oneNetInfo.netWork && (checkInfo.NET_DEVICE_OK == DEV_OK))			//当没有网络 且 网络模块检测到时
			{
				NET_DEVICE_Set_DataMode(DEVICE_CMD_MODE);							//设置为命令收发模式
				
				if(!NET_DEVICE_Init())												//初始化网络设备,能连入网络
				{
					OneNet_DevLink(oneNetInfo.devID, oneNetInfo.apiKey);			//接入平台
					
					if(oneNetInfo.netWork)
					{
						runTime = timInfo.timer6Out;								//更新时间
					}
					else
					{
					}
				}
			}
			
/******************************************************************************
			网络设备检测
******************************************************************************/
			if(checkInfo.NET_DEVICE_OK == DEV_ERR) 									//当网络设备未做检测
			{
				NET_DEVICE_Set_DataMode(DEVICE_CMD_MODE);							//设置为命令收发模式
				
				if(timerCount >= NET_TIME) 											//如果网络连接超时
				{
					UsartPrintf(USART_DEBUG, "Tips:		Timer Check Err\r\n");
					
					NET_DEVICE_Reset();												//复位网络设备
					timerCount = 0;													//清零连接超时计数
					faultType = FAULT_NONE;											//清除错误标志
				}
				
				if(!NET_DEVICE_SendCmd("AT\r\n", "OK"))								//网络设备检测
				{
					UsartPrintf(USART_DEBUG, "NET Device :Ok\r\n");
					checkInfo.NET_DEVICE_OK = DEV_OK;								//检测到网络设备,标记
					NET_DEVICE_Set_DataMode(DEVICE_DATA_MODE);						//设置为数据收发模式
				}
				else
				{
					UsartPrintf(USART_DEBUG, "NET Device :Error\r\n");
				}
			}
			}delay_ms(10);
	}

}

五、APP设计

APP invertor2是图形化界面的制作APP的工具,像我们这种不会软件制作的人也可以快速制作出一个不错的APP,智能窗户APP界面如图

在这里插入图片描述

六、成品展示

最后是激动人心的时刻,来吧,先上一张实物图
在这里插入图片描述

【智能窗户已完结】基于STM32的智能窗户已完结,来吧展示,喜欢的三连


有需要的可以加VX:HGbishe

版权声明:本文为CSDN博主「HG电子设计」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/HG_dianzi/article/details/122331478

生成海报
点赞 0

HG电子设计

我还没有学会写个人说明!

暂无评论

相关推荐

2022寒假自学蓝桥杯嵌入式

2022寒假自学蓝桥杯嵌入式 欢近似从0开始准备2022年4月份省赛 学习记录分享 2022/1/22晚 硬件部分的认识(国信长天) 液晶屏,芯片在液晶屏下 电源选择跳线 下载调试文件接口

STM32使用各种传感器的demo

各种传感器的demo 最近有假期有空整理了一些传感器的使用方式 激光测距 激光测距是我在完成电磁炮项目用的模块,大家也可以去借鉴我以前的文章,使用起来也是方便,当时涂方便,利用的是串口