语音模块 SU-03T
这是一个非特定人语音识别模块,也就是不用针对指定发音人的识别技术,这种语音识别技术不分年龄、性别,只要发音人说的是相同的语言就可以识别。的模块。这个模块的操作相较于其他语音识别模块更简单,不需要编程或二次开发,只需要通过厂家给的网站配置后即可使用。
配置语音模块
1. 首先,进入生产该模块的厂家所提供的配置网址 智能公元/AI产品零代码平台 然后点击右上角注册登录
2. 点击左侧的“所有产品”,然后点击右上侧的“创建产品”,然后选择“其他产品” -> “纯离线方案” -> "SU-03T" -> “下一步”
3. 配置"GPIO_A25" "GPIO_A26" "GPIO_A27",使其默认输出高电平,目的是通过语音识别模块来改变小车的三种工作模式:
4. 配置唤醒的文字:
5. 配置命令
5.1 先点击基础信息配置命令的内容
5.2 再点击控制详情,分别在xunji; bizhang; gensui后点击“添加控制”:
设置完的界面如下图:
因此,配置的结果就是,唤醒语句分别是“跟随小车”,“避障小车” 和 “循迹小车”,分别对应只有GPIO_A25,GPIO_A26 和 GPIO_A27 为低电平。
7. 点击右上角的发布版本进行保存并发布:
8. 等待SDK生成(大概10-30分钟),生成之后下载SDK下来,然后解压到一个只有英文的目录下:
9. 打开文件夹,点击“image_demo” -> 点击“Hummingbird-M-Update-Tool” -> 点击“UniOneUpdateTool.exe”
根据文档说明,刚开机的模块要更新烧录才可以使用
10. 将SU-03T通过CH340通过串口连接到电脑,根据手册B6接TXD B7接RXD
11. 再次打开第9步的软件,此时已经发现了这个设备,可以进行烧录:
11.1 选择镜像文件,选择刚刚下载的SDK中的bin文件:11.2 将模块的电源拨到OFF状态,然后点击烧录
11.3 再把电源从OFF 拨到 ON(其实和51单片机的烧录很像,就是软件不一样):
等待烧录完成
此时语音模块就配置好了!如果接入单片机,就可以通过代码实现对模式的控制了!
语音模块实现效果
1. 开机播报“欢迎使用"
1. 当说出“你好小美”或“小智小智”可以唤醒模块,模块回复“我在”或“你说”
2. 当超过10s没有指令或说出“退下”时,模块会进入休眠模式,并回复“有需要再叫我”
3. 当说出“循迹小车”时,模块回复“循迹模式”,并只将GPIO_A27拉低
4. 当说出“避障小车”时,模块回复“壁障模式”,并只将GPIO_A26拉低
5. 当说出“跟随小车”时,模块回复“跟随模式”,并只将GPIO_A25拉低
最终整合
将语音模块接入小车,并移植整合循迹;跟随;避障和显示的代码,实现最终的效果!
(但是由于避障小车的舵机和测距传感器各用了一个定时器,而C52一共就两个定时器,所以两轮分别调速和速度的测量和蓝牙控制(需要串口中断)就无法同时实现了,但如果使用更高级的板子,有5个及以上的定时器的话,其实把调速和速度测量和蓝牙串口控制的代码也一起移植过来就可以,也很简单。)
HC-SR04.c
#include <reg52.h>
#include "delay.h"
sbit Trig = P1^5;
sbit Echo = P1^6;
void Time1_Init()
{
TMOD &= 0x0F; //设置定时器模式
TMOD |= 0x10; //设置定时器模式
TH1 = 0;
TL1 = 0;
//设置定时器1工作模式1,初始值设定为0开始数数,不着急启动定时器
}
void start_HC()
{
Trig = 0;
Trig = 1;
Delay10us();
Trig = 0;
}
double get_distance()
{
double time;
//定时器清零,以便下一次测距用
TH1 = 0;
TL1 = 0;
//1.Trig,给Trig端口至少10us的高电平
Delay200ms();
start_HC();
//2.由低电平跳转到高电平,表示开始发送波
while(Echo == 0);
//波发出去的那一下,开始启动定时器
TR1 = 1;
//3.由高电平跳转回低电平,表示波回来了
while(Echo == 1);
//波回来的那一下,我们停止定时器
TR1 = 0;
//4。计算出之间经过多少时间
time = (TH1 * 256 + TH1) * 1.085;//单位是us
//5.距离 = 速度 (340m/s)*时间/2
return (0.017 * time); //340m/s = 34000cm/s = 34cm/ms = 0.034/us
}
SG90.c
#include <reg52.h>
#include "delay.h"
sbit sg90_con = P1^1;
sbit D5 = P3^7;//根据原理图(电路图),设备变量led1指向P3组IO口的第7口
sbit D6 = P3^6;//根据原理图(电路图),设备变量led2指向P3组IO口的第6口
int cnt = 0;
int angle = 1;
void Time0_Init()
{
//1.配置定时器0工作模式为16位计时
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式
//2.给初值,定一个500us=0.5ms出来
TL0 = 0x33; //设置定时初始值
TH0 = 0xFE;
//3、开始计时
TR0 = 1;
TF0 = 0;
//4.打开定时器0中断 ET0
ET0 = 1;
//5.打开总中断EA
EA = 1;
}
void Init_sg90_0()
{
angle = 1; //初始角度是零度,0.5ms溢出一次,高电平
//舵机角度控制:1:0°;2:45°;3:90°;4.135°;5.180°
cnt = 0;
sg90_con = 1;
}
void Light_open_state()
{
D5 = 0;
D6 = 1;
}
void Light_close_state()
{
D5 = 1;
D6 = 0;
}
void SG_middle()
{
angle = 3;//90度,1.5ms高电平
cnt = 0;
}
void SG_left()
{
angle = 5;//180度,1.5ms高电平
cnt = 0;
}
void SG_right()
{
angle = 1;//0度,0.5ms高电平
cnt = 0;
}
void Time0_Handler() interrupt 1
{
/*
// if(TF0 == 1)//当爆表的时候,硬件会修改bit5(TF0)位上面的数据,改成1(置1),向cpu请求中断
// {
// TF0 = 0;//不用中断,我们代码清零
使用了中断,直接清零了的*/
cnt++;//统计爆表的次数
//重新给初值
TL0 = 0x33;
TH0 = 0xFE;
//控制pwm波形
if(cnt < angle)//角度
{
sg90_con = 1;
}
else
{
sg90_con = 0;
}
if(cnt == 40)//爆表40次,经过了20ms
{
cnt = 0;//当40次表示20ms,重新让cnt从0开始,计算下一次的20ms
sg90_con = 1;
}
//}
}
#include "reg52.h"
sbit RightconlA = P3^6; //B-1A
sbit RightconlB = P3^3; //B-1B
sbit LeftconlA = P3^4; //A-1A
sbit LeftconlB = P3^5; //A-1B
void Motor_back()
{
RightconlA = 1;
RightconlB = 0;
LeftconlA = 1;
LeftconlB = 0;
}
void Motor_front()
{
RightconlA = 0;
RightconlB = 1;
LeftconlA = 0;
LeftconlB = 1;
}
void Motor_Left()
{
RightconlA = 0;
RightconlB = 1;
LeftconlA = 0;
LeftconlB = 0;
}
void Motor_Right()
{
RightconlA = 0;
RightconlB = 0;
LeftconlA = 0;
LeftconlB = 1;
}
void Motor_Stop()
{
RightconlA = 0;
RightconlB = 0;
LeftconlA = 0;
LeftconlB = 0;
}
main.c
#include <reg52.h>
#include "HC-SR04.h"
#include "delay.h"
#include "SG90.h"
#include "motor.h"
#include "oled.h"
//测距小于10cm,D5亮,D6灭;反之现象相反
#define middle 0
#define left 1
#define right 2
#define BZ 1
#define GS 2
#define XJ 3
//循迹
sbit Left_SensorX = P2^4;
sbit Right_SensorX = P2^5;
//跟随
sbit Left_SensorG = P2^4;
sbit Right_SensorG = P2^5;
//语音识别
sbit A25 = P1^5;
sbit A26 = P1^6;
sbit A27 = P1^7;
char dir;
double disMiddle;
double disLeft;
double disRight;
void xunji_mode()
{
if(Left_SensorX == 0 && Right_SensorX == 0)
{
Motor_front();//前
}
Delay1000ms();
if(Left_SensorX == 1 && Right_SensorX == 0)
{
Motor_Left();//左转
}
Delay1000ms();
if(Left_SensorX == 0 && Right_SensorX == 1)
{
Motor_Right();//右转
}
Delay1000ms();
if(Left_SensorX == 1 && Right_SensorX == 1)
{
Motor_Stop();
}
}
void gensui_mode()
{
if(Left_SensorG == 0 && Right_SensorG == 0)
{
Motor_front();//前
}
Delay1000ms();
if(Left_SensorG == 1 && Right_SensorG == 0)
{
Motor_Right();//右转
}
Delay1000ms();
if(Left_SensorG == 0 && Right_SensorG == 1)
{
Motor_Left();//左转
}
Delay1000ms();
if(Left_SensorG == 1 && Right_SensorG == 1)
{
Motor_Stop();
}
}
void bizhang_mode()
{
if(dir != middle)
{
SG_middle();
dir = middle;
Delay450ms();
}
disMiddle = get_distance();
if(disMiddle > 35)//前进
{
Motor_front();
}
else if(disMiddle < 10)
{
Motor_back();
// Delay200ms();
// Motor_Stop();
}
else
{
//停止
Motor_Stop();
//测左边距离
SG_left();
Delay450ms();
disLeft = get_distance();
SG_middle();
Delay450ms();
//测右边距离
SG_right();
Delay450ms();
dir = right;
disRight = get_distance();
if(disRight > disLeft)
{
Motor_Right();
Delay200ms();
Motor_Stop();
}
else
{
Motor_Left();
Delay200ms();
Motor_Stop();
}
}
}
void main()
{
int mark;
Time1_Init();
Time0_Init();
Init_sg90_0();
SG_middle();
Delay2000ms();
dir = middle;
OLED_Init();
OLED_Clear();
Oled_Show_Str(2,2,"----Ready----");
while(1)//
{
//满足循迹模式
if(A25 == 1 && A26 == 1 && A27 == 0)
{
if(mark != XJ){
OLED_Clear();
Oled_Show_Str(2,2,"----xunji----");
}
mark = XJ;
xunji_mode();
}
//满足跟随模式
if(A25 == 0 && A26 == 1 && A27 == 1)
{
if(mark != GS){
OLED_Clear();
Oled_Show_Str(2,2,"----gensui----");
}
mark = GS;
gensui_mode();
}
//满足避障模式
if(A25 == 1 && A26 == 0 && A27 == 1)
{
if(mark != BZ){
OLED_Clear();
Oled_Show_Str(2,2,"----bizhang----");
}
mark = BZ;
bizhang_mode();
}
if(A25 == 1 && A26 == 0 && A27 == 1)
{
if(mark != BZ && mark != GS && mark != XJ){
OLED_Clear();
Oled_Show_Str(2,2,"----stop----");
}
Motor_Stop();
}
}
}