目录
🤞大家好,这里是5132单片机毕设设计项目分享,今天给大家分享的是基于STM32的智能语音远程窗户控制系统。
随着科技的不断发展,智能化已经渗透到了人们的生活中的方方面面。智能家居作为智能化的重要组成部分,已经成为了人们生活中不可或缺的一部分。在这个大环境下促成了智能家居技术的诞生和发展,而智能窗户也就由此诞生了。所谓的智能窗户就是不同于传统的窗户,通过系统的控制它能够实时地保护人们生命财产安全。智能窗户作为智能家居的一种重要形式,能够实现自动开关、智能感光和远程控制等功能,为人们的生活带来了极大的便利。
设备的详细功能见网盘:
链接:https://pan.baidu.com/s/1uWSZX2zbZwy9sYwwnvyktQ?pwd=5132
提取码:5132
1、设计要求
自动模式通过光敏传感器采集光照强度,再利用光照强度变化控制步进电机进而控制窗户的开启与关闭,并在OLED显示屏实时光照强度。语音模式通过语音识别模块识别用户意图再利用步进电机精准控制窗户开闭。远程模式通过手机APP实现一键控制窗户,并且可以查看窗户状态和室内光线。当窗户出现故障蜂鸣器会进行报警。除此之外还设置了手动模式,提供更加多元的窗户开闭方式。
2、系统功能
1.语音识别模块。语音识别模块核心芯片采LD3320芯片,是一种非特定人“语音识别”专用芯片。通“开窗”和“关窗”等关键语句实现对窗帘的语音控制 。
2.ESP8266-01Wifi模块。通过本模块单片机系统可以连接到机智云,手机APP就可以远程控制窗户的开关。
3.光控模块。利用光控模块,可以根据日常需求自行设定室内光照度,通过光敏电阻实时监测室外光照度,单片机控制窗帘开合实现室内恒照度控制。窗帘实现光照度自动控制,天亮窗帘自动打开,室外光照度超过设定值自动关闭,天黑窗帘自动关闭。
4.步进电动机驱动模块。单片机控制步进电动机驱动模块给电动机输入一系列脉冲信号,控制电动机连续转动,带动窗帘运行。当步进驱动器接收到一个脉冲信号时,它就驱动步进电动机按设定的方向转动,通过输出连续脉冲信号控制窗帘的连续移动。
5.时钟模块。利用时钟振荡电路产生时钟信号。单片机时钟可以提供一个固定的时钟频率,用于同步和控制各个模块的操作。通过时钟信号的控制,可以确保单片机系统中各个模块按照一定的时间序列进行操作,从而实现定时功能。
6.OLED显示模块。OLED显示模块采用0.96寸液晶显示屏,该模块用来实时显示室外光照度数据及窗帘工作状态
7. 按键模块。按键模块用来控制模式选择和控制窗帘的开启与关闭。
8. 蜂鸣器模块。设备出现故障用来报警。
手动 |
通过一个按键控制窗户的开启与关闭 |
自动 |
通过光敏传感器采集的光照强度和设定的阈值控制窗户的开启与关闭 |
定时 |
通过设定的时间和实时时间比较,控制窗户的开启与关闭 |
语音 |
识别用户的语音窗户的开启与关闭, |
3、演示视频和实物
D22-基于STM32的智能语音远程窗户控制系统
4、系统设计框图
在本设计中,硬件上以STM32F103C8T6为主控制元件,使用光敏传感器、ESP8266-01S和LD3320A语音传感器分别进行光照强度控制、远程控制和用户语音控制,将其连接到单片机 I/O口,由于光敏传感器是读取模拟量的,所以需要进行模数转换,转换后可以读出光照强度。LD3320A通过串口和单片机通信,利用ULN2003芯片对所测得的数据进行处理,将其与预设的阈值进行对比,然后利用ULN2003芯片对电机进行驱动控制,实现了对窗户的开启和关闭,
5、软件设计流程图
6、原理图和PCB图
7、主程序
#include "stm32f10x.h" // 有需求的,可以联系VX:lwfw123456789
#include <stdio.h>
#include <string.h>
#include "sys.h"
#include "delay.h"
#include "OLED.h"
#include "Key.h"
#include "OLED.h"
#include "Serial.h"
#include "LED.h"
#include "Buzzer.h"
#include "AD.h"
#include "bjdj.h"
#include "Serial2.h"
#include "string.h"
#include "dht11.h"
#include "MyRTC.h"
#define Num_i 256 //电机步数
uint16_t RTC_Time1[] = {7, 0, 0}; //3个定时时间
uint16_t RTC_Time2[] = {11, 0, 0};
uint16_t RTC_Time3[] = {19, 0, 0};
uint16_t AD0, AD1, AD2, AD3; //存储ADC的值
uint8_t KeyNum; //存储按键值
uint8_t RxData; //蓝牙接收到的数据
uint32_t bufe[2];
float temp1; //adc转换值
u8 temp, humi;
u8 t = 0; //温湿度读取值的间隔
u32 guang; //存储AD模拟值转换为电压的值
u8 state = 1; //模式切换
u8 state1 = 1; //手动模式下窗帘控制
u8 state2 = 1; //自动模式下,阈值调节切换
u8 state2_1, state2_2;
u8 GuangYu_1 = 50; //光照强度阈值下限
u8 GuangYu_2 = 80; //光照强度阈值上限
u8 Flag_dakai = 0;
void ctrlue()
{
u16 ii = 0;
if (guang > GuangYu_2 && Flag_dakai == 0) //
{
for (ii = 0; ii < Num_i; ii++)
{
Motorcw_angle(1, 3);
MotorStop();
}
Flag_dakai = 1; // 窗户打开了
OLED_ShowChinese(4, 4, 12); // kai
}
if (guang < GuangYu_1 && Flag_dakai == 1)
{
for (ii = 0; ii < Num_i; ii++)
{
Motorccw_angle(1, 3);
MotorStop();
}
Flag_dakai = 0;
OLED_ShowChinese(4, 4, 13); // guan
}
if ((guang < GuangYu_1) && Flag_dakai == 1) //光照强度小于下限,窗户开,或者大于上限,窗户关,就是故障报警
{
Buzzer_ON();
}
if ((guang > GuangYu_2) && Flag_dakai == 0)
{
Buzzer_ON();
}
if (KeyNum == 2)
{
delay_ms(20);
if (KeyNum == 2)
{
state2_1++;
if (state2_1 > 1)
{
state2_1 = 0;
}
}
}
if (state2_1 == 0)
{
if (KeyNum == 4) GuangYu_1++;
if (KeyNum == 3) GuangYu_1--;
}
if (state2_1 == 1)
{
if (KeyNum == 4) GuangYu_2++;
if (KeyNum == 3) GuangYu_2--;
}
}
void shoudong()
{
u16 ii = 0;
if (KeyNum == 2)
{
delay_ms(20);
if (KeyNum == 2)
{
state2++;
if (state2 > 1)
{
state2 = 0;
}
}
}
if (state2 == 0)
{
if (Flag_dakai == 0)
{
for (ii = 0; ii < Num_i; ii++)
{
Motorcw_angle(1, 3);
MotorStop();
}
Flag_dakai = 1; // 窗户打开了
OLED_ShowChinese(4, 4, 12); // 开
}
}
if (state2 == 1)
{
if (Flag_dakai == 1)
{
for (ii = 0; ii < Num_i; ii++)
{
Motorccw_angle(1, 3);
MotorStop();
}
Flag_dakai = 0;
OLED_ShowChinese(4, 4, 13);
}
}
}
void YuYingMode()
{
u16 ii = 0;
if (Serial2_RxFlag == 1) //串口接收到数据包的标志位,若是收到数据包,会置1
{
if ((strcmp(Serial2_RxPacket, "LIAN_OFF") == 0)&&(Flag_dakai == 0) )//比较接收到的字符串是否和对应指令的字符串相等。(需要增加string头文件)
{
for (ii = 0; ii < Num_i; ii++)
{
Motorcw_angle(1, 3);
MotorStop();
}
Flag_dakai = 1; // 窗户打开了
OLED_ShowChinese(4, 4, 12); // 开
}
else if ((strcmp(Serial2_RxPacket, "LIAN_ON") == 0)&&(Flag_dakai ==1) )
{
for (ii = 0; ii < Num_i; ii++)
{
Motorccw_angle(1, 3);
MotorStop();
}
Flag_dakai = 0;
OLED_ShowChinese(4, 4, 13);
}
Serial2_RxFlag = 0; //将标志位清零,不清零就接收不到下一个数据包了
}
}
void DingShiMode()
{
u16 ii = 0;
if ((MyRTC_Time[3] == RTC_Time1[0]) && (MyRTC_Time[4] == RTC_Time1[1]) && (MyRTC_Time[5] == RTC_Time1[2])) //打开窗帘时间
{
if (Flag_dakai == 0)
{
for (ii = 0; ii < Num_i; ii++)
{
Motorcw_angle(1, 3);
MotorStop();
}
Flag_dakai = 1; // 窗户打开了
OLED_ShowChinese(4, 4, 12); // 开
}
}
if ((MyRTC_Time[3] == RTC_Time3[0]) && (MyRTC_Time[4] == RTC_Time3[1]) && (MyRTC_Time[5] == RTC_Time3[2])) //关闭窗帘时间
{
if (Flag_dakai == 1)
{
for (ii = 0; ii < Num_i; ii++)
{
Motorccw_angle(1, 3);
MotorStop();
}
Flag_dakai = 0;
OLED_ShowChinese(4, 4, 13);
}
}
//...............................修改定时时间..................................../
if (KeyNum == 2)
{
delay_ms(20);
if (KeyNum == 2)
{
state2_2++;
if (state2_2 > 3)
{
state2_2 = 0;
}
}
}
if (state2_2 == 0) //开时
{
if (KeyNum == 4) RTC_Time1[0]++;
if (KeyNum == 3) RTC_Time1[0]--;
}
if (state2_2 == 1)//开分
{
if (KeyNum == 4) RTC_Time1[1]++;
if (KeyNum == 3) RTC_Time1[1]--;
}
if (state2_2 == 2)//关时
{
if (KeyNum == 4) RTC_Time3[0]++;
if (KeyNum == 3) RTC_Time3[0]--;
}
if (state2_2 == 3)//关分
{
if (KeyNum == 4) RTC_Time3[1]++;
if (KeyNum == 3) RTC_Time3[1]--;
}
}
int main(void) //主函数
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); // 设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
delay_init(); //延时函数初始化
SystemInit();
Key_Init(); //按键初始化
LED_Init();
AD_Init();
OLED_Init();
Buzzer_Init();
Moto_Init();
// MyRTC_Init();
OLED_ShowString(1, 5, "XX:XX:XX");
OLED_ShowChinese(2, 1, 16); //窗帘状态
OLED_ShowChinese(2, 2, 39);
OLED_ShowString(2, 5, ":");
OLED_ShowChinese(4, 1, 44); //窗帘状态
OLED_ShowChinese(4, 2, 63);
OLED_ShowString(4, 5, ":");
OLED_ShowChinese(4, 4, 13); // 关
Serial_Init(); //串口1初始化(蓝牙)
Serial2_Init(); //串口2初始化(语音)
// Buzzer_Turn(); //设备上电响一下
// delay_ms(1000);
while (1)
{
LED1_ON(); //上电指示灯
// MyRTC_ReadTime();
// OLED_ShowNum(1, 5, MyRTC_Time[3], 2);
// OLED_ShowNum(1, 8, MyRTC_Time[4], 2);
// OLED_ShowNum(1, 11, MyRTC_Time[5], 2);
if (t % 10 == 0) //每100ms读取一次
{
AD0 = AD_GetValue(ADC_Channel_0); //光照强度传感器 PA0
if (AD0 > 4000)AD0 = 4000;
guang = (u8)(100 - (AD0 / 40));
OLED_ShowNum(2, 6, guang, 2);
OLED_ShowString(2, 8, "%");
}
delay_ms(10);
t++;
KeyNum = Key_GetNum(); //模式选择
if (KeyNum == 1)
{
delay_ms(20);
if (KeyNum == 1)
{
state1++;
if (state1 > 3)
{
state1 = 0;
}
}
}
if (state1 == 1)
{
ctrlue(); // 自动模式
OLED_ShowChinese(4, 7, 30);
OLED_ShowChinese(4, 8 , 31);
}
if (state1 == 3)
{
shoudong(); //手动模式
OLED_ShowChinese(4, 7, 29);
OLED_ShowChinese(4, 8, 31);
}
if (state1 == 2)
{
YuYingMode(); //语音模式
OLED_ShowChinese(4, 7, 54);
OLED_ShowChinese(4, 8, 55);
}
if (state1 == 0)
{
DingShiMode(); //定时模式
OLED_ShowChinese(4, 7, 59);
OLED_ShowChinese(4, 8, 60);
}
OLED_ShowChinese(3, 1, 61);
OLED_ShowString(3, 3, ":");
OLED_ShowNum(3, 4, RTC_Time1[0], 2);
OLED_ShowString(3, 6, ":");
OLED_ShowNum(3, 7, RTC_Time1[1], 2);
OLED_ShowChinese(3, 5, 62);
OLED_ShowString(3, 11, ":");
OLED_ShowNum(3, 12, RTC_Time3[0], 2);
OLED_ShowString(3, 14, ":");
OLED_ShowNum(3, 15, RTC_Time3[1], 2);
OLED_ShowNum(2, 12, GuangYu_1, 2);
OLED_ShowNum(2, 15, GuangYu_2, 2);
}
}
8、总结
设计了一款基于STM32的智能窗户,可以实现四种控制模式:远程模式、自动模式、手动模式和语音模式。