请选择 进入手机版|继续访问电脑版
返回列表 发新帖回复

语音识别、XBee、无线遥控与乐高智能车

[复制链接] 【【【进入图片模式】】】
  • TA的每日心情
    慵懒
    2017-6-13 09:31
  • 3

    主题

    3

    帖子

    51

    积分

    初级学士

    Rank: 2

    积分
    51
    发表在  2017-12-25 15:04:17  | 显示全部楼层 | 阅读模式
        我喜欢逐步把问题搞清楚,慢慢来,急不得,一个个知识点去实践。

       这篇文章所介绍的作品任务是:发布语音命令给遥控器主机,遥控器上有语音识别模块,它识别出语音命令,并处理成相应单字符标志,并及时把单字符通过XBee无线通讯,以RS232串口协议传送给从机控制器,从机控制器再根据这些单字符标志,控制乐高智能车的三个舵机,完成小车前后左右行走和机械手抓放物体的动作。从任务描述看,作品体现出四个关键词:语音识别、XBee、无线遥控、乐高智能车。

    语音识别、XBee、无线遥控与乐高智能车

    语音识别、XBee、无线遥控与乐高智能车

       用的时候,把上图右边的XBee传感器扩展板层叠到右侧的语音识别模块上。
    工作视频:

    遥控器主机任务是:当发出人声,前进"qian jin",后退"hou tui",左转"zuo zhuan",右转"you zhuan",抓起"zhua qi",放下"fang xia",停止"ting zhi"时,通过语音识别模块处理后,无线串口通信,向上位机分别发送单字符标志,'a','b'、'c'、'd'、'f'、'g'、's'。
    主机遥控器程序:(程序中关键程序段,我用红色字体标注)
    向Arduino控制器“写”程序前,先把XBee模块从控制器的XBee专门接口上拔下来,否则程序无法“写”入,“写”完程序后,再插上XBee模块。
    #include "Voice.h" //申明语音识别库文件
    #define SUM 7 //定义待识别的单词数量
    uint8  nAsrStatus=0; //申明语音模块工作状态
    //定义识别单词“拼音”内容的数组
    char sRecog[SUM][80] =
    {"qian jin","hou tui","zuo zhuan","you zhuan","zhua qi","fang xia","ting zhi"};
    char flag;//定义向上位机发送字符命令的变量
    //根据单词数组的元素号,执行相应命令
    void finally (unsigned char n)
    {
       switch(n)
    {
        case 0:
         flag='a';//小车前进
         Serial.print(flag);              
        break;
        case 1:
         flag='b'; //小车后退
                  Serial.print(flag);              
         break;
            case 2:
         flag='c'; //小车左转
                  Serial.print(flag);
                   break;
            case 3:
         flag='d'; //小车右转
                  Serial.print(flag);
                   break;
            case 4:
         flag='f';//机械手抓起
                  Serial.print(flag);
                   break;
            case 5:
         flag='g';//机械手放下
                  Serial.print(flag);
                   break;
            case 6:
         flag='s'; //小车停止
                  Serial.print(flag);
                   break;
          default:         
                  flag='e';
                  Serial.print(flag);
                    break;        
    }
    }
    //识别到声音,产生一个触发中断
    void ExtInt0Handler ()
    {
      Voice.ProcessInt0();//执行中断服务子程序
    }
    //初始化
    void setup()
    {
      Serial.begin(115200);//串行通信启动
      Voice.Initialise(MIC);//初始化语音模块
      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:
    {
                                    //Serial.print( "ASR_FOUN ONE: ");
                                   //提取所识别到的单词是数组的第几个元素
                                    nAsrRes =Voice. LD_GetResult();
                                    //根据数组元素号,执行相应命令
                                    finally(nAsrRes);
                                  nAsrStatus = LD_ASR_NONE;
                                   break;
    }
    //识别到单词“不是”设定单词
    case LD_ASR_FOUNDZERO:
                            {
                              //Serial.println( "ASR_FOUND ZERO");
                              nAsrStatus = LD_ASR_NONE;
                              break;
                            }
    default:
                          {
                            nAsrStatus = LD_ASR_NONE;
                            break;
                            }
    }// switch
       delay(10);
    }// while
    }

        从机控制器任务是:当接收到主机遥控器发送来的单字符命令,'a','b'、'c'、'd'、'f'、'g'、's'时,通过从机控制器处理后,驱动小车的两个舵机和机械手的一个舵机,完成前进,后退,左转,右转,抓起,放下,停止的动作。
    从机控制器程序:(程序中关键程序段,我用红色字体标注)

    #include "Servo.h"  //声明舵机函数库
    Servo controlservo;  // 定义机械手舵机对象变量
    Servo rightservo;  // 定义小车右车轮舵机对象变量
    Servo leftservo;  // 定义小车左车轮舵机对象变量
    int power1=80;//定义360°旋转舵机功率变量和初始化设置
    int power2=10;
    int val;   //存储从机接受主机发送的单字节命令的变量
    //初始化
    void setup()
    {
       Serial.begin(115200);//设置串行通信的波特率,启动串行通信   
       controlservo.attach(3); //定义3号数字量引脚来控制机械手舵机
       rightservo.attach(9);  //定义9号数字量引脚来控制小车右舵机
       leftservo.attach(10); //定义10号数字量引脚来控制小车左舵机
       //连续旋转的舵机, 执行myservo.write(90),舵机的速度可能不为0,
       //我手头的舵机,执行myservo.write(93),舵机的速度才为0。
       controlservo.write(93);//初始化三个舵机为停止状态
       rightservo.write(93);
       leftservo.write(93);
    }
    //主程序
    void loop()
    {
      if(Serial.available()>0) //查询串口有无数据
      {
            val=Serial.read();//读取主机发送的字符
             if(val=='a')//如果主机发送字符为'a'
            {
              //小车前进
               rightservo.write(93+power1);
               leftservo.write(93-power1);
               controlservo.write(93);        
            }
            if(val=='b')//如果主机发送字符为'b'
            {
              //小车后退
               rightservo.write(93-power1);
               leftservo.write(93+power1);
               controlservo.write(93);           
            }
            if(val=='c')//如果主机发送字符为'c'
            {
               //小车左转
               rightservo.write(93-power2);
               leftservo.write(93-power2);
               controlservo.write(93);                     
            }
            if(val=='d')//如果主机发送字符为'd'
            {
               //小车右转
               rightservo.write(93+power2);
               leftservo.write(93+power2);
               controlservo.write(93);         
            }
            if(val=='f')//如果主机发送字符为'e'
            {
               //机械手抓取物体
                controlservo.write(180);  
                rightservo.write(93);
                leftservo.write(93);         
            }
            if(val=='g')//如果主机发送字符为'f'
            {
                //机械手松开物体
                controlservo.write(0);
                rightservo.write(93);
                leftservo.write(93);           
            }
            if(val=='s')//如果主机发送字符为'n'
            {
              //所有舵机停止
              controlservo.write(93);  
              rightservo.write(93);
              leftservo.write(93);        
            }      
      }     
    }



    回复

    使用道具 举报

    发表回复

    您需要登录后才可以回帖 登录 | 立即注册 新浪微博登陆

    本版积分规则

    发表新帖 客服
    微信

    微信公众号

    微信二维码
    最优秀的创意分享平台

    客户端

    移动端

    手机端二维码
    扫码立即穿越至手机

    回到顶部
    快速回复 返回顶部 返回列表