LD3320语音识别模块:LDV7模块使用详解

30 篇文章 214 订阅 ¥9.90 ¥99.00

喜欢请关注微信公众号:嵌入式从0到1

公众号内容面向在校大学生、电子爱好者、嵌入式工程师;

涉及电子制作、模块使用、单片机技术、物联网相关知识分享;

软硬件全栈工程师,玩模块,学硬件,带你从0走到1


 
LD3320是非特定人(不用针对指定人)语音识别芯片,即语音声控芯片。最多可以识别50条预先内置的指令。
 
工作模式:
LD3320(LDV7)语音模块可以工作在以下三种模式:
普通模式:直接说话,模块直接识别;
按键模式:按键触发开始ASR进程;
口令模式:需要一级唤醒词(口令);
推荐使用口令模式,这样避免嘈杂环境下误动作。
 
应用场景:
1、家居智能控制
2、智能小车DIY设计
3、毕业设计创新功能
4、个人DIY设计
5、语音控制嵌入式产品设计
 
 
 
 
 
我购买的LDV7语音识别模块,内置单片机,LD3320语音识别芯片的驱动是靠模块上自带的STC11L08单片机驱动的,我们可以修改模块自带工程的Demo程序,修改里面的关键词,然后将识别的结果通过串口打印出来,我们使用另外一个MCU与该模块进行串口通信,解析收到的串口指令,进而做响应的指令动作。
 
例如
我们说口令:当前时间(dang qian shi jian)
》》 模块识别之后,串口输出:PrintCom("{\"VoiceCommandCode\":2}");
》》 MCU接收串口信息之后,对该串口指令进行解析(可以使用cJSON解析此字符串);
》》 然后通过TTS文字转语音模块播放当前时间,即完成本次语音识别控制过程。
 
 
识别原理:
就是你说一句话,然后模块用拼音去和你的发音做比较,在关键词中找出哪些预设值的词语与发音的接近程度大于多少的(假定50%),然后再从一堆大于(50% )里面输出一个最接近的。
 
这里就会造成一个问题,容易造成误识别太多。
如果你只有一个关键词:时间
然后你说了一句:‘时刻’,他识别到‘时’这个发音,所以有50% 以上的相似,但是候选词中没有‘时刻’这个比他更接近的关键词,所以他就会输出‘时间’的结果。这样子他就是错误了。
如果你设置一些拟声词,有可能随随便便就触发了。
 
解决方案:
在设定好要识别的关键词语后,为了进一步降低误识别率,可以再添加一些其他的任意词汇进识别列表,用来吸收错误识别,从而达到降低误识别率的目的。我们把这样一些关键词语称之为“垃圾关键词语”。
 
比如,某个应用场景中,需要识别的关键词语是 4 条,“前进”,“后退”,“开门”,“关门”。在把这 4 个关键词语设置进 LD3320 后,可以再另外设置10~30个词语进LD3320,比如“前门”,“后门”,“阿阿阿”,“呜 呜”等等。 所以最好把一些拟声词或者容易混淆的词语设置为垃圾关键词,即,识别后不进行输出。
 
只有识别结果是 4 个关键词语之内的,才认为识别有效。如果识别结果是 “垃圾关键词语”,则说明是其他的声音导致的误识别,产品应该重新开始一次识别过程。 这样,可以非常有效地降低误识别率。极大地提高终端用户的主观使用体验。
 
移植过程:
 
1、向LD模块中添加关键词
 
 
 
 
/************************************************************************
功能描述: 向LD模块添加关键词
入口参数: none
返 回 值: flag:1->添加成功
其他说明: 用户修改.
                     1、根据如下格式添加拼音关键词,同时注意修改sRecog 和pCode 数组的长度
                     和对应变了k的循环次数设置。拼音串和识别码是一一对应的。
                     2、开发者可以学习"语音识别芯片LD3320高阶秘籍.pdf"中
           关于垃圾词语吸收错误的用法,来提供识别效果。
                     3、”duo gong neng bao shi“ 为口令,故在每次识别时,必须先发一级口令“多功能报时”
**************************************************************************/
uint8 LD_AsrAddFixed()
{
    uint8 k, flag;
    uint8 nAsrAddLength;
    #define DATE_A 8   /*数组二维数值*/
    #define DATE_B 21        /*数组一维数值*/
    uint8 code sRecog[DATE_A][DATE_B] = {
                             "duo gong neng bao shi",\        
                             "xian zai ji dian le",\
                             "dang qian shi jian",\
                             "xian zai shi ke",\
                             "bao shi",\
                             "dang qian wen du",\
                             "dang qian shi du",\
                             "wen shi du duo shao"
                        };    /*添加关键词,用户修改*/


    uint8 code pCode[DATE_A] = {
                                    CODE_CMD,\
                                    CODE_XZJDL,\
                                    CODE_DQSJ,\
                                    CODE_XZSK,\
                                    CODE_BS,\
                                    CODE_DQWD,\
                                    CODE_DQSD,\
                                    CODE_WSDDS
                                 };    /*添加识别码,用户修改*/    
    flag = 1;
    for (k=0; k<DATE_A; k++)
    {
            
        if(LD_Check_ASRBusyFlag_b2() == 0)
        {
            flag = 0;
            break;
        }
        
        LD_WriteReg(0xc1, pCode[k] );
        LD_WriteReg(0xc3, 0 );
        LD_WriteReg(0x08, 0x04);
        delay(1);
        LD_WriteReg(0x08, 0x00);
        delay(1);


        for (nAsrAddLength=0; nAsrAddLength<DATE_B; nAsrAddLength++)
        {
            if (sRecog[k][nAsrAddLength] == 0)
                break;
            LD_WriteReg(0x5, sRecog[k][nAsrAddLength]);
        }
        LD_WriteReg(0xb9, nAsrAddLength);
        LD_WriteReg(0xb2, 0xff);
        LD_WriteReg(0x37, 0x04);
    }
    return flag;
}

 

 
2、用户执行函数 User_handle(nAsrRes); 处理语音识别结果
 
 
 
void  main(void)
{
    uint8 idata nAsrRes;
    uint8 i=0;
    Led_test();
    MCU_init();
    LD_Reset();
    UartIni(); /*串口初始化*/
    nAsrStatus = LD_ASR_NONE;        //    初始状态:没有在作ASR
    
    #ifdef TEST    
    PrintCom("一级口令:多功能报时\r\n"); /*text.....*/
    PrintCom("二级口令:1、现在几点了\r\n"); /*text.....*/
    PrintCom("    2、当前时间\r\n"); /*text.....*/
    PrintCom("    3、现在时刻\r\n"); /*text.....*/
    PrintCom("    4、报时\r\n"); /*text.....*/
    PrintCom("  5、当前温度\r\n"); /*text.....*/
    PrintCom("    6、当前湿度\r\n"); /*text.....*/
    PrintCom("    7、温湿度多少\r\n"); /*text.....*/
    #endif


    while(1)
    {
        switch(nAsrStatus)
        {
            case LD_ASR_RUNING:
            case LD_ASR_ERROR:        
                break;
            case LD_ASR_NONE:
            {
                nAsrStatus=LD_ASR_RUNING;
                if (RunASR()==0)    /*    启动一次ASR识别流程:ASR初始化,ASR添加关键词语,启动ASR运算*/
                {
                    nAsrStatus = LD_ASR_ERROR;
                }
                break;
            }
            case LD_ASR_FOUNDOK: /*    一次ASR识别流程结束,去取ASR识别结果*/
            {                
                nAsrRes = LD_GetResult();        /*获取结果*/
                User_handle(nAsrRes);            //用户执行函数
                nAsrStatus = LD_ASR_NONE;
                break;
            }
            case LD_ASR_FOUNDZERO:
            default:
            {
                nAsrStatus = LD_ASR_NONE;
                break;
            }
        }// switch                 
    }// while
}

 

 
3、根据不同结果,串口打印不同的指令
 
 
以JSON格式发送数据至串口,与语音识别模块相连的MCU接收此结果,然后对此字符串进行解析,进而得到当前识别的命令是什么,进而做相应的动作。
 
PrintCom("{\"VoiceCommandCode\":1}");


/***********************************************************
* 名    称:用户执行函数
* 功    能:识别成功后,执行动作可在此进行修改
* 入口参数: 无
* 出口参数:无
* 说    明:                      
**********************************************************/
void User_handle(uint8 dat)
{
     //UARTSendByte(dat);//串口识别码(十六进制)
         if(0==dat)
         {
              G0_flag=ENABLE;
            LED=0;
            PrintCom("{\"VoiceCommandCode\":0}");
            PrintCom("收到\r\n"); /*text.....*/
         }
         else if(ENABLE==G0_flag)
         {    
             G0_flag=DISABLE;
            LED=1;
            switch(dat)           /*对结果执行相关操作,客户可删除Printcom 串口输出语句替换为其他需要控制的代码*/
            {
              case CODE_XZJDL:            /*命令“测试”*/
                    PrintCom("{\"VoiceCommandCode\":1}");
                    PrintCom("“现在几点了”命令识别成功\r\n"); /*text.....*/
                    break;
                case CODE_DQSJ:
                    PrintCom("{\"VoiceCommandCode\":2}");
                    PrintCom("“当前时间”命令识别成功\r\n"); /*text.....*/
                    break;
                case CODE_XZSK:
                    PrintCom("{\"VoiceCommandCode\":3}");        
                    PrintCom("“现在时刻”命令识别成功\r\n"); /*text.....*/
                    break;
                case CODE_BS:
                    PrintCom("{\"VoiceCommandCode\":4}");            
                    PrintCom("“报时”命令识别成功\r\n"); /*text.....*/
                    break;
                case CODE_DQWD:
                    PrintCom("{\"VoiceCommandCode\":5}");        
                    PrintCom("“当前温度”命令识别成功\r\n"); /*text.....*/
                    break;
                case CODE_DQSD:
                    PrintCom("{\"VoiceCommandCode\":6}");        
                    PrintCom("“当前湿度”命令识别成功\r\n"); /*text.....*/
                    break;
                case CODE_WSDDS:
                    PrintCom("{\"VoiceCommandCode\":7}");        
                    PrintCom("“温湿度多少”命令识别成功\r\n"); /*text.....*/
                    break;                                                                                                            
                default:
                    PrintCom("{\"VoiceCommandCode\":-1}");
                    PrintCom("请重新识别发口令\r\n"); /*text.....*/
                    break;
            }    
        }    
        else     
        {
            PrintCom("{\"VoiceCommandCode\":-2}");
            PrintCom("请说出一级口令\r\n"); /*text.....*/    
        }
}
 
 
 
4、MCU根据指令不同,执行不同的动作
 
以JSON格式发送数据至串口,与语音识别模块相连的MCU接收此结果,然后对此字符串进行解析,进而得到当前识别的命令是什么,进而做相应的动作。
 
//LD3320
if(USART5_RX_STA&0x8000)
{
    uart5Len=USART5_RX_STA&0x3f;                                    //得到此次接收到的数据长度   
    
    //发送测试数据至串口1
    for(i=0;i<uart5Len;i++)    
    {  
        USART_SendData(USART1, USART5_RX_BUF[i]);                      //向串口 1 发送数据         
        while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);         //等待发送结束     
    }        


    receive_json = cJSON_Parse(USART5_RX_BUF);   //创建JSON解析对象,返回JSON格式是否正确
    if (!receive_json)
    {
        printf("JSON格式错误:%s \r\n", cJSON_GetErrorPtr()); //输出json格式错误信息
    }
    else
    {
        printf("JSON格式正确:%s \r\n",cJSON_Print(receive_json) );
        item_obj = receive_json->child; //获取name键对应的值的信息
        
        while(item_obj)
        {
            char * string = item_obj->string;
            
            if(!strcmp(string,"VoiceCommandCode"))
            {
                if(item_obj->valueint==0)
                {
                    printf("收到一级口令 智能报时 ... \r\n");    
                }
                else if(item_obj->valueint==1)
                {
                    printf("“现在几点了”命令识别成功 \r\n");
                    
                    m_nCurrentVoicePlayTimes++;
                    while(U5152_BSY){}
                    if(m_nCurrentVoicePlayTimes%2==0)
                    {
                        sprintf((char*)dtbuf,"[v5][s5][m3]当前时间为%02d时%02d分%02d秒 \r\n",NowHour,NowMinute,NowSecond);
                    }
                    else
                    {
                        sprintf((char*)dtbuf,"[v5][s5][m51]当前时间为%02d时%02d分%02d秒 \r\n",NowHour,NowMinute,NowSecond);
                    }                                
                    printf((char*)dtbuf);
                    XFS_FrameInfo((char*)dtbuf) ;
                    delay_ms(10);while(U5152_BSY){delay_ms(500);printf("while(U5152_BSY) \r\n");}
                }
                else if(item_obj->valueint==2)
                {
                    printf("“当前时间”命令识别成功\r\n");
                    
                    m_nCurrentVoicePlayTimes++;
                    while(U5152_BSY){}
                    if(m_nCurrentVoicePlayTimes%2==0)
                    {
                        sprintf((char*)dtbuf,"[v5][s5][m3]当前时间为%02d时%02d分%02d秒 \r\n",NowHour,NowMinute,NowSecond);
                    }
                    else
                    {
                        sprintf((char*)dtbuf,"[v5][s5][m51]当前时间为%02d时%02d分%02d秒 \r\n",NowHour,NowMinute,NowSecond);
                    }                                
                    printf((char*)dtbuf);
                    XFS_FrameInfo((char*)dtbuf) ;
                    delay_ms(10);while(U5152_BSY){delay_ms(500);printf("while(U5152_BSY) \r\n");}
                }
                else if(item_obj->valueint==3)
                {
                    printf("“现在时刻”命令识别成功\r\n");
                    
                    m_nCurrentVoicePlayTimes++;
                    while(U5152_BSY){}
                    if(m_nCurrentVoicePlayTimes%2==0)
                    {
                        sprintf((char*)dtbuf,"[v5][s5][m3]当前时间为%02d时%02d分%02d秒 \r\n",NowHour,NowMinute,NowSecond);
                    }
                    else
                    {
                        sprintf((char*)dtbuf,"[v5][s5][m51]当前时间为%02d时%02d分%02d秒 \r\n",NowHour,NowMinute,NowSecond);
                    }                                
                    printf((char*)dtbuf);
                    XFS_FrameInfo((char*)dtbuf) ;
                    delay_ms(10);while(U5152_BSY){delay_ms(500);printf("while(U5152_BSY) \r\n");}
                }
                else if(item_obj->valueint==4)
                {
                    printf("“关灯”命令识别成功\r\n");
                }
                else if(item_obj->valueint==5)
                {
                    printf("“当前温度”命令识别成功\r\n");
                    
                    m_nCurrentVoicePlayTimes++;
                    while(U5152_BSY){}
                    if(m_nCurrentVoicePlayTimes%2==0)
                    {
                        sprintf((char*)dtbuf,"[v5][s5][m3]当前温度为%.1f摄氏度 \r\n",DHT11Temp);    
                    }
                    else
                    {
                        sprintf((char*)dtbuf,"[v5][s5][m51]当前温度为%.1f摄氏度 \r\n",DHT11Temp);    
                    }                                
                    printf((char*)dtbuf);
                    XFS_FrameInfo((char*)dtbuf) ;
                    delay_ms(10);while(U5152_BSY){delay_ms(500);printf("while(U5152_BSY) \r\n");}
                }
                else if(item_obj->valueint==6)
                {
                    printf("“当前湿度”命令识别成功\r\n");
                    
                    m_nCurrentVoicePlayTimes++;
                    while(U5152_BSY){}
                    if(m_nCurrentVoicePlayTimes%2==0)
                    {
                        sprintf((char*)dtbuf,"[v5][s5][m3]当前湿度为百分之%.1f \r\n",DHT11Hum);    
                    }
                    else
                    {
                        sprintf((char*)dtbuf,"[v5][s5][m51]当前湿度为百分之%.1f \r\n",DHT11Hum);    
                    }                                
                    printf((char*)dtbuf);
                    XFS_FrameInfo((char*)dtbuf) ;
                    delay_ms(10);while(U5152_BSY){delay_ms(500);printf("while(U5152_BSY) \r\n");}
                }
                else if(item_obj->valueint==7)
                {
                    printf("“温湿度多少”命令识别成功\r\n");
                    
                    m_nCurrentVoicePlayTimes++;
                    while(U5152_BSY){}
                    if(m_nCurrentVoicePlayTimes%2==0)
                    {
                        sprintf((char*)dtbuf,"[v5][s5][m3]温度为%.1f度,湿度为%.1f \r\n",DHT11Temp,DHT11Hum);    
                    }
                    else
                    {
                        sprintf((char*)dtbuf,"[v5][s5][m51]温度为%.1f度,湿度为%.1f \r\n",DHT11Temp,DHT11Hum);    
                    }                                
                    printf((char*)dtbuf);
                    XFS_FrameInfo((char*)dtbuf) ;
                    delay_ms(10);while(U5152_BSY){delay_ms(500);printf("while(U5152_BSY) \r\n");}
                }                        
            }
            
            item_obj = item_obj->next;
            
            printf("while(item_obj) \r\n");
        }
        
    }
    
    cJSON_Delete(receive_json);        
    
    USART5_RX_STA=0;   
    memset(USART5_RX_BUF, 0, sizeof(USART5_RX_BUF));                  //清空数组  
}

 

 
LDV7模块固件下载:
 
1、打开编译后的.hex文件
 
 
 
 
2、选对串口号,芯片型号后,选择“下载/编程”按钮,然后给STC单片机上电或者复位。
 
 
3、发出语音,测试语音识别结果
 
 
 
 
 
{"VoiceCommandCode":0}收到
{"VoiceCommandCode":1}“现在几点了”命令识别成功
{"VoiceCommandCode":0}收到
{"VoiceCommandCode":2}“当前时间”命令识别成功
{"VoiceCommandCode":0}收到
{"VoiceCommandCode":3}“现在时刻”命令识别成功
{"VoiceCommandCode":0}收到
{"VoiceCommandCode":4}“报时”命令识别成功
{"VoiceCommandCode":0}收到
{"VoiceCommandCode":5}“当前温度”命令识别成功
{"VoiceCommandCode":0}收到
{"VoiceCommandCode":6}“当前湿度”命令识别成功
{"VoiceCommandCode":0}收到
{"VoiceCommandCode":7}“温湿度多少”命令识别成功
{"VoiceCommandCode":0}收到
{"VoiceCommandCode":7}“温湿度多少”命令识别成功

然后其他与LDV7模块相连的MCU只要解析接收到的串口数据即可。


从六月份开始,每个月会制作一个毕业设计难度的DIY作品,

前期作品以模块组合的形式搭建,降低门槛,方便大家一起跟着做;

DIY过程只在微信公众号中分享,大家没关注的,赶紧关注哈。

 

每个月时间大致安排:

上个月25号,公布DIY作品名称;

每月1日公布作品功能点及所需要的功能模块链接;

每月10日前绘制完模块配合的线路板;

每月15日之前硬件搭建完毕,之后按模块撰写代码,调试,随时公众号更新进展;

每月月底开源整个作品的源码和PCB工程文件。

 

题目选取原则:

公众号每个月20日发起投票,25号截止,票数最多的作为下个月的DIY内容;

投票的备选项大家可以后台留言给我,我会选出五种留言最多的作为选项;

每个月的DIY内容尽量与上个月分享的文章有一定的相关度,起到温故知新的作用。

 

有什么想法或者建议,留言给我哈。

 

  • 59
    点赞
  • 591
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 42
    评论
LD3320语音识别模块是一款基于DSP技术的语音识别芯片,它能够对人声进行实时识别和处理。目前,LD3320语音识别模块已经广泛应用于智能家居、智能机器人、智能医疗等领域。 LD3320语音识别模块的主要特点如下: 1. 支持多种语音识别:LD3320语音识别模块支持中文、英文、数字、特定词汇等多种语音识别,并且能够自定义添加关键词。 2. 高精度语音识别:LD3320语音识别模块采用先进的DSP技术,能够对人声进行高精度的识别和处理。 3. 简易的串口通信口:LD3320语音识别模块的通信口采用标准的串口通信协议,使用方便。 4. 小巧的封装:LD3320语音识别模块体积小巧,适合于各种小型智能设备或机器人的嵌入式设计。 5. 低功耗:LD3320语音识别模块的功耗非常低,可以在智能设备中长时间稳定运行。 LD3320语音识别模块的硬件设计一般包括模块电路板、麦克风、功放等组成。其中,模块电路板是LD3320语音识别芯片的核心部分,麦克风用于收声音信号,功放用于输出语音指令。 LD3320语音识别模块的软件设计主要包括以下几个方面: 1. 语音识别算法:使用LD3320语音识别模块前,需要先将语音识别算法烧录到芯片中。 2. 串口通信协议:LD3320语音识别模块采用标准的串口通信协议,需要根据协议进行通信。 3. 语音指令识别程序:根据具体应用场景,编写相应的语音指令识别程序,实现智能设备的语音控制功能。 总之,LD3320语音识别模块是一款功能强大、性能稳定的语音识别芯片,可以广泛应用于各种智能设备中,为人们的生活带来更多的便利。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 42
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员小哈

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值