我们组是由五个肯塔基大学的学生学习电气和计算机工程。我们开发这个项目的一个信号与系统(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);//一秒的延迟