文章目录
- 一、项目简介
- 二、项目组成
- 三、原理图设计
- 四、源码设计
- 五、小程序设计
- 六、成品展示
- 七、数据获取与联系
一、项目简介
到目前为止,我们的生活中有很多物联网设备,如智能空调、智能台灯、智能窗户、智能窗帘、智能汽车等。今天,我们将为您带来一个基于微信applet控制的智能家居系统。该系统实现自动控制、手动控制和远程控制,并可安装语音控制。 本系统的主要功能如下: 开关窗帘(亮度范围0~100,亮度>70开窗帘,亮度<=70关窗帘,步进电机模拟开关窗帘) ⑩所有执行器都可以通过手动按键本地控制 ?使用微信小程序显示环境数据 ?执行器通过微信小程序控制
你认为有很多功能吗?这是对的。你学的功能越多,锻炼的就越多。 本项目将制作万用板版本和两个版本PCB版本
二、项目组成
先上图 PCB版本 万用板版本元器件
(万用板散件使用的几个模块已经修改,图中没有列出) 看完图,再来看看系统的组成部分: 万用板 ①STM32F103C8T6最小系统板1 ②DHT11温湿度传感器1 ③MQ-2烟雾浓度传感器1 ④光敏电阻传感器1 ⑤热释电人体红外传感器1 ⑥OLED显示屏1 ⑦ESP82661 转接板 ⑧L298N1 ⑨蜂鸣器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 "infoh"
#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) //如果数据指针不为空,则代表收到了数