在過去的幾周里,我一直在努力重新與我對吉他的熱愛聯(lián)系起來。彈奏箱式吉他是我在薩克斯管接管之前的幾年前放松的方式?;氐郊?,在3年很少彈奏和弦之后,我發(fā)現(xiàn)我不再知道每根弦應(yīng)該如何發(fā)聲,用我朋友的話來說,“我的聽力不再調(diào)諧”,因此,如果沒有鍵盤或移動(dòng)應(yīng)用程序的幫助,我無法調(diào)吉他后來下載。幾周過去了,直到幾天前,我的制造商變得有動(dòng)力,我決定建立一個(gè)基于Arduino的吉他調(diào)音器。在今天的教程中,我將分享如何構(gòu)建自己的DIY Arduino吉他調(diào)音器。
吉他調(diào)諧器的工作原理
在我們轉(zhuǎn)向電子產(chǎn)品之前,了解構(gòu)建背后的原理很重要。有 7 個(gè)主要音符由字母表示;A,B,C,D,E,F(xiàn),G,通常以另一個(gè)A結(jié)尾,該A始終比第一個(gè)A高一個(gè)八度。在音樂中,這些音符存在幾個(gè)版本,如第一個(gè)A和最后一個(gè)A。這些音符分別與它們的變化區(qū)分開來,并通過稱為音高的聲音特征之一來區(qū)分彼此。音高被定義為聲音的響度或低度,并由該聲音的頻率表示。由于這些音符的頻率是已知的,因此要確定吉他是否調(diào)音,我們只需要將特定弦的音符頻率與弦所代表的音符的實(shí)際頻率進(jìn)行比較即可。
7個(gè)音符的頻率是:
A = 27.50Hz
B = 30.87Hz
C = 16.35Hz
D = 18.35Hz
E = 20.60Hz
F = 21.83Hz
G = 24.50Hz
這些音符的每個(gè)變化總是在等于 FxM 的音高,其中 F 是頻率,M 是非零整數(shù)。因此,對于如前所述比第一個(gè) A 高一個(gè)八度的最后一個(gè) A,頻率是;
27.50 x 2 = 55Hz。
吉他(主音/盒式吉他)通常有 6 根弦,由開弦上的音符 E、A、D、G、B、E 表示。像往常一樣,最后一個(gè) E 將比第一個(gè) E 高一個(gè)八度。我們將設(shè)計(jì)我們的吉他調(diào)音器,以幫助使用這些音符的頻率調(diào)整吉他。
根據(jù)標(biāo)準(zhǔn)的吉他調(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 |
項(xiàng)目流程非常簡單;我們將吉他產(chǎn)生的聲音信號轉(zhuǎn)換為頻率,然后與被調(diào)諧琴弦的確切頻率值進(jìn)行比較。當(dāng)值相關(guān)時(shí),使用 LED 通知吉他手。
頻率檢測/轉(zhuǎn)換涉及 3 個(gè)主要階段;
放大
抵消
模數(shù)轉(zhuǎn)換(采樣)
產(chǎn)生的聲音信號太弱,Arduino的ADC無法識別,因此我們需要放大信號。放大后,為了將信號保持在Arduino的ADC可識別的范圍內(nèi)以防止信號削波,我們偏移了信號的電壓。偏移后,信號被傳遞到Arduino ADC,在那里對其進(jìn)行采樣并獲得該聲音的頻率。
必需組件
生成此項(xiàng)目需要以下組件;
阿杜伊諾烏諾 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)諧器電路圖所示。
按鈕連接時(shí)沒有上拉/下拉電阻,因?yàn)閷⑹褂肁rduino內(nèi)置的上拉電阻。這是為了確保電路盡可能簡單。
吉他調(diào)諧器的Arduino代碼
這個(gè)吉他調(diào)音器項(xiàng)目代碼背后的算法很簡單。為了調(diào)音特定的琴弦,吉他手通過按下相應(yīng)的按鈕來選擇琴弦,然后彈奏一根開放的琴弦。聲音由放大級收集并傳遞到Arduino ADC。對頻率進(jìn)行解碼和比較。當(dāng)串的輸入頻率小于指定頻率時(shí),對于該串,其中一個(gè)黃色 LED 亮起,指示應(yīng)擰緊串。當(dāng)測量的頻率大于該串的規(guī)定頻率時(shí),另一個(gè) LED 亮起。當(dāng)頻率在該弦的規(guī)定范圍內(nèi)時(shí),綠色 LED 亮起以引導(dǎo)吉他手。
最后給出了完整的Arduino代碼,這里我們簡要解釋了代碼的重要部分。
我們首先創(chuàng)建一個(gè)數(shù)組來容納開關(guān)。
int buttonarray[] = {13, 12, 11, 10, 9, 8}; // [E2, A2, D3, G3, B3, E4]
接下來,我們創(chuàng)建一個(gè)數(shù)組來保存每個(gè)字符串的相應(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)連接到的每個(gè)引腳啟用Arduino上的內(nèi)部上拉。之后,我們將LED連接的引腳設(shè)置為輸出,并啟動(dòng)串行監(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)路功能,我們實(shí)現(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)注
187文章
6457瀏覽量
186502
發(fā)布評論請先 登錄
相關(guān)推薦
評論