发作品签到
专业版

2023K题【辨音识键奏乐系统】天天翘电机队

工程标签

4.3k
0
0
2

简介

本项目为2023年电赛K题,辨音识键奏乐系统。

简介:本项目为2023年电赛K题,辨音识键奏乐系统。
助力2023全国电赛

开源协议

GPL 3.0

创建时间:2023-07-11 07:26:33更新时间:2023-09-11 06:31:55

描述

一、团队介绍

2023电赛K题全国一等奖
学校:湖南工业职业技术学院
队员A:张**,电子信息专业,主要负责队伍里的硬件,设计一些简单模块的原理图。在队伍遇到困难时提供一些构思。
队员B:肖**,物联网专业,队伍里的软件,交给他的事绝对能放心。
队员C:杨**,电子信息专业,队伍里的软件,与肖在队伍里相辅相成。在代码出现BUG时能快速的解决。
指导老师:刘良斌.吴利清

二、题目要求

屏幕截图 2023-09-05 154805.png

仔细阅读题目,该题的意思就是让我们制作出一套可以拾别到杯子敲击音并识别最终再发出该声音的一套系统。该系统分为四个部分:
1.能拾到敲击杯子发出的声音。
2.单片机可以处理声音的频率。
3.需要显示对应频率的杯号。
4.可以发出与识别到的频率一样的声音。

三、设计摘要

本设计以STM32F103VET6为核心构建了辩音识键奏乐系统。系统通过LM339拾音设备,采集敲击杯口的声音,该信号通过快速傅里叶变换后,通过软件进行带通滤波,实现杯子特征频率的提取。系统在学习阶段将不同杯体的特征频率存储至内存中,测试阶段比对采集到的特征频率与存储的特征频率信号,实现对不同杯子、不同水量的识别。

四、题目分析

本辩音识键奏乐系统要求根据水杯敲击时发出的声音识别出水杯编号,并在水杯注入不同水量后能通过识别控制器识别演奏内置对应音乐。识别控制器具有拾音、分析识别、显示、音乐播放等功能。经过分析研究,主要有以下几个方面需要分析设计:
1)声音采集分析:采集到的声音信号是包含多个频率的波进行叠加后的结果,为了更好的还原波形,应尽可能提高信号的采集频率,以更好的还原信号。
2)声音处理分析:拾音设备集到的声音是包含了环境噪声后的混合数据,需要对采集到的数据进行滤波、选择等操作。频谱分析是研究声学现象的一种重要手段,通过频谱分析可以解决声音中的组成成分及各成分间的相互关系。在典型的频谱图中横坐标表示声音中每个泛音的频率纵坐标表示每个泛音的强度。设计通过频谱分析,对信号进行分析与处理。
3)输出需求分析:发声设备可以通过扬声器,实现简单乐曲的演奏、不同音阶声音的发出。显示设备可以通过液晶屏、数码管等方式,实现当前频率、杯号等信息的显示。
经过上述分析,将系统分为5个基本模块,包括主控模块、电源模块、声音采集模块、发声模块、数据显示模块。系统的总体设计。

五、总体设计框图

屏幕截图 2023-09-05 160441.png

六、硬件电路组成

硬件电路设计
1.声音采集电路
声音传感器采集到声音数据后,输出模拟量信号可能存在幅值大小不一,无法进行准确数据分析。将模拟数据接入信号处理电路进行前期波形处理,若幅值过大或过小均可通过该电路进行缩放,保证数据波形稳定。具体原理图如图4所示。
屏幕截图 2023-09-05 164056.png
2.发声模块
单片机通过输出不同频率的PWM波,实现扬声器发出不同频率的声音。扬声器的功率为1W,只需要通过PNP三极管,控制扬声器即可,非常简单。
屏幕截图 2023-09-05 164355.png
3.主控部分及显示模块
电赛开始前,我们训练积累了非常多的开发板,这次电赛主控部分用的就是我们以前打样的一块搭载了STM32F103VET6的开发板。

七、程序流程图

微信图片_20230905191845.jpg

八、实物展示

微信图片_20230905170538.jpg

九、注意事项

该题的难度在软件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

暂无BOM

附件

序号文件名称下载次数
1
其他程序.rar
201
2
空杯识别.rar
140
3
演示视频.mp4
48
克隆工程
添加到专辑
0
0
分享
侵权投诉

评论

全部评论(1)
按时间排序|按热度排序
粉丝0|获赞0
相关工程
暂无相关工程

底部导航