tzlzy 发表于 2014-7-28 10:13:45

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:01:12

本帖最后由 洛水一梦24 于 2016-5-17 23:06 编辑

楼主,您好,我问一下,如果我想做一个语音控制的蓝牙小车,也是和您的这个例子一样,只不过我要用的是arduino UNO+语音识别扩展板作为手持端,小车另一端作为接收端,两个arduinoUNO的板子各连一个蓝牙,使用串口通信,可使我们老师说串口连通后相当于一条线联通,在不需要其他改变,那么我想知道,如果我做小车的话,如果只是想让它进行简单的左右前后转向,是不是就可以参照您的语音控制的智能小车的例子,如果我不播放音乐等,那么我应该把程序的哪里修改一下,因为您的程序里手持端和小车端程序我不是太懂,能麻烦您告知一下吗?看您身份像老师,能麻烦您在百忙总解答一下吗?另外我还需要一份voice的库,您能发我邮箱吗?1099608789@qq.com
另外,我用的老是显示编译不对,后来才知道是库不对。您百忙之中看一看可以吗?

DFSH_Faith 发表于 2018-8-20 16:31:43

本帖最后由 DFSH_Faith 于 2018-8-20 16:33 编辑

本教程中的接线图出现了一些问题,代码中的10和11软串口控制电机,硬串口连接MP3,但接线图画反了。
页: [1]
查看完整版本: Bluno+4WD语音控制小车