下面将解释一步一步如何建立一个设备,检测的音符被演奏的吉他。该装置利用麦克风声波中读取完成这个任务,音频放大器和直流偏置电路的调整信号,一个频率的确定算法,和一七段显示器和发光二极管显示注。下面是在引用以下教学发展:Arduino的音频输入,Arduino的频率检测,和Arduino的吉他调谐器。
零件清单:
亚马逊
-
Arduino Uno和USB电缆
-
部分#:lysb01kfd3f0i-cmptraccs
-
跳线
-
线路板
Radio Shack
-
5mm绿色LED
-
¼英寸单内联音频插孔
-
重型9v卡连接器(2)
-
单向动圈话筒
-
9V电池(2)
Digi-Key
-
- 2放大器电路
-
10K欧姆岗线性面板安装电位器
-
100欧姆±5% 0.25w通孔电阻(3)
-
47欧姆±5% 0.25w通孔电阻(3)
-
390欧姆±5% 0.25w通孔电阻(1)
-
±100K欧姆5% 0.25w通孔电阻(3)
-
10µF 16v铝电容器
-
0.047µF - 20% + 80% 25V的陶瓷电容器
步骤1:步骤1:音频输入电路
我们的音频输入电路的设计是基于从电路设计Arduino的音频输入命令。我们的电路图所示。这部分电路可以对音频进行采样和Arduino处理。从麦克风的音频信号进入电路通过一个运算放大器电路和偏置电路,然后进入DC的Arduino。
<strong>制备的Audio Jack</strong>:在我们的电路,我们用¼英寸单声道音频杰克。连接导线的单插孔接地引脚,这通常是在杰克大销。然后连接导线的一种单杰克两信号引脚,这是较小的销。在我们自己的电路,我们用电工胶带,但你可以焊锡丝更好的连接。
<strong>搭建电路</strong>:参考电路图以上构建的电路。在电路的第一步是放大器。它增加了信号的幅度在200到2.5±MV±诉它也保护音频源的其他电路。9 V的电池功率放大器。丝+ V和V的运算放大器。线信号从单杰克非反相输入端连接千斤顶的0 V参考电压电源地引脚上(串联两9 V电池间的连接)。一个100欧姆的电阻丝的输出端和反相运算放大器输入之间。我们用一个10欧姆电位器作为可变电阻调节运放的增益。增益是输出电压的幅值除以输入电压幅值。线反相输入和0 V基准之间的电位差计。你可以调整电位器调整基于麦克风的灵敏度,同时保持它在一个可接受的范围内为Arduino的放大器的增益,这是0到5 V。
<strong>直流偏移</strong>:+ 2.5 V直流偏移,使音频信号振荡约2.5 V,它保持在可接受的范围内(0 - 5 V)为Arduino的模拟输入。直流偏置电路主要有两部分组成:一个分压器和电容器。我们的分压器是由两个100k电阻串联的Arduino的5 V电源接地。由于电阻具有相同的性能,在交界处的电压等于2.5 V 2.5 V节点与10μF电容放大器的输出。这使得电压在2.5 V至2.5 V附近节点的中心连接的10μF输出负铅从运算放大器。连接电容的另一端的节点两100k电阻串联在5V和地面之间。从2.5 V至地面加47 nF的电容。现在输出到模拟输入引脚A0的Arduino。
步骤2:步骤2:7段显示器
用一七段显示器和四个发光二极管代表下面的注释一个吉他:E2,A2,D3,G3,B3和E4。每段和LED将由Arduino数字输出动力。数字引脚2-8将映射到段,B,C,D,E,F和G的七段显示器。数字引脚10将用于发电的七段。数字引脚11-13将LED提供逻辑。七段显示器将显示的说明信,LED将照亮代表音阶。由于七段显示器的限制,票据将在以下的方式呈现:
E2:“E”和两个LED亮
A2:“两个LED亮
维生素D3:“D”和三个发光二极管点亮
G3:“G”三个发光二极管点亮
B3:“B”三个发光二极管点亮
E4:“E”和四个发光二极管点亮
是指在“编程”部分的代码和“附录”程序的LED七段显示器。请参阅上面的电路图,线的七段显示器和发光二极管。
步骤3:步骤3:规划
代码分为两个部分。第一部分,写Amanda Ghassaei,接收音频输入通过Arduino的模拟数字转换器。
从setup()无效;
cli();/ /禁用中断 /设置连续采样的模拟引脚0在38.5khz /清晰的adcsra和adcsrb寄存器 adcsra = 0; adcsrb = 0; admux | =(1 << refs0);//设置参考电压 admux | =(1 <<超前设计的直线加速器放射外科);//左对齐的ADC值,我们可以读到最高的8位adch登记只 adcsra | =(1 << adps2)|(1 << adps0)设置ADC的时钟32分频器- 16mhz / 32 = 500khz /; adcsra | =(1 <<日期);//启用自动触发 adcsra | =(1 <<艾迪);//使中断时,测量完成 adcsra | =(1 <<亚丁);//使ADC adcsra | =(1 << ADSC);//启动ADC测量 sei();/
此外,本节讨论的频率检测。它通过内部形成图。然后处理此图,检测振荡频率形成。
ISR(adc_vect){ //当新的ADC值准备 prevData = newData;//store previous value newData = ADCH;//get value from A0 if (prevData < 127 && newData >=127){//if increasing and crossing midpoint newSlope = newData - prevData;//calculate slope if (abs(newSlope-maxSlope) 9){ reset(); } } } else if (newSlope>maxSlope){//if new slope is much larger than max slope maxSlope = newSlope; time = 0;//reset clock noMatch = 0; index = 0;//reset index } else{//slope not steep enough noMatch++;//increment no match counter if (noMatch>9){ reset(); } } } time++;//increment timer at rate of 38.5kHz ampTimer++;//increment amplitude timer if (abs(127-ADCH)>maxAmp){ maxAmp = abs(127-ADCH); } if (ampTimer==1000){ ampTimer = 0; checkMaxAmp = maxAmp; maxAmp = 0; } }
无效reset() { //清除一些变量 指数= 0;//复位指数 nomatch = 0;//重置对手反 maxslope = 0;//设置边坡 }
第二部分决定如何处理收到的频率,并通过diracakteers写。在这一部分中,从上面的频率进行比较的频率所需的音符的频率确定注。有一次,被确定的频率,然后代码驱动七段LED显示和适当。
frequencycheck() { void if(frequency>70&&frequency<90){ // Displays E on the seven segment display and turns on two LEDs digitalWrite(2,HIGH); digitalWrite(5,HIGH); digitalWrite(6,HIGH); digitalWrite(7,HIGH); digitalWrite(8,HIGH); digitalWrite(10,LOW); digitalWrite(11,HIGH); } else if(frequency>100&&frequency<120){ // Displays A on the seven segment display and turns on two LEDs digitalWrite(2,HIGH); digitalWrite(3,HIGH); digitalWrite(4,HIGH); digitalWrite(6,HIGH); digitalWrite(7,HIGH); digitalWrite(8,HIGH); digitalWrite(10,LOW); digitalWrite(11,HIGH); } else if(frequency>135&&frequency<155){ // Displays D on the seven segment display and turns on three LEDs digitalWrite(3,HIGH); digitalWrite(4,HIGH); digitalWrite(5,HIGH); digitalWrite(6,HIGH); digitalWrite(8,HIGH); digitalWrite(10,LOW); digitalWrite(11,HIGH); digitalWrite(12,HIGH); } else if(frequency>186&&frequency<205){ // Displays G on the seven segment display and turns on three LEDs digitalWrite(2,HIGH); digitalWrite(3,HIGH); digitalWrite(4,HIGH); digitalWrite(5,HIGH); digitalWrite(7,HIGH); digitalWrite(8,HIGH); digitalWrite(10,LOW); digitalWrite(11,HIGH); digitalWrite(12,HIGH); } else if(frequency>235&&frequency<255){ // Displays B on the seven segment display and turns on three LEDs digitalWrite(4,HIGH); digitalWrite(5,HIGH); digitalWrite(6,HIGH); digitalWrite(7,HIGH); digitalWrite(8,HIGH); digitalWrite(10,LOW); digitalWrite(11,HIGH); digitalWrite(12,HIGH); } else if(frequency>320&&frequency<340){ // Displays E on the seven segment display and turns on four LEDs digitalWrite(2,HIGH); digitalWrite(5,HIGH); digitalWrite(6,HIGH); digitalWrite(7,HIGH); digitalWrite(8,HIGH); digitalWrite(10,LOW); digitalWrite(11,HIGH); digitalWrite(12,HIGH); digitalWrite(13,HIGH); } else{ digitalWrite(8,HIGH); } } // void allOff(){ // turn off each segment of the seven segment显示所有的LED digitalwrite(2,低); digitalwrite(3,低); digitalwrite(4,低); digitalwrite(5,低); digitalwrite(6,低); digitalwrite(7,低); digitalwrite(8,低 digitalwrite);(9,低); digitalwrite(10,低); digitalwrite(11,低); digitalwrite(12,低#p#分页标题#e#
该代码可以看完整的附录中。
步骤4:步骤4:测试
在三个阶段的音调检测器。完成试验1和试验2在你建的音频输入电路和上传代码到你的Arduino。完成测试3在你构建的七段显示器和LED电路。
1。测试麦克风阅读任何声音,代码打印相应频率的连续监测在Arduino的编程环境。用你的声音通过麦克风的这个阶段的测试声源。在我们的项目中,我们遇到了一些麻烦,接线时麦克风。确保您使用的是适当的渠道上的麦克风。
2。测试你的设备是检测特定频率的合理。拿着麦克风4 - 6英寸的吉他琴弦,检查显示的频率在串行监测符合预期的频率在每一个音符。
以上是从什么ampthreshold样品试验确定的使用价值。如果你遇到了问题检测某些频率,尝试改变一些门槛值。两试验分别在20和一个测试阈值记录阈值25的记录。正如你可以看到上面的图,电路难以在更高的频率检测记录。消除一些静态的,确保你在一个安静的房间里几乎没有任何环境噪声测试。
三.试验表明,七段显示器和相关的LED显示正确的注。2重复试验,但是这一次看七段显示反馈,相对于串行监测。项目虽然很敏感,如某些笔记(尤其是E4)是嘈杂或难回暖。
步骤5:结论,来源,和附录
我们组是由五个肯塔基大学的学生学习电气和计算机工程。我们开发这个项目的一个信号与系统(EE 421)课程。请参考我们的网站,diracakteers '基音检测的响应,其中包括一个博客我们的进步而发展这种装置和一个描述音高与频率。
来源
Arduino的音频输入Amanda Ghassaei(amandaghassaei)
Arduino的频率检测Amanda Ghassaei(amandaghassaei)
Arduino的吉他调谐器通过nikoala3
附录:
<p>//Modified and used by Dirackteers<br>//
//generalized wave freq detection with 38.5kHz sampling rate and interrupts
//by Amanda Ghassaei
//https://www.instructables.com/id/Arduino-Frequency-Detection/
//Sept 2012</p><p>/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
*</p><p>/data storage variables
byte newData = 0;
byte prevData = 0;
unsigned int time = 0;//keeps time and sends values to store in timer[] occasionally
int timer[10];//storage for timing of events
int slope[10];//storage for slope of events
unsigned int totalTimer;//used to calculate period
unsigned int period;//storage for period of wave
byte index = 0;//current storage index
float frequency;//storage for frequency calculations
int maxSlope = 0;//used to calculate max slope as trigger point
int newSlope;//storage for incoming slope data</p><p>//variables for decided whether you have a match
byte noMatch = 0;//counts how many non-matches you've received to reset variables if it's been too long
byte slopeTol = 3;//slope tolerance- adjust this if you need
int timerTol = 10;//timer tolerance- adjust this if you need</p><p>//variables for amp detection
unsigned int ampTimer = 0;
byte maxAmp = 0;
byte checkMaxAmp;
byte ampThreshold = 30;//raise if you have a very noisy signal</p><p>void setup(){
Serial.begin(9600);</p><p> pinMode(2,OUTPUT); // segment a
pinMode(3,OUTPUT); // segment b
pinMode(4,OUTPUT); // segment c
pinMode(5,OUTPUT); // segment d
pinMode(6,OUTPUT); // segment e
pinMode(7,OUTPUT); // segment f
pinMode(8,OUTPUT); // segment g
pinMode(9,OUTPUT); // decimal point of the seven segment display
pinMode(10,OUTPUT); // common
pinMode(11,OUTPUT); // LED 2
pinMode(12,OUTPUT); // LED 3
pinMode(13,OUTPUT); // LED 4
/* BEGIN AMANDA’s CODE */
cli();//disable interrupts
//set up continuous sampling of analog pin 0 at 38.5kHz
//clear ADCSRA and ADCSRB registers
ADCSRA = 0;
ADCSRB = 0;
ADMUX |= (1 << REFS0); //set reference voltage
ADMUX |= (1 << ADLAR); //left align the ADC value- so we can read highest 8 bits from ADCH register only
ADCSRA |= (1 << ADPS2) | (1 << ADPS0); //set ADC clock with 32 prescaler- 16mHz/32=500kHz
ADCSRA |= (1 << ADATE); //enable auto trigger
ADCSRA |= (1 << ADIE); //enable interrupts when measurement complete
ADCSRA |= (1 << ADEN); //enable ADC
ADCSRA |= (1 << ADSC); //start ADC measurements
sei();//enable interrupts
}</p><p>ISR(ADC_vect) {//when new ADC value ready
prevData = newData;//store previous value
newData = ADCH;//get value from A0
if (prevData < 127 && newData >=127){//if increasing and crossing midpoint
newSlope = newData - prevData;//calculate slope
if (abs(newSlope-maxSlope) 9){
reset();
}
}
}
else if (newSlope>maxSlope){//if new slope is much larger than max slope
maxSlope = newSlope;
time = 0;//reset clock
noMatch = 0;
index = 0;//reset index
}
else{//slope not steep enough
noMatch++;//increment no match counter
if (noMatch>9){
reset();
}
}
}
time++;//increment timer at rate of 38.5kHz
ampTimer++;//increment amplitude timer
if (abs(127-ADCH)>maxAmp){
maxAmp = abs(127-ADCH);
}
if (ampTimer==1000){
ampTimer = 0;
checkMaxAmp = maxAmp;
maxAmp = 0;
}
}</p><p>void reset(){//clear out some variables
index = 0;//reset index
noMatch = 0;//reset match counter
maxSlope = 0;//reset slope
}</p><p>/* END AMANDA’s CODE */</p><p>void frequencyCheck(){
if(frequency>70&&frequency<90){ // Displays E on the seven segment display and turns on two LEDs
digitalWrite(2,HIGH);
digitalWrite(5,HIGH);
digitalWrite(6,HIGH);
digitalWrite(7,HIGH);
digitalWrite(8,HIGH);
digitalWrite(10,LOW);
digitalWrite(11,HIGH);
}
else if(frequency>100&&frequency<120){ // Displays A on the seven segment display and turns on two LEDs
digitalWrite(2,HIGH);
digitalWrite(3,HIGH);
digitalWrite(4,HIGH);
digitalWrite(6,HIGH);
digitalWrite(7,HIGH);
digitalWrite(8,HIGH);
digitalWrite(10,LOW);
digitalWrite(11,HIGH);
}
else if(frequency>135&&frequency<155){ // Displays D on the seven segment display and turns on three LEDs
digitalWrite(3,HIGH);
digitalWrite(4,HIGH);
digitalWrite(5,HIGH);
digitalWrite(6,HIGH);
digitalWrite(8,HIGH);
digitalWrite(10,LOW);
digitalWrite(11,HIGH);
digitalWrite(12,HIGH);
}
else if(frequency>186&&frequency<205){ // Displays G on the seven segment display and turns on three LEDs
digitalWrite(2,HIGH);
digitalWrite(3,HIGH);
digitalWrite(4,HIGH);
digitalWrite(5,HIGH);
digitalWrite(7,HIGH);
digitalWrite(8,HIGH);
digitalWrite(10,LOW);
digitalWrite(11,HIGH);
digitalWrite(12,HIGH);
}
else if(frequency>235&&frequency<255){ // Displays B on the seven segment display and turns on three LEDs
digitalWrite(4,HIGH);
digitalWrite(5,HIGH);
digitalWrite(6,HIGH);
digitalWrite(7,HIGH);
digitalWrite(8,HIGH);
digitalWrite(10,LOW);
digitalWrite(11,HIGH);
digitalWrite(12,HIGH);
}
else if(frequency>320&&frequency<340){ // Displays E on the seven segment display and turns on four LEDs
digitalWrite(2,HIGH);
digitalWrite(5,HIGH);
digitalWrite(6,HIGH);
digitalWrite(7,HIGH);
digitalWrite(8,HIGH);
digitalWrite(10,LOW);
digitalWrite(11,HIGH);
digitalWrite(12,HIGH);
digitalWrite(13,HIGH);
}
else{
digitalWrite(8,HIGH);
}
}
//
void allOff(){ // turn off each segment of the seven segment display and all of the LEDs
digitalWrite(2,LOW);
digitalWrite(3,LOW);
digitalWrite(4,LOW);
digitalWrite(5,LOW);
digitalWrite(6,LOW);
digitalWrite(7,LOW);
digitalWrite(8,LOW);
digitalWrite(9,LOW);
digitalWrite(10,LOW);
digitalWrite(11,LOW);
digitalWrite(12,LOW);
digitalW礼仪(13,低);
}
无效loop() { </P > <P> alloff();
如果(checkmaxamp > ampthreshold){
频率= 38462 /浮(期);//定时器周期计算频率利用率超过
串口打印(频率);//打印结果显示
串口串口。println(HZ);
}
frequencycheck();
延迟(1000);//一秒的延迟
(责任编辑:admin) |