在過去的幾周里,我一直在努力重新與我對吉他的熱愛聯系起來。彈奏箱式吉他是我在薩克斯管接管之前的幾年前放松的方式。回到吉他,在3年很少彈奏和弦之后,我發現我不再知道每根弦應該如何發聲,用我朋友的話來說,“我的聽力不再調諧”,因此,如果沒有鍵盤或移動應用程序的幫助,我無法調吉他后來下載。幾周過去了,直到幾天前,我的制造商變得有動力,我決定建立一個基于Arduino的吉他調音器。在今天的教程中,我將分享如何構建自己的DIY Arduino吉他調音器。
吉他調諧器的工作原理
在我們轉向電子產品之前,了解構建背后的原理很重要。有 7 個主要音符由字母表示;A,B,C,D,E,F,G,通常以另一個A結尾,該A始終比第一個A高一個八度。在音樂中,這些音符存在幾個版本,如第一個A和最后一個A。這些音符分別與它們的變化區分開來,并通過稱為音高的聲音特征之一來區分彼此。音高被定義為聲音的響度或低度,并由該聲音的頻率表示。由于這些音符的頻率是已知的,因此要確定吉他是否調音,我們只需要將特定弦的音符頻率與弦所代表的音符的實際頻率進行比較即可。
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 是非零整數。因此,對于如前所述比第一個 A 高一個八度的最后一個 A,頻率是;
27.50 x 2 = 55Hz。
吉他(主音/盒式吉他)通常有 6 根弦,由開弦上的音符 E、A、D、G、B、E 表示。像往常一樣,最后一個 E 將比第一個 E 高一個八度。我們將設計我們的吉他調音器,以幫助使用這些音符的頻率調整吉他。
根據標準的吉他調音,每根弦的音符和相應的頻率如下表所示。
字符串 | 頻率 | 表示法 |
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 |
項目流程非常簡單;我們將吉他產生的聲音信號轉換為頻率,然后與被調諧琴弦的確切頻率值進行比較。當值相關時,使用 LED 通知吉他手。
頻率檢測/轉換涉及 3 個主要階段;
放大
抵消
模數轉換(采樣)
產生的聲音信號太弱,Arduino的ADC無法識別,因此我們需要放大信號。放大后,為了將信號保持在Arduino的ADC可識別的范圍內以防止信號削波,我們偏移了信號的電壓。偏移后,信號被傳遞到Arduino ADC,在那里對其進行采樣并獲得該聲音的頻率。
必需組件
生成此項目需要以下組件;
阿杜伊諾烏諾 x1
LM386 x1
電容麥克風 x1
麥克風/音頻插孔 x1
10k 電位器 x1
O.1uf 電容器 x2
100歐姆電阻 x4
10歐姆電阻 x1
10uF 電容器 x3
5毫米黃色發光二極管 x2
5毫米綠色發光二極管 x1
常開按鈕 x6
跳線
面包板
圖表
連接組件,如下面的吉他調諧器電路圖所示。
按鈕連接時沒有上拉/下拉電阻,因為將使用Arduino內置的上拉電阻。這是為了確保電路盡可能簡單。
吉他調諧器的Arduino代碼
這個吉他調音器項目代碼背后的算法很簡單。為了調音特定的琴弦,吉他手通過按下相應的按鈕來選擇琴弦,然后彈奏一根開放的琴弦。聲音由放大級收集并傳遞到Arduino ADC。對頻率進行解碼和比較。當串的輸入頻率小于指定頻率時,對于該串,其中一個黃色 LED 亮起,指示應擰緊串。當測量的頻率大于該串的規定頻率時,另一個 LED 亮起。當頻率在該弦的規定范圍內時,綠色 LED 亮起以引導吉他手。
最后給出了完整的Arduino代碼,這里我們簡要解釋了代碼的重要部分。
我們首先創建一個數組來容納開關。
int buttonarray[] = {13, 12, 11, 10, 9, 8}; // [E2, A2, D3, G3, B3, E4]
接下來,我們創建一個數組來保存每個字符串的相應頻率。
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() 函數。
在這里,我們首先為開關連接到的每個引腳啟用Arduino上的內部上拉。之后,我們將LED連接的引腳設置為輸出,并啟動串行監視器以顯示數據。
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);
}
接下來,就是空隙環路功能,我們實現頻率檢測和比較。
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
+關注
關注
188文章
6468瀏覽量
186956
發布評論請先 登錄
相關推薦
評論