【毕业设计】基于单片机微信小程序智能家居控制系统


项目视频
哔哩哔哩视频链接:
1.项目开题
2.原理图讲解
3.程序讲解
3-1OLED显示
3-2独立按键的使用
3-3蜂鸣器的驱动
3-4温湿度获取
3-5人体红外检测
3-6亮度烟雾传感器检测
3-7步进电机控制
3-8PWM调节LED亮度
3-9本地功能整合
3-10最终代码讲解+成品演示
3-11小程序导入

一、项目简介

至今我们生活中已有许许多多的物联网设备,比如我们的智能空调,智能台灯,智能窗户,智能窗帘,智能汽车等等,今天我们将带给大家一款基于微信小程序控制的智能家居系统,该系统实现了自动控制、手动控制和远程控制,还可以加装语音控制。
我们这个系统主要实现的功能有以下几部分:
①温湿度采集
②烟雾浓度采集
③环境亮度采集
④检测是否有人
⑤OLED显示数据
⑥根据温湿度控制风扇(温度高于30℃打开风扇降温或者湿度大于90%RH打开风扇除湿)
⑦室内烟雾浓度过高,蜂鸣器报警
⑧有人时环境亮度控制灯光的亮暗
⑨根据环境亮度自动开关窗帘(亮度范围0~100,亮度>70开窗帘,亮度<=70关窗帘,开关窗帘使用步进电机模拟)
⑩所有执行器可以通过手动按键本地控制
⑪使用微信小程序显示环境数据
⑫通过微信小程序控制执行器

是不是觉得功能很多,这就对了,功能越多学的也就越多,对自己的锻炼也会多。
此项目我们会做两个版本,万用板版本和PCB版本

二、项目组成

先上图
PCB版本
在这里插入图片描述
万用板版本元器件

(万用板散件使用的有几个模块有修改,图中没列出来)
在这里插入图片描述
看完图后我们再来看一下系统的组成部分:
万用板
①STM32F103C8T6最小系统板1
②DHT11温湿度传感器
1
③MQ-2烟雾浓度传感器1
④光敏电阻传感器
1
⑤热释电人体红外传感器1
⑥OLED显示屏
1
⑦ESP82661+转接板
⑧L298N
1
⑨蜂鸣器1
⑩LED灯
1
⑪风扇1
⑫步进电机驱动+步进电机
1
⑬按键4
⑭万用板
1
⑮HGD01-DC-DC电源模块1
⑯12V电源适配器
1
再附上一张系统组成框图
在这里插入图片描述

三、原理图设计

原理图也分为万用板和PCB版本,需要PDF原版的看文章尾部获取
万用板版本
在这里插入图片描述
PCB版本
在这里插入图片描述

四、源码设计

源码分为单片机源码和小程序源码
具体代码讲解看视频
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 "oled.h"
#include "bmp.h"
#include "adc.h"
#include "lsens.h"
#include "dht11.h"
#include "rthw.h"
#include "pwm.h"
#include "fmq.h"
#include "bjdj.h"
#include "key.h"
//C库
#include <string.h>

	 u8 led_flag=0;
	 u8 fs_flag=0;
	 u8 mode_flag=0;
	 u8 lsens=0;
	 u32 mq2=0;
	 u8 temp=0,humi=0;
	 u16 led_pwm=900;
	 u8 ch_flag=0;
//数据流
DATA_STREAM dataStream[] = {
								{"wendu", &temp, TYPE_UCHAR, 1},
								{"shidu", &humi, TYPE_UCHAR, 1},
								{"led_flag", &led_flag, TYPE_UCHAR, 1},
								{"fs_flag", &fs_flag, TYPE_UCHAR, 1},					
								{"mode_flag", &mode_flag, TYPE_UCHAR, 1},
								{"lsens", &lsens, TYPE_UCHAR, 1},				
								{"mq2", &mq2, TYPE_UINT, 1},
								{"led_pwm", &led_pwm, TYPE_UCHAR, 1},					
								{"ch_flag", &ch_flag, TYPE_UCHAR, 1},
							};
unsigned char dataStreamLen = sizeof(dataStream) / sizeof(dataStream[0]);





/*
************************************************************
*	函数名称:	Hardware_Init
*
*	函数功能:	硬件初始化
*
*	入口参数:	无
*
*	返回参数:	无
*
*	说明:		初始化单片机功能以及外接设备
************************************************************
*/
void Hardware_Init(void)
{
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);								//中断控制器分组设置

}

/*
************************************************************
*	函数名称:	main
*
*	函数功能:	
*
*	入口参数:	无
*
*	返回参数:	0
*
*	说明:		
************************************************************
*/
int main(void)
{
	u16 i;
	unsigned char *dataPtr;
	unsigned int runTime = 0;
	_Bool sendFlag = 0;
	 u8 t=0;	

		SysTick_Init(72);
	 Delay_Init();																//systick初始化	
		Led_Init();																	//LED初始化	
		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
	 OLED_Init();
	 Lsens_Init();
	 DHT11_Init();
	 RTHW_Init();
	 FMQ_Init();
	 BJDJ_Init();
	 KEY_Init();
	 TIM4_PWM_Init(899,0);
		NET_DEVICE_IO_Init();								//网络设备IO初始化
		NET_DEVICE_Reset();									//网络设备复位
		NET_DEVICE_Set_DataMode(DEVICE_CMD_MODE);			//设置为命令收发模式(例如ESP8266要区分AT的返回还是平台下发数据的返回)
	 OLED_ColorTurn(0);//0正常显示,1 反色显示
   OLED_DisplayTurn(0);//0正常显示 1 屏幕翻转显示
	 OLED_ShowChinese(0,0,0,16,1);//温度
	 OLED_ShowChinese(15,0,2,16,1);
	 OLED_ShowChar(30,0,':',16,1);
	 OLED_ShowChinese(60,0,1,16,1);//湿度
	 OLED_ShowChinese(75,0,2,16,1);
	 OLED_ShowChar(90,0,':',16,1);
	 OLED_ShowChinese(0,17,5,16,1);//亮度
	 OLED_ShowChinese(15,17,2,16,1);
	 OLED_ShowChar(30,17,':',16,1);
	 OLED_ShowChinese(60,17,3,16,1);//烟雾
	 OLED_ShowChinese(75,17,4,16,1);
	 OLED_ShowChar(90,17,':',16,1);
	 OLED_ShowChinese(0,34,13,16,1);//窗帘 关
	 OLED_ShowChinese(15,34,14,16,1);
	 OLED_ShowChinese(40,34,16,16,1);
	 OLED_ShowChar(30,34,':',16,1);
	 OLED_ShowChinese(60,34,10,16,1);//风扇 关
	 OLED_ShowChinese(75,34,11,16,1);
	 OLED_ShowChinese(100,34,16,16,1);
	 OLED_ShowChar(90,34,':',16,1);
	 OLED_ShowString(10,49,"LED:",12,1);//灯 0挡
	 OLED_ShowNum(40,49,0,1,12,1);
	 OLED_ShowString(60,49,"PEOPLE:",12,1);//人 无
	 OLED_ShowNum(100,49,0,1,12,1);
	 
	 OLED_Refresh();
	while(1)
	{
			t=KEY_Scan(0);		//按键
			switch(t)
			{				 
				case KEY1_PRES:  //模式切换0自动1手动
						mode_flag=!mode_flag;
				if(mode_flag==1)
				{
					led_pwm=900;
					TIM_SetCompare2(TIM4,led_pwm);
					OLED_ShowNum(40,49,100-led_pwm/9,3,12,1);
				}
					break;
				case KEY2_PRES:
					if(mode_flag==1)
					{
						fs_flag=!fs_flag;
					}
					break;
				case KEY3_PRES:				
					if(mode_flag==1)
					{

							led_pwm=led_pwm-200;
							if(led_pwm<=0||led_pwm>900)
							{
								led_pwm=900;
							}
							 TIM_SetCompare2(TIM4,led_pwm);
							OLED_ShowNum(40,49,100-led_pwm/9,3,12,1);
						
					}
					break;
				case KEY4_PRES:	
				if(mode_flag==1)
				{
					 if(ch_flag==0)//如果窗户关
					 {
								for(i=0;i<150;i++)
								{
									FZ;
								}	
								TZ;
								ch_flag=1;
					 }
					 else
					 {
								for(i=0;i<150;i++)
								{
									ZZ;
								}	
								TZ;
								ch_flag=0;
					 }
				}
					break;
				default:
					delay_ms(10);	
			} 
		 
		 
		 DHT11_Read_Data(&temp,&humi);  //获取湿度
		 OLED_ShowNum(40,0,temp,2,16,1);
		 OLED_ShowNum(100,0,humi,2,16,1);
		 lsens=Lsens_Get_Val();  //获取亮度
		 mq2=Mq2_Get_Val();      //获取烟雾浓度
		 OLED_ShowNum(36,17,lsens,3,16,1);
		 OLED_ShowNum(98,17,mq2,4,16,1);
		 if(mode_flag==0)
		 { 

			 OLED_ShowNum(122,0,0,1,12,1);
			 if(RTHW==1) //有人
			 {
				OLED_ShowNum(100,49,1,1,12,1);
				 led_pwm=lsens*9;
				 TIM_SetCompare2(TIM4,led_pwm);
				 OLED_ShowNum(40,49,100-led_pwm/9,3,12,1);
			 }
			 else
			 {
				TIM_SetCompare2(TIM4,900);
				OLED_ShowNum(100,49,0,1,12,1);
			 }
			 if(temp>30||humi>90)//温度大于30或湿度大于90打开风扇
			 {
					fs_flag=1;
					OLED_ShowChinese(100,34,15,16,1);
			 }
			 else
			 {
					fs_flag=0;
					OLED_ShowChinese(100,34,16,16,1);
			 } 

			 if(ch_flag==0)//如果窗户关
			 {
				 if(lsens>70)//亮度>70开窗帘,<=70关窗帘
				 {
						for(i=0;i<150;i++)
						{
							FZ;
						}	
						TZ;
						ch_flag=1;
				 }
				 else
				 {
						TZ;
				 }
			 }
			 else
			 {
					if(lsens>70)//亮度>70开窗帘,<=70关窗帘
				 {
						TZ;
				 }
				 else
				 {
						for(i=0;i<150;i++)
						{
							ZZ;
						}	
						TZ;
						ch_flag=0;
				 }
			 }
		 }
		 else  //手动
		 {

				OLED_ShowNum(122,0,1,1,12,1);
		 }
			 if(mq2>500)   //烟雾浓度大于00打开蜂鸣器
			 {
					GPIO_SetBits(GPIOB,FMQ);
			 }
			 else
			 {
					GPIO_ResetBits(GPIOB,FMQ);
			 } 
		 if(fs_flag==0)
		 {
				GPIO_ResetBits(GPIOB,FS);
			 OLED_ShowChinese(100,34,16,16,1);
		 }
		 else
		 {
				GPIO_SetBits(GPIOB,FS);
			 OLED_ShowChinese(100,34,15,16,1);
		 }
		 if(ch_flag==0)
		 {
				
				OLED_ShowChinese(40,34,16,16,1);
		 }
		 else
		 {
			
			 	 OLED_ShowChinese(40,34,15,16,1);
		 }
		 OLED_Refresh();


		if(oneNetInfo.netWork == 1)
		{
			OLED_ShowNum(122,49,1,1,12,1);
			 OLED_Refresh();
//		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(122,49,0,1,12,1);
			 OLED_Refresh();
//		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);
	}

}


五、小程序设计

小程序使用小程序开发者工具开发
小程序界面
在这里插入图片描述

六、成品展示

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

微信小程序智能家居最后一讲 程序讲解加成果展示

七、资料获取与联系


关注公众号“HG电子”发送“微信小程序智能家居”可获取PDF版本原理图
在这里插入图片描述
有别的需求也可加我V:HGbishe

  • 8
    点赞
  • 167
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值