【STM32单片机】智能窗帘控制系统
本项目基于STM32F103C8T6单片机设计了一套智能窗帘控制系统,通过多种传感器和模块实现自动化控制。系统采用DHT11采集温湿度,光敏传感器检测光照强度,OLED显示实时数据和工作状态。支持自动和手动两种模式:自动模式下根据预设的温度和光照阈值智能控制窗帘开关;手动模式下可通过按键、蓝牙APP或语音指令("打开窗帘"/"关闭窗帘")操作。系统还提供阈值
一、功能简介
本项目使用STM32F103C8T6单片机控制器,使用HC05/06蓝牙模块、IIC OLED液晶、DHT11温湿度传感器、按键模块、ASRONE语音识别模块、
光敏传感器模块、有源蜂鸣器模块、28BYJ48步进电机模块等。
主要功能:
系统运行后,OLED液晶显示当前检测温湿度、工作模式、光线强度、温度和光线阈值、
窗帘开关状态;系统默认处于自动控制模式,可通过K4键选择自动/手动
控制模式;在自动控制模式下,可通过K3键进入阈值设置界面,可设置光线强度和
温度阈值,K3键切换阈值位置,K1和K2调节,K4确认退出;
如果检测温度在温度阈值范围内,光线低于下限,窗帘打开,高于上限窗帘关闭。
如果温度高于温度上限,则打开窗帘,温度低于温度下限,则关闭窗帘。
在手动模式下,可通过K1键手动开关窗帘;同时还可以通过手机蓝牙app控制
窗帘开关以及工作模式;手动模式既可按键控制,也可语音控制;
在语音模式下,可通过语音“小智”唤醒语音模块,通过指令“打开窗帘”、“关闭窗帘”
进行控制;
蓝牙控制命令
#define LY_KEY1_VALUE 0X01
#define LY_KEY2_VALUE 0X02
#define LY_KEY3_VALUE 0X03
#define LY_KEY4_VALUE 0X04
二、软件设计
/*
作者:嗨小易(QQ技术交流群:570487280)
*/
//系统数据获取
void sys_data_get(void)
{
while(1)
{
//获取环境温湿度
DHT11_Read_Data(&sys_ctrl.temp,&sys_ctrl.humi);
//获取光照强度
sys_ctrl.light=99-Get_ADC_Value(ADC_Channel_9,5)/41;
break;
}
}
//系统数据显示
void sys_data_show(void)
{
static u8 i=0;
while(1)
{
//正常模式显示
if(sys_ctrl.mode==0)
{
//温度
OLED_ShowNum(16*2+8,16,sys_ctrl.temp,2,16);
//温度阈值
OLED_ShowxNum(16*2+8*6,16,sys_ctrl.templ,2,16,0,1);
OLED_ShowxNum(16*2+8*9,16,sys_ctrl.temph,2,16,0,1);
//湿度
OLED_ShowNum(16*2+8,32,sys_ctrl.humi,2,16);
//窗帘开关标志
if(sys_ctrl.onoff==0)OLED_ShowFontHZ(16*4+8,32,17,16,1);
else OLED_ShowFontHZ(16*4+8,32,16,16,1);
//自动手动模式
if(sys_ctrl.auto_flag==0)
{
//自动
OLED_ShowFontHZ(16*6,32,13,16,1);
OLED_ShowFontHZ(16*7,32,15,16,1);
}
else
{
//手动
OLED_ShowFontHZ(16*6,32,14,16,1);
OLED_ShowFontHZ(16*7,32,15,16,1);
}
//光线
OLED_ShowNum(16*2+8,48,sys_ctrl.light,2,16);
//光线阈值
OLED_ShowxNum(16*2+8*6,48,sys_ctrl.lightl,2,16,0,1);
OLED_ShowxNum(16*2+8*9,48,sys_ctrl.lighth,2,16,0,1);
//将数据传输到蓝牙
i++;
if(i%10==0)
{
u3_printf("\r\n温度:%d°C 湿度:%d%%\r\n",sys_ctrl.temp,sys_ctrl.humi);
u3_printf("光线:%d%%\r\n",sys_ctrl.light);
if(sys_ctrl.onoff==0)u3_printf("窗帘:关\r\n");
else u3_printf("窗帘:开\r\n");
if(sys_ctrl.auto_flag==0)u3_printf("模式:自动\r\n");
else u3_printf("模式:手动\r\n");
}
}
//参数设置模式显示
else
{
switch(sys_ctrl.mode)
{
case 1://温度下
OLED_ShowxNum(16*2+8*9,48,sys_ctrl.lighth,2,16,0,1);
OLED_ShowxNum(16*2+8*6,16,sys_ctrl.templ,2,16,0,0);
break;
case 2://温度上
OLED_ShowxNum(16*2+8*6,16,sys_ctrl.templ,2,16,0,1);
OLED_ShowxNum(16*2+8*9,16,sys_ctrl.temph,2,16,0,0);
break;
case 3://光线下
OLED_ShowxNum(16*2+8*9,16,sys_ctrl.temph,2,16,0,1);
OLED_ShowxNum(16*2+8*6,48,sys_ctrl.lightl,2,16,0,0);
break;
case 4://光线上
OLED_ShowxNum(16*2+8*6,48,sys_ctrl.lightl,2,16,0,1);
OLED_ShowxNum(16*2+8*9,48,sys_ctrl.lighth,2,16,0,0);
break;
}
}
OLED_Refresh_Gram();//刷新显示缓存
break;
}
}
//系统数据设置
void sys_data_set(void)
{
u8 key=0;
key=KEY_Scan(0);
if(key!=0)BEEP_Alarm(2,2000);
//设置
if(key==KEY3_PRESS || USART3_RX_BUF[0]==LY_KEY3_VALUE)
{
sys_ctrl.mode++;
if(sys_ctrl.mode>4)sys_ctrl.mode=1;
}
//加
else if(key==KEY1_PRESS || USART3_RX_BUF[0]==LY_KEY1_VALUE)
{
switch(sys_ctrl.mode)
{
case 1://温度下限
sys_ctrl.templ++;
if(sys_ctrl.templ>99)sys_ctrl.templ=0;
break;
case 2://温度上限
sys_ctrl.temph++;
if(sys_ctrl.temph>99)sys_ctrl.temph=0;
break;
case 3://光线下限
sys_ctrl.lightl++;
if(sys_ctrl.lightl>99)sys_ctrl.lightl=0;
break;
case 4://光线上限
sys_ctrl.lighth++;
if(sys_ctrl.lighth>99)sys_ctrl.lighth=0;
break;
}
}
//减
else if(key==KEY2_PRESS || USART3_RX_BUF[0]==LY_KEY2_VALUE)
{
switch(sys_ctrl.mode)
{
case 1://温度下限
sys_ctrl.templ--;
if(sys_ctrl.templ<0)sys_ctrl.templ=99;
break;
case 2://温度上限
sys_ctrl.temph--;
if(sys_ctrl.temph<0)sys_ctrl.temph=99;
break;
case 3://光线下限
sys_ctrl.lightl--;
if(sys_ctrl.lightl<0)sys_ctrl.lightl=99;
break;
case 4://光线上限
sys_ctrl.lighth--;
if(sys_ctrl.lighth<0)sys_ctrl.lighth=99;
break;
}
}
//确定
else if(key==KEY4_PRESS || USART3_RX_BUF[0]==LY_KEY4_VALUE)
{
if(sys_ctrl.mode!=0)sys_ctrl.mode=0;
else sys_ctrl.auto_flag=!sys_ctrl.auto_flag;
}
//手动模式
if(sys_ctrl.auto_flag==1)
{
//窗帘开关
if(key==KEY1_PRESS || USART3_RX_BUF[0]==LY_KEY1_VALUE)
{
sys_ctrl.onoff=!sys_ctrl.onoff;
}
}
if(USART3_RX_BUF[0]!=0)USART3_RX_BUF[0]=0;
}
//系统功能控制
void sys_fun_ctrl(void)
{
static u8 oneflag=0;
//自动模式
if(sys_ctrl.auto_flag==0)
{
//如果温度高于上限值,打开窗帘
if(sys_ctrl.temp>sys_ctrl.temph)
{
sys_ctrl.onoff=1;
}
//如果温度低于下限,关闭窗帘
else if(sys_ctrl.temp<sys_ctrl.templ)
{
sys_ctrl.onoff=0;
}
//如果在阈值范围内
else
{
//光线高于上限,关闭窗帘
if(sys_ctrl.light>sys_ctrl.lighth)
{
sys_ctrl.onoff=0;
}
//光线低于下限,打开窗帘
else if(sys_ctrl.light<sys_ctrl.lightl)
{
sys_ctrl.onoff=1;
}
}
}
//语音识别模块控制
switch(USART2_RX_BUF[0])
{
case 0x01://自动模式
sys_ctrl.auto_flag=0;
break;
case 0x02://手动模式
sys_ctrl.auto_flag=1;
break;
case 0x09://语音模式
sys_ctrl.auto_flag=1;
break;
}
//手动模式控制
if(sys_ctrl.auto_flag==1)
{
switch(USART2_RX_BUF[0])
{
case 0x03://打开窗帘
sys_ctrl.onoff=1;
break;
case 0x04://关闭窗帘
sys_ctrl.onoff=0;
break;
}
}
if(USART2_RX_BUF[0]!=0)USART2_RX_BUF[0]=0;
//原本关闭窗帘,开窗帘
if(sys_ctrl.onoff==1)
{
if(oneflag==0)
{
oneflag=1;
Step_Motor_Run(8,sys_ctrl.onoff,STEPMOTOR_MAXSPEED,180,1);
}
}
//原本打开窗帘,关闭窗帘
else
{
if(oneflag==1)
{
oneflag=0;
Step_Motor_Run(8,sys_ctrl.onoff,STEPMOTOR_MAXSPEED,180,1);
}
}
}
三、实验现象
B站演示视频:https://space.bilibili.com/444388619

联系作者
视频地址:https://space.bilibili.com/444388619/video
专注于51单片机、STM32、国产32、DSP、Proteus、arduino、ESP32、物联网软件开发,PCB设计,视频分享,技术交流。
火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。
更多推荐
所有评论(0)