
开源协议
:GPL 3.0
描述
* 设计要求与指标
技术要求
(1)雨滴传感器模块:用于检测雨滴;
(2)光线强度传感器模块:用于检测光线强度;
(3)红外接收模块和蓝牙模块,用于遥控控制;
(4)步进电机模块:用于窗户窗帘驱动。
技术指标
(1)可以通过红外\蓝牙遥控与语音设置是否打开自动模式;
(2)在自动模式下,当光照强度很高时,自动展开窗帘;当光照强度很低时,自动关闭窗帘;
(3)在自动模式下,当检测到大量雨滴时,自动展开窗帘,此优先级比光照检测高;
(4)在任何时候,可以通过红外\蓝牙遥控或语音命令展开与关闭窗帘,并关闭自动模式;
(5)主控芯片接收到数据后,驱动电机运转,现实智能窗帘窗户系统。
* 实物图片
* 电路设计
主控电路
电源电路
对应实物
1. 雨滴检测电路
对应实物
2. 光照检测电路
对应实物
3. 红外接收电路
对应实物
4. 蓝牙控制电路
对应实物
5. 语音控制电路
对应实物
烧录
通过官方的教程配置语音识别固件后,使用软件HLK-M-Updata-Tool和硬件ch340下载器进行烧录
- 连线,断开5V-GND
这里GND选择雨滴传感器的GND接口
- 打开烧录工具,选择需要烧录的文件【.bin】
- 点击烧录
4. 连接5V-GND,这里是插入跳线帽,等待烧录完成
6. 步进电机驱动电路
对应实物
* PCB绘制
* 程序设计
主函数
主要变量
#define Rain_Value_Max 42
#define Light_Value_Max 60
#define Light_Value_Min 10
#define ADC_Max 4095
#define Motor_Step_Max 597
#define Motor_Step_Min 2
uint8_t Mode_Flag = 1;//0-auto 1-mamual
uint16_t Rain_New = 0;
uint16_t Light_New = 0;
unsigned char voice_buff[4][5] =
{
{0xaa,0x55,0x01,0x55,0xaa},//当前为自动模式
{0xaa,0x55,0x02,0x55,0xaa},//当前为手动模式
{0xaa,0x55,0x03,0x55,0xaa},//窗帘已打开
{0xaa,0x55,0x04,0x55,0xaa} //窗帘已关闭
};
int main(void)
{
nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2); //优先级分组
systick_config(); //滴答定时器初始化
usart_gpio_config(9600U); //串口0 => PC
usart_2_gpio_config(9600U); //串口2 <= other device
hlk_usart_init(9600U); //串口1 语音识别模块引脚初始化
raindrop_and_light_config(); //ADC2 PF6 PF8初始化
stepper_motor_config(); //步进电机初始化
stepper_motor_timer_config(); //步进电机 定时器5初始化
infrared_goio_config(); //红外接收初始化
Curtain_Reset(); //窗帘复位
while(1)
{
//自动模式
Auto_Mode();
//手动模式
Manual_Mode();
}
}
自动模式
void Auto_Mode(void)
{
if(Mode_Flag == 0)//自动模式
{
//获取最新雨滴数据
Rain_New = (1-(float)Get_ADC_Value(BSP_RAINDROP_ADC_CHANNEL)/ADC_Max)*100;
//获取最新光照数据
Light_New = (1-(float)Get_ADC_Value(BSP_LIGHT_ADC_CHANNEL)/ADC_Max)*100;
if(Rain_New >= Rain_Value_Max)
{
//打开窗帘
Curtain_Open();
}
else
{
if(Light_New >= Light_Value_Max)
{
//打开窗帘
Curtain_Open();
}
else if(Light_New <= Light_Value_Min)
{
//关闭窗帘
Curtain_Close();
}
}
}
}
手动模式
{
//红外遥控操作
Read_Infrared();
//语音识别操作
voice_anakysis_data();
//蓝牙遥控操作
BlueTeeth_Ctrol();
}
红外遥控函数
红外遥控按键值
/*
【CH-】:0xa2 【CH】 :0x62 【CH+】 :0xe2
【<<】 :0x22 【>>】 :0x02 【>|】 :0xc2
【-】 :0xe0 【+】 :0xa8 【EQ】 :0x90
【0】 :0x68 【100+】:0xa8 【200+】:0xb0
【1】 :0x30 【2】 :0x18 【3】 :0x7a
【4】 :0x10 【5】 :0x38 【6】 :0x5a
【7】 :0x42 【8】 :0x4a 【9】 :0x52
*/
void Read_Infrared(void)
{
if(get_infrared_command() != 0)
{
switch(get_infrared_command())
{
case 0x22://【<<】 打开窗帘
Curtain_Open();
hlk_usart_send_hex(voice_buff[2],5);
break;
case 0x02://【>>】 关闭窗帘
Curtain_Close();
hlk_usart_send_hex(voice_buff[3],5);
break;
case 0xe0://【-】 自动模式
hlk_usart_send_hex(voice_buff[0],5);
Mode_Flag = 0;
break;
case 0xa8://【+】 手动模式
hlk_usart_send_hex(voice_buff[1],5);
Mode_Flag = 1;
break;
}
//步进电机限位判断
Motor_Stop_Judgement(step_count);
clear_infrared_command();
}
}
语音识别函数
unsigned char voice_anakysis_data(void)
{
unsigned char ret = 0;
if( rx_flag == 1 )//接收到语音命令
{
rx_flag = 0;
switch( rx_data )//根据语音命令确定对应的动作
{
case 0x01://开窗帘
Mode_Flag = 1;
Curtain_Open();
break;
case 0x02://关窗帘
Mode_Flag = 1;
Curtain_Close();
break;
case 0x03://自动模式
Mode_Flag = 0;
break;
case 0x04://手动模式
Mode_Flag = 1;
break;
}
ret = 1;
//清除当前数据
clear_hlk_rx_buff();
}
//步进电机限位判断
Motor_Stop_Judgement(step_count);
return ret;
}
蓝牙遥控函数
void BlueTeeth_Ctrol(void)
{
if(g_recv_complete_flag)
{
g_recv_complete_flag = 0;
if(g_recv_buff[0] == '0')
{
Curtain_Open();//打开窗帘
Mode_Flag = 1;//手动模式
}
if(g_recv_buff[0] == '1')
{
Curtain_Reset();//打开窗帘
Mode_Flag = 1;//手动模式
}
if(g_recv_buff[0] == '2')
{
Mode_Flag = 1;//手动模式
}
if(g_recv_buff[0] == '3')
{
Mode_Flag = 0;//自动模式
}
memset(g_recv_buff,0,g_recv_length);
g_recv_length = 0;
}
}
步进电机相关函数
/* 模式选择 0 => 顺时针 1 => 逆时针 2 => 停止 */
void Motor_Mode(uint8_t mode)
{
if(mode == 0)
{
//开启顺时针旋转
motor_cw_flag = 1;
motor_ccw_flag = 0;
}
else if(mode == 1)
{
//开启逆时针旋转
motor_cw_flag = 0;
motor_ccw_flag = 1;
}
else
{
//停止
motor_cw_flag = 0;
motor_ccw_flag = 0;
Motor_Stop();
}
}
/*窗帘复位*/
void Curtain_Reset(void)
{
//当步数没有达到599时,那么步数++到599
while(step_count < Motor_Step_Max)
{
Motor_Mode_Flag = 0;
}
motor_ccw_flag = 0;
Motor_Stop();
}
/*窗帘打开*/
void Curtain_Open(void)
{
if(step_count>Motor_Step_Min)
{
step_count = Motor_Step_Max;
Motor_Mode_Flag = 1;
}
else
{
Motor_Mode_Flag = 2;
}
}
/*窗帘关闭*/
void Curtain_Close(void)
{
if(step_count < Motor_Step_Max)
{
Motor_Mode_Flag = 0;
}
else
{
Motor_Mode_Flag = 2;
}
}
/*步进电机停止判断*/
void Motor_Stop_Judgement(int num)
{
if(motor_cw_flag == 1)
{
if(num >= Motor_Step_Max)
{
motor_ccw_flag = 0;
Motor_Stop();
}
}
if(motor_ccw_flag == 1)
{
if(num <= 0)
{
motor_cw_flag = 0;
Motor_Stop();
}
}
}
完整代码见附件
演示视频
https://www.bilibili.com/video/BV19N411H7nu/
存在的问题
- PCB绘制时,一对40P排母放错位置。解决:用杜邦线连接扩展版排母与梁山派开发板排针相应的引脚,更改了实物整体的高度
2. ...
设计图

BOM


评论