来21ic潜水了好久,发现这次的活动很给力,我也来分享一下自己正在做的项目。这个是基于MSP430G2553和LD3320的语音识别智能家居设计,是我大学老师帮找的项目,感谢王老师。
大家先看下视频:
h()t()tp://v.youku.com/v_show/id_XNTg2MDUwNjM2.html(去掉括号)
这个项目已做好的部分包括:
一,上位机用VB写的,来实现图形界面和反馈。
二,语音识别部分使用芯片LD3320和STC89LE52,来实现语音识别。
三,接收语音识别码再和上位机通信使用MSP430G2553作为主机。
四,MSP430G2553主机控制NRF24l01模块与另一块带有NRF24l01控制继电器的MSP430G2553节点通信。
五,最后就是为了实现语音控制家电用另一个MSP430G2553节点来模拟遥控器,实现语音控制电视的功能。
硬件部分的话,为了先写代码,调试程序方便就用了2块LUANCHPAD,一块做主机一块做节点(各自带有NRF24l01模块)。还有一块LD3320模块上面带了一块STCLE52,通过STC89LE52控制LD3220进行语音识别,再把识别出来结果通过串口和LUANCHPAD主机通信,来实现语音识别。最后临时用万用板焊了一块继电器来控制灯的开关,还有一块是模拟遥控发射的电路板。LUNCHPAD的电路我看21ic的大家因该不陌生了,NRF24l01模块因该都用过了,那就说下LD3320实现语音识别的电路,这个芯片主要通过80总线和STCL89E52通信,也可以用SPI通信。这个芯片只要外接一些电容电阻,还有最重要的麦克风就可以了。麦克风推荐用电容麦。
最主要和21ic的大家分享一下软件的实现了。首先说下上位机。我在学校学过C++,但是由于学习不用功,所以如果要用C++写好的上位机不是一件容易的事,所以说改用比较容易的VB来开发。这个上位机主要实现的功能是串口通信,接收来自单片机的语音识别码和温度数据,通过播放动画来实现互动和反馈。这个上位机启动就自动检测串口,搜索那个串口是和单片机连接的。就等待单片机发来命令,通信协议是这样的,如果是语音识别码就直接发过来,如果是温度数据则先发送一个0xea,接着就发MSP430G2553内部的温度。例如上位机收到0xea+0x1a,这就表示收到了温度数据而且温度是26度,最后根据温度来播放动画。
调用MSComm1控件实现串口通信的代码
Private Sub MSComm1_OnComm()
Select Case MSComm1.CommEvent
Case comEvReceive
ax1 = MSComm1.Input
MSComm1.InBufferCount = 0
ax(0) = ax1(0)
If flag_c = 1 Then
rdata(0) = ax(0)
ax(0) = 0
' Text2.Text = rdata(0)
flag_c = 0
End If
If ax(0) = &HEA Then
ax(0) = 0
flag_c = 1
End If
MSComm1.InBufferCount = 0
End Select
End Sub
说下LD3320的代码。由于LD3320是内置DSP的芯片,内部有语音识别算法,我只要通过80总线来读写寄存器实现芯片的初始化,再把要识别的语句通过拼音的字符串写入芯片,最多可以实现50个语句的识别。LD3320有两个模式,一个就是口令模式,一个是普通模式,因为在环境里毕竟有噪声的存在,为了防止噪声误触发识别命令,所以选择口令模式最好,先说口令之后才能有效识别,为了让显示语音识别成功与否,加了一个LED,如果检测到口令LED就会亮,如果检测到口令后再识别到关键字,那么表示语音识别成功,LED就会灭。
以下是LD3320的添加关键字部分代码
uint8 LD_AsrAddFixed()
{
uint8 k, flag;
uint8 nAsrAddLength;
#define DATE_A 17
#define DATE_B 20
uint8 code sRecog[DATE_A][DATE_B] = {
"chu yin",\ //添加语音识别拼音字符串
"ni hao",\
"wen du",\
"kai deng",\
"guan deng",\
};
uint8 code pCode[DATE_A] = {
CODE_CMD,\
NI_HAO,\
WEN_DU,\
KAI_DENG,\
GUAN_DENG,\
};
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;
}
说下主角MSP430G2553作为主机和节点。作为主机的MSP430G2553主要是接收来自STC89LE52的识别码和对这些识别码的相应处理。例如收到的是开灯的识别码就会通过NRF24l01发送到节点,节点就驱动继电器来开灯。如果收到的是XX电视台的识别码,就发送到另一个节点来模拟遥控器实现电视机节目的切换(先让单片机学习遥控器的编码)。如果收到的是温度识别码就测量单片机的温度,发到上位机。一些别的识别码就通过单片机转发到上位机。
测温的代码:
void te()
{
for(int i=0;i<256;i++)//多次测量求平均温度
{
ADC10CTL0&=~ADC10IFG;
ADC10CTL0 |= ENC + ADC10SC;
while(!(ADC10CTL0&ADC10IFG));
temp+=ADC10MEM;
}
temp>>=8;
degree = ((temp - 673) * 423) / 1024;
}
通过24l01发送的代码:
msg[0]=0xe6;
nRF24L01_TxPacket(msg);
SPI_RW_Reg(WRITE_REG+STATUS,0xff); // clear interrupt flag(TX_DS)
Delay_us(1000);
GLED_ray();
Delay_us(1000);
最后终结下这个项目的心得。其实这个项目最难的是写上位机,这个花了好久时间才写好的,包括制作动画合成语音。在调试上位机的时候试过单片机无法连接上,后发现是LUNCHPAD支持的波特率最高就9600,再高就无法通信了。还有一个最难忘的是在模拟遥控器的时候,先用430捕获来捕获每一个跳变沿,由于接收和发送的是电平相反的信号所以当时好天真地认为把电平改一下就可以发出去了,再次用捕获回自己模拟遥控器的信号,发现捕获回来的信号和原来的遥控器很不一样。想了好久都没有发现问题所在,后来发现,原来发送信号是要经过38KHZ的载波的,即高电平的时候是频率为38KHZ的方波,低电平则是没有信号。
一句话总结就是在做项目的时候要细心,一个小错误都会让你的系统无法工作。
还有个语音遥控电视视频没拍希望楼下留个位置放视频
:) 感谢楼主分享,本帖已被管理员推荐到应用频道。详情:http://www.21ic.com/app/smart/201307/186922.htm
|