智能家具系统分为两个不同版本系列:
①系列一:手机app远程控制、远程检测温湿度显示在app,(云平台)!!!! https://blog.csdn.net/m0_59113542/article/details/123737710
②系列二:语音识别控制-------本文章
硬件采购链接:
一、项目介绍
功能:离线语音识别模块SU-03T识别到我们不同的语音命令,改变不同引脚电平的状态,stm32读取引脚电平状态,完成相关的外设驱动。
本系统采用的SU-03T 是一款低成本、低功耗、小体积的离线语音识别模组,能快速应用于智能家 居。
目前市面上多用LD3320语音识别模块,这里先说一下我们为什么SU-03T,而不采用LD3320。
①:LD3320淘宝价格120左右, SU-03T淘宝价格20左右
②:LD3320是c语音编程, SU-03T刷词条,只需简单配置
(这个各有各的好处,c语言编程,麻烦但是比较灵活,,,刷词条,简单,但是有一定的局限性)
③:识别率:!!!!!!!!!!!最重要的一点!!!!!!!!!!
语音识别,玩的不就是识别率吗
虽然现在用LD3320的比较多,但是它的语音识别率。emmm........还真的不敢恭维,我第一次用的时候,怎么喊都不管用,还以为是硬件坏了,捣鼓了一下午才发现,你得慢慢的说,语速得很慢。比如:打~~开~~灯~~光~~,这这这这......
而SU-03T,虽然便宜,但是很神奇,其识别率真的YYDS。
这个时候肯定有人不信了,说:“啊,,这人是不是商家的托啊,怎么可能便宜的还好用”!!本人还真不是托,只是一个踩过多次坑的孩子。我劝大家去淘宝买家秀看看,别看卖家秀,看买家秀!!!!!!!!!!!!LD3320很多买家秀都喊两次才能识别,而SU-03T离很远却能识别!!!!!神奇!!!!!
二、项目原理
智能家具吗,我们不可能真的去改造家里的家具(有钱的当我没说,楼主是很穷),所以我们采用模拟的方式,用单步电机加上一条履带模拟窗帘,舵机模拟开关门,LED灯模拟家里的灯,风扇.....大家还可以发挥想象,加一些其他的外设。
接下来就是各个外设的驱动: 首先是语音识别模块:SU-03T,可以初始化引脚电平,假如说为低吧,当识别到语音的时候可拉高电平,将stm32的某些引脚设置为下拉输入模式,与SU-03T的引脚相连,这不就完成了吗,,so easy。
舵机是用PWM控制角度的,PWM不同的占空比对应不同的角度。
步进电机在前面的文章有详细的讲解及代码 链接:步进电机的原理及驱动
LED、与风扇就不多说了,无非就是将GPIO的输出高 输出低的问题!
三、程序实现
Servo_motor.c 舵机驱动
#include "Servo_motor.h"
#include "delay.h"
//高级定时器1pwm输出初始化
//arr:自动重装值(周期) psc:时钟预分频数
void tim1_pwmInit(uint16_t arr, uint16_t psc)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); // 使能定时器1的外设时钟
RCC_APB2PeriphClockCmd(TIM1_CH1_GPIO_CLK, ENABLE); //使能GPIO外设时钟使能
//设置该引脚为复用输出功能,输出TIM1 CH1的PWM脉冲波形
GPIO_InitStructure.GPIO_Pin = TIM1_CH1_PIN; //TIM_CH1
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(TIM1_CH1_PORT, &GPIO_InitStructure);
TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 80K
TIM_TimeBaseStructure.TIM_Prescaler = psc; //设置用来作为TIMx时钟频率除数的预分频值 不分频(预分频系数,如系统时钟为72Mhz,psc为7199,则分频后为72M/(7199+1)=10k ~~~0.1ms,,也就是说一个周期0.1ms,,,,在×arr就得到定时时间了)
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
//TIM_OCInitStructure.TIM_Pulse = 0; //设置待装入捕获比较寄存器的脉冲值(占空比)
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性:TIM输出比较极性低
TIM_OC1Init(TIM1, &TIM_OCInitStructure); //根据TIM_OCInitStruct中指定的参数初始化外设TIMx
TIM_CtrlPWMOutputs(TIM1,ENABLE); //MOE 主输出使能
TIM_Cmd(TIM1, ENABLE); //使能TIM1
}
void servo_init(void)
{
tim1_pwmInit(SERVO_TIM_ARR,SERVO_TIM_PSC);
TIM_SetCompare1(TIM1,150); //使舵机恢复到中间位置
}
//0.5ms--0° 2.5ms--180°
void servo_angle(uint16_t angle)
{
uint16_t pulse;
//针对舵机可转角度限辐
if(angle <= 5)
angle = 5;
if(angle >= 175)
angle = 175;
//将角度值转换为脉冲值
pulse = (uint16_t)(50 + angle * 100/90.0); //此转换公式需根据pwm的arr及psc配置来做相应变化
TIM_SetCompare1(TIM1, pulse);
}
void servo_debug(void)
{
uint8_t i;
for(i = 0; i < 10; ++i)
{
delay_ms(500);
servo_angle(80); //中间位置
delay_ms(500);
servo_angle(175);
}
}
Servo_motor.h
#ifndef __Servo_motor_H
#define __Servo_motor_H
#include "stm32f10x.h"
// 72M / (719 + 1) = 0.1M 故记一个数的时间为10us 定时周期:(1999 + 1) * 10us = 20ms
#define SERVO_TIM_ARR 1999
#define SERVO_TIM_PSC 719
#define TIM1_CH1_GPIO_CLK RCC_APB2Periph_GPIOA
#define TIM1_CH1_PORT GPIOA
#define TIM1_CH1_PIN GPIO_Pin_8
void servo_init(void);
void servo_angle(uint16_t angle);
void servo_debug(void);
void tim1_pwmInit(uint16_t arr, uint16_t psc);
#endif //__TIMER_H
ASR.c语音识别
#include "ASR.h"
//初始化PB5和PE5为输出口.并使能这两个口的时钟
//LED IO初始化
void ASR_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(ASR_LED_CLK, ENABLE); //使能PG端口时钟
GPIO_InitStructure.GPIO_Pin = ASR_LED_PIN |ASR_FS_PIN |ASR_stepper_motor_PIN |ASR_Servo_motor_PIN; //PA.1、PA.2 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //输入下拉
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz
GPIO_Init(ASR_LED_PORT, &GPIO_InitStructure);
GPIO_ResetBits(ASR_LED_PORT, ASR_LED_PIN);
GPIO_ResetBits(ASR_FS_PORT, ASR_FS_PIN);
GPIO_ResetBits(ASR_stepper_motor_PORT, ASR_stepper_motor_PIN);
GPIO_ResetBits(ASR_Servo_motor_PORT, ASR_Servo_motor_PIN);
}
ASR.h
#ifndef __ASR_H
#define __ASR_H
#include "sys.h"
//led
#define ASR_LED_PIN GPIO_Pin_1
#define ASR_LED_PORT GPIOA
#define ASR_LED_CLK RCC_APB2Periph_GPIOA
//风扇
#define ASR_FS_PIN GPIO_Pin_2
#define ASR_FS_PORT GPIOA
#define ASR_FS_CLK RCC_APB2Periph_GPIOA
//步进电机(窗帘)
#define ASR_stepper_motor_PIN GPIO_Pin_3
#define ASR_stepper_motor_PORT GPIOA
#define ASR_stepper_motor_CLK RCC_APB2Periph_GPIOA
//开关门
#define ASR_Servo_motor_PIN GPIO_Pin_4
#define ASR_Servo_motor_PORT GPIOA
#define ASR_Servo_motor_CLK RCC_APB2Periph_GPIO4
#define LED_read PAin(1)// PA1
#define FS_read PAin(2)// PA2
#define BJ_read PAin(3)// PB3
#define KM_read PAin(4)// PB4
void ASR_Init(void);//初始化
#endif
main.c
#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "usart.h"
#include "step_motor.h"
#include "Servo_motor.h"
#include "ASR.h"
int main(void)
{
static u8 BJ_flag;
delay_init(); //延时函数初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
uart_init(9600); //串口初始化为115200
ASR_Init();
LED_Init(); //LED端口初始化
KEY_Init(); //初始化与按键连接的硬件接口
servo_init();
Step_Motor_GPIO_Init();
servo_angle(80); //私服电机初始角度(关门状态)
//STEP_MOTOR_OFF();
while(1)
{
//判断语音开关灯
if(LED_read == 1)
{
LED0=0; //开灯
LED1=1;
}
else
{
LED0=1; //关灯
LED1=0;
}
//语音判断开关风扇
if(FS_read == 1)
{
FS=1;
}
else
{
FS=0;
}
//判断语音开关窗帘
if((BJ_read == 1)&&(BJ_flag == 0))
{
motorNcircle(64,(bool)1); //步进电机正传
BJ_flag=1;
}
else if((BJ_read == 0)&&(BJ_flag == 1))
{
//STEP_MOTOR_OFF();
motorNcircle(64,(bool)0); //步进电机反传
BJ_flag=0;
}
//判断语音开关门
if(KM_read == 1)
{
servo_angle(175);
delay_ms(500);
}
else
{
servo_angle(80);
delay_ms(500);
}
}
}
步进电机的程序就不在这里重复了,上面那个链接里有。
完整工程链接:AI智能语音识别模块离线语音控制模块语音识别芯片声控模块SU-03T-淘宝网 (taobao.com)
欢迎大家指正交流,有空可以一起讨论代码啊。
制作不易,感谢大家支持,感谢!!!!!!
--------------一个正在努力的人