智能桌面天气预报系统(终)

常持正念方圆梦;不忘初心总是春。

1

前言

智能桌面天气预报系统(一)

智能桌面天气预报系统(二)

智能桌面天气预报系统(三)

智能桌面天气预报系统(四)

这是关于这个智能天气预报系统的最后一篇分享啦。本系统源码下载链接见文末

本系统人机对话功能采用了两个硬件模块:(1)语音识别模块:采用LD3320语音识别芯片;(2)语音合成模块:采用SYN6288语音合成芯片。

2

语音识别模块

本系统语音识别模块采用的语音芯片是LD3320。该芯片已经集成了语音识别的处理器,不需要外接其他的辅助芯片如Flash、 RAM 等,直接嵌入在现有的产品中就可以实现语音识别的功能。

语音识别的过程为:

(1)先预存要识别的关键词,如:

//-------------------------搜索天气-----------------------------------
#define  STR00  "xiao tian"                    // 小天
#define  STR01  "sou suo fu zhou tian qi"      // 搜索福州天气
#define  STR02  "sou suo shang hai tian qi"    // 搜索上海天气
#define  STR03  "sou suo shen zhen tian qi"    // 搜索深圳天气
#define  STR04  "sou suo bei jing tian qi"     // 搜索北京天气
#define  STR05  "sou suo guang zhou tian qi"   // 搜索广州天气
#define  STR06  "sou suo nan ning tian qi"     // 搜索南宁天气
#define  STR07  "sou suo xia men tian qi"      // 搜索厦门天气
#define  STR08  "sou suo quan zhou tian qi"    // 搜索泉州天气
#define  STR09  "sou suo pu tian tian qi"      // 搜索莆田天气
#define  STR10  "sou suo nan ping tian qi"     // 搜索南平天气

可以预存50条关键词(关键句),小编已经把关键词写死在程序里了,这显然就不能灵活的面对各种场景。其实可以通过代码编写一个学习功能,即识别之前首先进行学习一些即将要识别的关键词,然后在进行识别演示,这样就可以应对比较多的场景。

但是,这样还是不够智能,毕竟只能识别已经预存的关键词(关键句),要是没有预存就没办法识别了。所以真正的语音识别应该是在软件算法上下功夫,关于语音识别已然成为热门的一大研究专题,这属于人工智能的范畴。

 人工智能相关资源

【机器学习】Python3机器学习经典算法与应用

【资源分享03】Python3入门与进阶视频教程

【资源分享04】Python人工智能TensorFlow

【资源分享05】OpenCV人工智能图像处理

(2)开始识别,如:

static void Task_ASR(void)
{
 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:
     nAsrRes = LD_GetResult( );  //  一次ASR识别流程结束,去取ASR识别结果  
     ASRSuccess_Handle(nAsrRes);
     nAsrStatus = LD_ASR_NONE;  
   break;
   
   case LD_ASR_FOUNDZERO:
   default:
     nAsrStatus = LD_ASR_NONE;  
     break;
 }
}

nAsrStatus是用来表示语音识别的状态,不是LD3320芯片内部的状态寄存器。nAsrStatus有几种情况。我们比较关注的是LD_ASR_FOUNDOK状态。LD_ASR_FOUNDOK状态为识别成功,识别成功后将调用“ASRSuccess_Handle”函数进行识别后的操作。

(3)识别成功则执行相应操作,如

void ASRSuccess_Handle(uint8 asr_code)
{
 printf("\r\n识别码:%d\n",asr_code);    
 if(0 == asr_code)
 {
   printf("我在,需要我的帮助吗?\n");
   TTSPlay(0, "[t3][2]我在,[2]需要[2]我的[3]帮助吗");
   RunFlag = TRUE;
 }
 else if(RunFlag)
 {
   RunFlag = FALSE;
   /* 识别码0-10为搜索天气识别码 */
   if(asr_code>=0&&asr_code<=10)
   {
     switch(asr_code)      
     {
       case CODE01:      
         printf("“福州”命令识别成功\r\n");
         TTSPlay(0, "[t3][2]小天正在为您搜索福州天气");
         memcpy(g_city,"fujianfuzhou",sizeof(g_place));
         break;
       case CODE02:  
         printf("“上海”命令识别成功\r\n");
         TTSPlay(0, "[t3][2]小天正在为您搜索上海天气");      
         memcpy(g_city,"shanghai",sizeof(g_place));
         break;
       case CODE03:    
         printf("“深圳”命令识别成功\r\n");
         TTSPlay(0, "[t3][2]小天正在为您搜索深圳天气");  
         memcpy(g_city,"shenzhen",sizeof(g_place));
         break;
       case CODE04:    
         printf("“北京”命令识别成功\r\n");
         TTSPlay(0, "[t3][2]小天正在为您搜索北京天气");  
         memcpy(g_city,"beijing",sizeof(g_place));
         break;
       case CODE05:    
         printf("“广州”命令识别成功\r\n");
         TTSPlay(0, "[t3][2]小天正在为您搜索广州天气");  
         memcpy(g_city,"guangzhou",sizeof(g_place));
         break;
       case CODE06:    
         printf("“南宁”命令识别成功\r\n");
         TTSPlay(0, "[t3][2]小天正在为您搜索南宁天气");  
         memcpy(g_city,"nanning",sizeof(g_place));
         break;
       case CODE07:    
         printf("“厦门”命令识别成功\r\n");
         TTSPlay(0, "[t3][2]小天正在为您搜索厦门天气");  
         memcpy(g_city,"xiamen",sizeof(g_place));
         break;
       case CODE08:    
         printf("“泉州”命令识别成功\r\n");
         TTSPlay(0, "[t3][2]小天正在为您搜索泉州天气");  
         memcpy(g_city,"quanzhou",sizeof(g_place));
         break;
       case CODE09:    
         printf("“莆田”命令识别成功\r\n");
         TTSPlay(0, "[t3][2]小天正在为您搜索莆田天气");  
         memcpy(g_city,"putian",sizeof(g_place));
         break;
       case CODE10:  
         printf("“南平”命令识别成功\r\n");
         TTSPlay(0, "[t3][2]小天正在为您搜索南平天气");  
         memcpy(g_city,"nanping",sizeof(g_place));
         break;
     }
     memset(&weather_data, 0, sizeof(weather_data));
     GET_NowWeather();
     GET_DailyWeather();
     GetWeatherTimer = TIMER1_HOUR;  
     DisplayWeather(weather_data);
     DisplayWeatherIcon(weather_data);
   }
   else
   {
     switch(asr_code)  
     {
       case CODE11:
         printf("“语音播报天气”命令识别成功\r\n");
         printf("%s\n",g_WeatherText);
//          TTSPlay(0, (uint8_t*)g_WeatherText);
         break;
       case CODE12:
         printf("“今天的气温是多少”命令识别成功\r\n");
         break;
       default:
         TTSPlay(0, "语音识别失败,请对准麦克风说话!");
         break;
     }
   }
   
 }
}

设计识别码0为一级指令码,当一级指令码识别成功后,才能进行二级指令地识别。语音识别成功后,会调用“TTSPlay”函数播报所设定的语音,这样每一次地识别与播报就可以达到了一种人机互动的效果。

3

语音合成模块

本系统的语音合成模块采用SYN6288语音合成芯片,支持文本直接转化为语音。其与单片机的通信方式为串口通信。向该模块发送以下格式的数据包:

5字节帧头+文本+1字节校验,文本字节数小于等于200字节

即可合成语音。代码如:

void TTSPlay(uint8_t Music,uint8_t *Text)
{
 /****************需要发送的文本**********************************/
 uint8_t DataPacket[50];    //
 uint8_t Text_Len;  
 uint8_t ecc  = 0;        //定义校验字节
 uint8_t i=0;  
 Text_Len =strlen((const char*)Text);       //需要发送文本的长度

/*****************帧固定配置信息**************************************/          
 DataPacket[0] = 0xFD ;         //构造帧头FD
 DataPacket[1] = 0x00 ;         //构造数据区长度的高字节
 DataPacket[2] = Text_Len + 3;     //构造数据区长度的低字节
 DataPacket[3] = 0x01 ;         //构造命令字:合成播放命令          
 DataPacket[4] = 0x01 | Music<<4 ;   //构造命令参数:背景音乐设定

/*******************校验码计算***************************************/    
 for(i = 0; i<5; i++)           //依次发送构造好的5个帧头字节
 {  
   ecc=ecc^(DataPacket[i]);    //对发送的字节进行异或校验  
 }

for(i= 0; i<Text_Len; i++)       //依次发送待合成的文本数据
 {  
   ecc=ecc^(Text[i]);         //对发送的字节进行异或校验    
 }    
 /*******************发送帧信息***************************************/      
 memcpy(&DataPacket[5], Text, Text_Len);
 DataPacket[5+Text_Len]=ecc;
 UART4_SendStr((char*)DataPacket,5+Text_Len+1);
}

调用方式如:

TTSPlay(0, "[t3][2]小天正在为您搜索福州天气");

(0)

相关推荐