
开源协议
:GPL 3.0
描述
一、团队介绍
2023电赛K题全国一等奖
学校:湖南工业职业技术学院
队员A:张**,电子信息专业,主要负责队伍里的硬件,设计一些简单模块的原理图。在队伍遇到困难时提供一些构思。
队员B:肖**,物联网专业,队伍里的软件,交给他的事绝对能放心。
队员C:杨**,电子信息专业,队伍里的软件,与肖在队伍里相辅相成。在代码出现BUG时能快速的解决。
指导老师:刘良斌.吴利清
二、题目要求
仔细阅读题目,该题的意思就是让我们制作出一套可以拾别到杯子敲击音并识别最终再发出该声音的一套系统。该系统分为四个部分:
1.能拾到敲击杯子发出的声音。
2.单片机可以处理声音的频率。
3.需要显示对应频率的杯号。
4.可以发出与识别到的频率一样的声音。
三、设计摘要
本设计以STM32F103VET6为核心构建了辩音识键奏乐系统。系统通过LM339拾音设备,采集敲击杯口的声音,该信号通过快速傅里叶变换后,通过软件进行带通滤波,实现杯子特征频率的提取。系统在学习阶段将不同杯体的特征频率存储至内存中,测试阶段比对采集到的特征频率与存储的特征频率信号,实现对不同杯子、不同水量的识别。
四、题目分析
本辩音识键奏乐系统要求根据水杯敲击时发出的声音识别出水杯编号,并在水杯注入不同水量后能通过识别控制器识别演奏内置对应音乐。识别控制器具有拾音、分析识别、显示、音乐播放等功能。经过分析研究,主要有以下几个方面需要分析设计:
1)声音采集分析:采集到的声音信号是包含多个频率的波进行叠加后的结果,为了更好的还原波形,应尽可能提高信号的采集频率,以更好的还原信号。
2)声音处理分析:拾音设备集到的声音是包含了环境噪声后的混合数据,需要对采集到的数据进行滤波、选择等操作。频谱分析是研究声学现象的一种重要手段,通过频谱分析可以解决声音中的组成成分及各成分间的相互关系。在典型的频谱图中横坐标表示声音中每个泛音的频率纵坐标表示每个泛音的强度。设计通过频谱分析,对信号进行分析与处理。
3)输出需求分析:发声设备可以通过扬声器,实现简单乐曲的演奏、不同音阶声音的发出。显示设备可以通过液晶屏、数码管等方式,实现当前频率、杯号等信息的显示。
经过上述分析,将系统分为5个基本模块,包括主控模块、电源模块、声音采集模块、发声模块、数据显示模块。系统的总体设计。
五、总体设计框图
六、硬件电路组成
硬件电路设计
1.声音采集电路
声音传感器采集到声音数据后,输出模拟量信号可能存在幅值大小不一,无法进行准确数据分析。将模拟数据接入信号处理电路进行前期波形处理,若幅值过大或过小均可通过该电路进行缩放,保证数据波形稳定。具体原理图如图4所示。
2.发声模块
单片机通过输出不同频率的PWM波,实现扬声器发出不同频率的声音。扬声器的功率为1W,只需要通过PNP三极管,控制扬声器即可,非常简单。
3.主控部分及显示模块
电赛开始前,我们训练积累了非常多的开发板,这次电赛主控部分用的就是我们以前打样的一块搭载了STM32F103VET6的开发板。
七、程序流程图
八、实物展示
九、注意事项
该题的难度在软件FFT处理和误差判断上,硬件电路比较简单,我们也尝试过给电路做一个前级滤波,但效果不太理想,会给波形带来失真,甚至还会有误触发。所以最终我们衡量过后,选择了更加稳定的软件滤波。另外,误判断那一块,我们也花了很多心思,感兴趣的同学可以查看附录中的文件。
十、演示视频
附件查看
十一、附件内容
程序附件一 :空杯识别
if(timu==2)
{
if(xuexi)
{
if(mainFrequency>3000)
{
data[x][y] = mainFrequency;
y++;
if(y>3)
{
y=0;
x+=1;
if(x>3)x=1;
}
mainFrequency = 0;
}
}
if(xuexi==0)
{
//*************************************
if(data[1][0] == data[1][1] && data[1][1] == data[1][2] && data[1][2] == data[1][3])
{
data_buffer = data[1][0] ;
}
else
{
data_buffer = 0 ;
}
for(y1=0;y1<4;y1++)
{
if(data[1][y1] == mainFrequency || (data_buffer >= mainFrequency - 8 && data_buffer <= mainFrequency + 8))
{
ko1=1;
x = 1;
}
}
//*************************************
if(data[2][0] == data[2][1] && data[2][1] == data[2][2] && data[2][2] == data[2][3])
{
data_buffer = data[2][0] ;
}
else
{
data_buffer = 0 ;
}
for(y1=0;y1<4;y1++)
{
if(data[2][y1] == mainFrequency || (data_buffer >= mainFrequency - 8 && data_buffer <= mainFrequency + 8))
{
ko3=3;
x = 3;
}
}
//*************************************
if(data[3][0] == data[3][1] && data[3][1] == data[3][2] && data[3][2] == data[3][3])
{
data_buffer = data[3][0] ;
}
else
{
data_buffer = 0 ;
}
for(y1=0;y1<4;y1++)
{
if(data[3][y1] == mainFrequency || (data_buffer >= mainFrequency - 8 && data_buffer <= mainFrequency + 8))
{
ko5=5;
x = 5;
}
}
}
//数据集合处理,优先级判断,敲出数据 > 减法 > 加法
if((ko1==1 && ko3==3) || (ko1==1 && ko5==5) || (ko3==3 && ko5==5) || (ko3==3 && ko5==5 && ko1==1))
{
if(ko1==1 && ko3==3)
{
if(data[1][0] < data[2][0])
{
x=1;
}
else
{
x=3;
}
}
else if(ko1==1 && ko5==5)
{
if(data[1][0] < data[3][0])
{
x=1;
}
else
{
x=5;
}
}
else if(ko3==3 && ko5==5)
{
if(data[2][0] < data[3][0])
{
x=3;
}
else
{
x=5;
}
}
for(i=1;i<4;i++)
{
for(j=0;i<4;j++)
{
if(data[i][j] == mainFrequency)
{
if(i==1) {x=1; bre=1;break;}
if(i==2) {x=3; bre = 3;break;}
if(i==3) {x=5; bre = 5 ;break;}
}
}
if(bre!=0)
{
bre=0;
break;
}
}
}
ko1=0; ko3=0; ko5=0;
}
/********************************************************************************************************
本程序为空杯识别部分,对学习部分,我们把学习得到的频率数据存到二维数组中,在敲击部分,检索二维数组里的数据,和敲击出来的频率对比,相同则为对应数据杯号,由于误差为8,如果学习的数据一个杯子有三个以上数据相同,则和那相同的频率的正负8也进行对比,然后识别出杯号;为防止在误差里撞频,设置了优先级处理,
敲出数据 > 减法8 > 加法8 ;
************************************************************************************************************/
程序附件二 :其他程序
if(timu==3)
{
if(xuexi)
{
if(mainFrequency>2500)
{
data[x][y] = mainFrequency;
y++;
if(y>3)
{
y=0;
x+=1;
if(x>3)x=1;
}
mainFrequency = 0;
}
}
if(xuexi==0)
{
for(y1=0;y1<4;y1++)
{
if(data[1][y1] == mainFrequency||data[1][y1] == mainFrequency-8||data[1][y1] == mainFrequency+8)
{
x = 2;
WS_Borad_Buzzer_Set_Freq(mainFrequency - 900);
WS_Borad_Buzzer_Open_Time(500);
}
}
for(y1=0;y1<4;y1++)
{
if(data[2][y1] == mainFrequency||data[2][y1] == mainFrequency-8||data[2][y1] == mainFrequency+8)
{
x = 4;
WS_Borad_Buzzer_Set_Freq(mainFrequency - 1500);
WS_Borad_Buzzer_Open_Time(500);
}
}
for(y1=0;y1<4;y1++)
{
if(data[3][y1] == mainFrequency||data[3][y1] == mainFrequency-8||data[3][y1] == mainFrequency+8)
{
x = 5;
WS_Borad_Buzzer_Set_Freq(mainFrequency-2200);
WS_Borad_Buzzer_Open_Time(500);
}
}
}
}
if(timu==4)
{
if(xuexi)
{
if(mainFrequency>2200)
{
data[x][y] = mainFrequency;
y++;
if(y>3)
{
y=0;
x+=1;
if(x>5)x=1;
}
mainFrequency = 0;
}
}
if(xuexi==0)
{
if(mainFrequency>2200)
{
x = -1 ;
}
for(i=0;i<4;i++)
{
count = 0;
for(j=0;j<4;j++)
{
if(data[1][i] == data[1][j])
{
count ++;
}
}
if(count == 3 || count == 4)
{
data_buffer = data[1][i] ;
break;
}
else
{
data_buffer = 0;
}
}
for(y1=0;y1<4;y1++)
{
if(data[1][y1]==mainFrequency || data_buffer == mainFrequency - 8 || data_buffer == mainFrequency + 8 || data_buffer == mainFrequency - 7 || data_buffer == mainFrequency + 7 )
{
N++;
if(N>1)
{
x = 1;
WS_Borad_Buzzer_Set_Freq(523);
WS_Borad_Buzzer_Open_Time(500);
}
}
if(y1==4)N=0;
}
for(i=0;i<4;i++)
{
count = 0;
for(j=0;j<4;j++)
{
if(data[2][i] == data[2][j])
{
count ++;
}
}
if(count == 3 || count == 4)
{
data_buffer = data[2][i] ;
break;
}
else
{
data_buffer = 0;
}
}
for(y1=0;y1<4;y1++)
{
if(data[2][y1]==mainFrequency || data_buffer == mainFrequency - 8 || data_buffer == mainFrequency + 8 || data_buffer == mainFrequency - 7 || data_buffer == mainFrequency + 7 )
{
N++;
if(N>1)
{
x = 2;
WS_Borad_Buzzer_Set_Freq(587);
WS_Borad_Buzzer_Open_Time(500);
}
}
if(y1==4)N=0;
}
for(i=0;i<4;i++)
{
count = 0;
for(j=0;j<4;j++)
{
if(data[3][i] == data[3][j])
{
count ++;
}
}
if(count == 3 || count == 4)
{
data_buffer = data[3][i] ;
break;
}
else
{
data_buffer = 0;
}
}
for(y1=0;y1<4;y1++)
{
if(data[3][y1]==mainFrequency || data_buffer == mainFrequency - 8 || data_buffer == mainFrequency + 8 || data_buffer == mainFrequency - 7 || data_buffer == mainFrequency + 7 )
{
N++;
if(N>1)
{
x = 3;
WS_Borad_Buzzer_Set_Freq(659);
WS_Borad_Buzzer_Open_Time(500);
}
}
if(y1==4)N=0;
}
for(i=0;i<4;i++)
{
count = 0;
for(j=0;j<4;j++)
{
if(data[4][i] == data[4][j])
{
count ++;
}
}
if(count == 3 || count == 4)
{
data_buffer = data[4][i] ;
break;
}
else
{
data_buffer = 0;
}
}
for(y1=0;y1<4;y1++)
{
if(data[4][y1]==mainFrequency || data_buffer == mainFrequency - 8 || data_buffer == mainFrequency + 8 || data_buffer == mainFrequency - 7 || data_buffer == mainFrequency + 7 )
{
N++;
if(N>1)
{
x = 4;
WS_Borad_Buzzer_Set_Freq(698);
WS_Borad_Buzzer_Open_Time(500);
}
}
if(y1==4)N=0;
}
for(i=0;i<4;i++)
{
count = 0;
for(j=0;j<4;j++)
{
if(data[5][i] == data[5][j])
{
count ++;
}
}
if(count == 3 || count == 4)
{
data_buffer = data[5][i] ;
break;
}
else
{
data_buffer = 0;
}
}
for(y1=0;y1<4;y1++)
{
if(data[5][y1]==mainFrequency || data_buffer == mainFrequency - 8 || data_buffer == mainFrequency + 8 || data_buffer == mainFrequency - 7 || data_buffer == mainFrequency + 7 )
{
N++;
if(N>1)
{
x = 5;
WS_Borad_Buzzer_Set_Freq(784);
WS_Borad_Buzzer_Open_Time(500);
}
}
if(y1==4)N=0;
}
if (x == -1)
{
x = 0 ;
}
}
}
设计图

BOM


评论