本帖最后由 tzlzy 于 2014-7-28 15:45 编辑
好吧,楼主带着她的语音控制小车又来啦。吼吼吼~~~先简单介绍一下吧。Bluno和语音识别扩展板作为手持端,功能嘛,无非是语音识别扩展板对外界输入的语音进行识别,而Bluno自带的蓝牙则负责将识别到并且经过处理的信息发送到小车端。4WD小车、Uno主控板、mp3播放模块,小喇叭,以及ble link蓝牙4.0通讯模块一起组成了小车端。功能也是很明确的,mp3负责播放,语音指令啦,唱歌啦,讲故事啦,看我们的心情罗,小喇叭当然不用说,蓝牙负责与手持端进行通讯,将收到的信息发送给Uno进行处理。还可以给我们的小车加上一些传感器,LED等等,相信也是一件有意思的事情。楼主这里就不一一赘述了。
器材:
*******************我是手持端的分割线*************
Bluno扩展板 *1
语音识别扩展板 *1
*******************我是小车端的分割线*************
4WD小车 *1
Uno R3主控板 *1
Ble Link蓝牙4.0 *1
MP3播放模块 *1
小喇叭 *1
第一部分:手持端
1.硬件搭建
将Bluno办卡与语音识别扩展板插叠在一起。就像下面这样:
2.程序编写
语音识别扩展板的教程中是有样例代码的,可以查看使用教程。我在之前的一篇语音控制小车的帖子中也具体讲过。这里就不再累述。这个帖子跟之前的那个最大的区别在于分为了手持端和小车端,两者通过蓝牙通信,所以主要也是对一些做了改变的地方做一些说明。先看代码。
- #include <Voice.h>
- #define SUM 10 //SUM识别关键词的个数,最大不超过50个
- uint8 nAsrStatus=0;
- char sRecog[SUM][80] = {"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说出相应的指令,小车会执行相应的动作啦。
|