Bluno+4WD语音控制小车
本帖最后由 tzlzy 于 2014-7-28 15:45 编辑好吧,楼主带着她的语音控制小车又来啦。吼吼吼~~~先简单介绍一下吧。Bluno和语音识别扩展板作为手持端,功能嘛,无非是语音识别扩展板对外界输入的语音进行识别,而Bluno自带的蓝牙则负责将识别到并且经过处理的信息发送到小车端。4WD小车、Uno主控板、mp3播放模块,小喇叭,以及ble link蓝牙4.0通讯模块一起组成了小车端。功能也是很明确的,mp3负责播放,语音指令啦,唱歌啦,讲故事啦,看我们的心情罗,小喇叭当然不用说,蓝牙负责与手持端进行通讯,将收到的信息发送给Uno进行处理。还可以给我们的小车加上一些传感器,LED等等,相信也是一件有意思的事情。楼主这里就不一一赘述了。
器材:
*******************我是手持端的分割线*************
Bluno扩展板 *1
语音识别扩展板 *1
*******************我是小车端的分割线*************
4WD小车 *1
UnoR3主控板 *1
Ble Link蓝牙4.0 *1
MP3播放模块 *1
小喇叭 *1
第一部分:手持端
1.硬件搭建
将Bluno办卡与语音识别扩展板插叠在一起。就像下面这样:
2.程序编写
语音识别扩展板的教程中是有样例代码的,可以查看使用教程。我在之前的一篇语音控制小车的帖子中也具体讲过。这里就不再累述。这个帖子跟之前的那个最大的区别在于分为了手持端和小车端,两者通过蓝牙通信,所以主要也是对一些做了改变的地方做一些说明。先看代码。
#include <Voice.h>
#define SUM 10 //SUM识别关键词的个数,最大不超过50个
uint8nAsrStatus=0;
char sRecog = {"qian jin", "hou tui","zuo zhuan", "you zhuan","ting zhi","chang ge","zan ting bo","ji xu bo","xia yi shou","shang yi shou"};//每个关键词拼音字母个数不超过79个,用户可以自行修改
void finally (unsigned char n)
{
switch(n)//n为数组中对应关键词的序列号,例如数组sRecog中的第一个关键词为“kai deng”则对应的序列号为0;
{
case 0:
Serial.println("0");
break;
case 1:
Serial.println("1");
break;
case 2:
Serial.println("2");
break;
case 3:
Serial.println("3");
break;
case 4:
Serial.println("4");
break;
case 5:
Serial.println("5");
break;
case 6:
Serial.println("6");
break;
case 7:
Serial.println( "7");
break;
case 8:
Serial.println( "8");
break;
case 9:
Serial.println( "9");
break;
default:
Serial.println( "error");
Serial.println( " ");
break;
}
}
void ExtInt0Handler ()
{
Voice.ProcessInt0(); //芯片送出中断信号
}
void setup()
{
Serial.begin(9600);
Voice.Initialise(MIC,VoiceRecognitionV1);//Initialise mode MIC or MONO,default is MIC
//VoiceRecognitionV1 is VoiceRecognitionV1.0 shield
//VoiceRecognitionV2 is VoiceRecognitionV2.1 module
attachInterrupt(0,ExtInt0Handler,LOW);
}
void loop()
{
uint8 nAsrRes;
nAsrStatus = LD_ASR_NONE;
while(1)
{
switch(nAsrStatus)
{
case LD_ASR_RUNING:
case LD_ASR_ERROR:
break;
case LD_ASR_NONE:
{
nAsrStatus=LD_ASR_RUNING;
if (Voice.RunASR(SUM,80,sRecog)==0)//识别不正确
{
nAsrStatus= LD_ASR_ERROR;
Serial.println( "ASR_ERROR");
}
Serial.println( "ASR_RUNING.....");
break;
}
case LD_ASR_FOUNDOK:
{
nAsrRes =Voice. LD_GetResult();//一次ASR识别流程结束,去取ASR识别结果
finally(nAsrRes);
nAsrStatus = LD_ASR_NONE;
break;
}
case LD_ASR_FOUNDZERO:
default:
{
nAsrStatus = LD_ASR_NONE;
break;
}
}// switch
delay(500);
}// while
} 主要说一下finaly函数,它与上面的sRecog相对应,当然里面的”qian jin“、”hou tui“等可以自行根据需要修改。这里的意思是,当语音识别模块检测到”qian jin“,会返回数值”0“,我们没有对这个“0”作处理,只将返回的这个0打印出来,为后面的手持端与小车端的通信作铺垫。
第二部分:小车端
1.硬件搭建
step 1:将UNO R3固定在4WD小车上;
step 2:将mp3播放模块与小喇叭连起来,5V接在Uno的5V插孔上,GND接GND,RX接Uno的TX针脚,TX接Uno的Rx针脚;
step 3:将mp3播放模块与Uno办板卡连接起来(MP3模块使用的SD卡要求是1G的);
step 4:将Ble Link安在4WD小车上,因为使用了蓝牙,所以得将4WD上面的RX、TX连接在Uno的RX、TX上,但是因为Uno自身的RX、TX针脚已经被mp3模块占用了,所以我们这里使用的是软串口,假设使用数字针脚10和11作为RX、TX,因此,将4WD自带的RX、TX针脚分别接在UNO数字针脚10、11上。连线图如下:
2.程序编写小车端的程序编写主要是比较简单,先贴代码:#include <SoftwareSerial.h>
int E1 = 5; //M1 Speed Control
int E2 = 6; //M2 Speed Control
int M1 = 4; //M1 Direction Control
int M2 = 7; //M1 Direction Control
char a;
SoftwareSerial mySerial(10, 11) ; //RX,TX
void stop(void) //Stop
{
digitalWrite(E1,0);
digitalWrite(E2,0);
}
void advance(char a,char b) //Move forward
{
analogWrite (E1,a); //PWM Speed Control
digitalWrite(M1,HIGH);
analogWrite (E2,b);
digitalWrite(M2,HIGH);
}
void back_off (char a,char b) //Move backward
{
analogWrite (E1,a);
digitalWrite(M1,LOW);
analogWrite (E2,b);
digitalWrite(M2,LOW);
}
void turn_L (char a,char b) //Turn Left
{
analogWrite (E1,a);
digitalWrite(M1,LOW);
analogWrite (E2,b);
digitalWrite(M2,HIGH);
}
void turn_R (char a,char b) //Turn Right
{
analogWrite (E1,a);
digitalWrite(M1,HIGH);
analogWrite (E2,b);
digitalWrite(M2,LOW);
}
void setup(void)
{
int i;
for(i=4;i<=7;i++)
pinMode(i, OUTPUT);
mySerial.begin(9600); //Set Baud Rate
Serial.begin(19200); //Set Baud Rate
delay(2000);//等待2秒钟播放器初始化完成
Serial.println("\\:v 255");
delay(50);
}
void loop()
{
if ( mySerial.available())
{
a = mySerial.read();
{
switch(a)
{
case '0':
Serial.println("qian");
Serial.println("\\qian");
advance (255,255);
break;
case '1': Serial.println("\\hou");
back_off (255,255);
break;
case '2': Serial.println("\\zuo");
turn_L (100,100);
break;
case '3': Serial.println("\\you");
turn_R (100,100); ;
break;
case '4': Serial.println("\\zhi");
stop();
break;
case '5': Serial.println("\\bo");
Serial.println("\\2");
break;
case '6': Serial.println("\\:p");
break;
case '7': Serial.println("\\:s");
break;
case '8': Serial.println("\\:n");
break;
case '9': Serial.println("\\:u");
break;
default:break;
}
}
}
}
说明一下:首先是加了一个软串口mySerial,定义数字针脚10和11为RX,TX,这个软串口是用来使用ble link与bluno手持端通信的。主函数里面主要是指当我们的蓝牙收到相应的数据以后做出的反应。比如收到“0”,小车播放前进指令,并且调用advance()函数向前进。这里,主要完成了小车前进、后退、左转、右转、停止、播放歌曲等功能。
第三部分:手持端和小车端的通信。 这里主要是通过蓝牙通信,我们要配置一下蓝牙。
1.将其设置成一主一从。相关AT指令如下:
AT+ROLE=ROLE_CENTRAL<CR+LF>设置BLE工作在主机状态下
AT+ROLE=ROLE_PERIPHERAL<CR+LF> 设置BLE工作在从机状态下
AT+ROLE=?<CR+LF> 查询当前BLE芯片的主从机状态。 (默认值为ROLE_PERIPHERAL)
2.绑定制定mac。
如果有多人在使用蓝牙,为了避免自己的蓝牙与其他人的蓝牙连接上了,造成干扰,可以给其绑定mac地址。绑定Mac地址以及查询自身mac地址的AT指如下:
(1) "AT+BIND" 设置BLE芯片绑定蓝牙地址
AT+BIND=0x0017ea9397e1<CR+LF> 设置BLE芯片绑定的蓝牙地址为0x0017ea9397e1
AT+BIND=?<CR+LF> 查询当前BLE芯片绑定蓝牙地址。 默认值为0x000000000000
(2)"AT+CMODE" 设置BLE芯片连接模式
AT+CMODE=UNIQUE<CR+LF> 设置连接模式为指定蓝牙地址连接模式(指定蓝牙地址由BIND命令设置,见"AT+BIND" )
AT+CMODE=ANYONE<CR+LF> 设置连接模式为任意蓝牙地址连接模式(不受BIND命令设置地址的约束,见"AT+BIND")
AT+CMODE=?<CR+LF> 查询当前BLE芯片连接模式。 默认值为ANYONE
(3)"AT+MAC"查询BLE芯片MAC地址
AT+MAC=?<CR+LF> 查询当前BLE芯片MAC地址
蓝牙详细使用教程请点击链接,查看其使用教程。 通电以后,过段时间,bluno和ble link将会连接上,此时,两者的Link灯会点亮,表示可以正常通信了。此时,我们手持Bluno,对着语音识别模块的Mic说出相应的指令,小车会执行相应的动作啦。
本帖最后由 洛水一梦24 于 2016-5-17 23:06 编辑
楼主,您好,我问一下,如果我想做一个语音控制的蓝牙小车,也是和您的这个例子一样,只不过我要用的是arduino UNO+语音识别扩展板作为手持端,小车另一端作为接收端,两个arduinoUNO的板子各连一个蓝牙,使用串口通信,可使我们老师说串口连通后相当于一条线联通,在不需要其他改变,那么我想知道,如果我做小车的话,如果只是想让它进行简单的左右前后转向,是不是就可以参照您的语音控制的智能小车的例子,如果我不播放音乐等,那么我应该把程序的哪里修改一下,因为您的程序里手持端和小车端程序我不是太懂,能麻烦您告知一下吗?看您身份像老师,能麻烦您在百忙总解答一下吗?另外我还需要一份voice的库,您能发我邮箱吗?1099608789@qq.com
另外,我用的老是显示编译不对,后来才知道是库不对。您百忙之中看一看可以吗?
本帖最后由 DFSH_Faith 于 2018-8-20 16:33 编辑
本教程中的接线图出现了一些问题,代码中的10和11软串口控制电机,硬串口连接MP3,但接线图画反了。
页:
[1]