在過去的幾周里,我一直在努力重新與我對吉他的熱愛聯(lián)系起來。彈奏箱式吉他是我在薩克斯管接管之前的幾年前放松的方式。回到吉他,在3年很少彈奏和弦之后,我發(fā)現(xiàn)我不再知道每根弦應(yīng)該如何發(fā)聲,用我朋友的話來說,“我的聽力不再調(diào)諧”,因此,如果沒有鍵盤或移動應(yīng)用程序的幫助,我無法調(diào)吉他后來下載。幾周過去了,直到幾天前,我的制造商變得有動力,我決定建立一個基于Arduino的吉他調(diào)音器。在今天的教程中,我將分享如何構(gòu)建自己的DIY Arduino吉他調(diào)音器。
吉他調(diào)諧器的工作原理
在我們轉(zhuǎn)向電子產(chǎn)品之前,了解構(gòu)建背后的原理很重要。有 7 個主要音符由字母表示;A,B,C,D,E,F(xiàn),G,通常以另一個A結(jié)尾,該A始終比第一個A高一個八度。在音樂中,這些音符存在幾個版本,如第一個A和最后一個A。這些音符分別與它們的變化區(qū)分開來,并通過稱為音高的聲音特征之一來區(qū)分彼此。音高被定義為聲音的響度或低度,并由該聲音的頻率表示。由于這些音符的頻率是已知的,因此要確定吉他是否調(diào)音,我們只需要將特定弦的音符頻率與弦所代表的音符的實際頻率進行比較即可。
7個音符的頻率是:
A = 27.50Hz
B = 30.87Hz
C = 16.35Hz
D = 18.35Hz
E = 20.60Hz
F = 21.83Hz
G = 24.50Hz
這些音符的每個變化總是在等于 FxM 的音高,其中 F 是頻率,M 是非零整數(shù)。因此,對于如前所述比第一個 A 高一個八度的最后一個 A,頻率是;
27.50 x 2 = 55Hz。
吉他(主音/盒式吉他)通常有 6 根弦,由開弦上的音符 E、A、D、G、B、E 表示。像往常一樣,最后一個 E 將比第一個 E 高一個八度。我們將設(shè)計我們的吉他調(diào)音器,以幫助使用這些音符的頻率調(diào)整吉他。
根據(jù)標準的吉他調(diào)音,每根弦的音符和相應(yīng)的頻率如下表所示。
字符串 | 頻率 | 表示法 |
1 (E) | 329.63赫茲 | E4 |
2 (B) | 246.94赫茲 | B3 |
3 (G) | 196.00赫茲 | G3 |
4 (D) | 146.83赫茲 | D3 |
5 (一) | 110.00赫茲 | 答2 |
6 (E) | 82.41赫茲 | E2 |
項目流程非常簡單;我們將吉他產(chǎn)生的聲音信號轉(zhuǎn)換為頻率,然后與被調(diào)諧琴弦的確切頻率值進行比較。當值相關(guān)時,使用 LED 通知吉他手。
頻率檢測/轉(zhuǎn)換涉及 3 個主要階段;
放大
抵消
模數(shù)轉(zhuǎn)換(采樣)
產(chǎn)生的聲音信號太弱,Arduino的ADC無法識別,因此我們需要放大信號。放大后,為了將信號保持在Arduino的ADC可識別的范圍內(nèi)以防止信號削波,我們偏移了信號的電壓。偏移后,信號被傳遞到Arduino ADC,在那里對其進行采樣并獲得該聲音的頻率。
必需組件
生成此項目需要以下組件;
阿杜伊諾烏諾 x1
LM386 x1
電容麥克風(fēng) x1
麥克風(fēng)/音頻插孔 x1
10k 電位器 x1
O.1uf 電容器 x2
100歐姆電阻 x4
10歐姆電阻 x1
10uF 電容器 x3
5毫米黃色發(fā)光二極管 x2
5毫米綠色發(fā)光二極管 x1
常開按鈕 x6
跳線
面包板
圖表
連接組件,如下面的吉他調(diào)諧器電路圖所示。
按鈕連接時沒有上拉/下拉電阻,因為將使用Arduino內(nèi)置的上拉電阻。這是為了確保電路盡可能簡單。
吉他調(diào)諧器的Arduino代碼
這個吉他調(diào)音器項目代碼背后的算法很簡單。為了調(diào)音特定的琴弦,吉他手通過按下相應(yīng)的按鈕來選擇琴弦,然后彈奏一根開放的琴弦。聲音由放大級收集并傳遞到Arduino ADC。對頻率進行解碼和比較。當串的輸入頻率小于指定頻率時,對于該串,其中一個黃色 LED 亮起,指示應(yīng)擰緊串。當測量的頻率大于該串的規(guī)定頻率時,另一個 LED 亮起。當頻率在該弦的規(guī)定范圍內(nèi)時,綠色 LED 亮起以引導(dǎo)吉他手。
最后給出了完整的Arduino代碼,這里我們簡要解釋了代碼的重要部分。
我們首先創(chuàng)建一個數(shù)組來容納開關(guān)。
int buttonarray[] = {13, 12, 11, 10, 9, 8}; // [E2, A2, D3, G3, B3, E4]
接下來,我們創(chuàng)建一個數(shù)組來保存每個字符串的相應(yīng)頻率。
float freqarray[] = {82.41, 110.00, 146.83, 196.00, 246.94, 329.63};//all in Hz
完成此操作后,我們聲明LED連接的引腳以及將用于從ADC獲取頻率的其他變量。
int lowerLed = 7;
int higherLed = 6;
int justRight = 5;
#define LENGTH 512
byte rawData[LENGTH];
int count;
接下來是 void setup() 函數(shù)。
在這里,我們首先為開關(guān)連接到的每個引腳啟用Arduino上的內(nèi)部上拉。之后,我們將LED連接的引腳設(shè)置為輸出,并啟動串行監(jiān)視器以顯示數(shù)據(jù)。
void setup()
{
for (int i=0; i<=5; i++)
{
pinMode(buttonarray[i], INPUT_PULLUP);
}
pinMode(lowerLed, OUTPUT);
pinMode(higherLed, OUTPUT);
pinMode(justRight, OUTPUT);
Serial.begin(115200);
}
接下來,就是空隙環(huán)路功能,我們實現(xiàn)頻率檢測和比較。
void loop(){
if (count < LENGTH)?
{
count++;
rawData[count] = analogRead(A0)>>2;
}
else {
sum = 0;
pd_state = 0;
int period = 0;
for(i=0; i < len; i++)
{
// Autocorrelation
sum_old = sum;
sum = 0;
for(k=0; k < len-i; k++) sum += (rawData[k]-128)*(rawData[k+i]-128)/256;
// Serial.println(sum);
// Peak Detect State Machine
if (pd_state == 2 && (sum-sum_old) <=0)?
{
period = i;
pd_state = 3;
}
if (pd_state == 1 && (sum > thresh) && (sum-sum_old) > 0) pd_state = 2;
if (!i) {
thresh = sum * 0.5;
pd_state = 1;
}
}
// Frequency identified in Hz
if (thresh >100) {
freq_per = sample_freq/period;
Serial.println(freq_per);
for (int s=0; s<=5; s++)
{
if (digitalRead(buttonarray[i])== HIGH)
{
if (freq_per - freqarray[i] < 0)
{
digitalWrite(lowerLed, HIGH);
}
else if(freq_per - freqarray[i] > 10)
{
digitalWrite(higherLed, HIGH);
}
else
{
digitalWrite(justRight, HIGH);
}
}
}
}
count = 0;
}
}
-
Arduino
+關(guān)注
關(guān)注
188文章
6469瀏覽量
187093
發(fā)布評論請先 登錄
相關(guān)推薦
評論