![Nota Dedektörü: 3 Adım Nota Dedektörü: 3 Adım](https://i.howwhatproduce.com/images/001/image-2728-3-j.webp)
İçindekiler:
2025 Yazar: John Day | [email protected]. Son düzenleme: 2025-01-23 15:13
![Image Image](https://i.howwhatproduce.com/images/001/image-2728-5-j.webp)
![](https://i.ytimg.com/vi/2n_JiXvBwsw/hqdefault.jpg)
Bir enstrümanın çaldığı notayı algılayan bu proje ile arkadaşlarınızı ve ailenizi şaşırtın. Bu proje, bir elektronik klavyede, piyano uygulamasında veya başka herhangi bir enstrümanda çalınan notaların yanı sıra yaklaşık frekansı da gösterecektir.
Detaylar
Bu proje için, ses modülü dedektöründen gelen analog çıkış, Arduino Uno'nun A0 analog girişine gönderilir. Analog sinyal örneklenir ve nicelenir (sayısallaştırılır). İlk 3 periyodu kullanarak temel frekansı bulmak için otokorelasyon, ağırlıklandırma ve ayar kodu kullanılır. Yaklaşık temel frekans daha sonra en yakın nota frekansını belirlemek için oktav 3, 4 ve 5 aralığındaki frekanslarla karşılaştırılır. Son olarak en yakın frekans için tahmin edilen not ekrana yazdırılır.
Not: Bu talimat yalnızca projenin nasıl oluşturulacağına odaklanır. Ayrıntılar ve tasarım gerekçeleri hakkında daha fazla bilgi için lütfen şu bağlantıyı ziyaret edin: Daha Fazla Bilgi
Gereçler
- (1) Arduino Uno (veya Genuino Uno)
- (1) DEVMO Mikrofon Sensörü Yüksek Hassasiyetli Ses Algılama Modülü Uyumlu
- (1) Lehimsiz Breadboard
- (1) USB-A - B Kablosu
- Atlama telleri
- Müzik kaynağı (hoparlörlü piyano, klavye veya ağrılı uygulama)
- (1) Bilgisayar veya dizüstü bilgisayar
Adım 1: Nota Dedektörü Donanımını Oluşturun
![Nota Dedektörünü Ayarlayın Nota Dedektörünü Ayarlayın](https://i.howwhatproduce.com/images/001/image-2728-6-j.webp)
Arduino Uno, bağlantı kabloları, lehimsiz devre tahtası ve DEVMO Mikrofon Sensörü Yüksek Hassasiyetli Ses Algılama Modülü (veya benzeri) kullanarak bu resimde gösterilen devreyi oluşturun.
Adım 2: Nota Dedektörünü Programlayın
Arduino IDE'de aşağıdaki kodu ekleyin.
gistfile1.txt
/* |
Dosya/Çizim Adı: MusicalNoteDetector |
Sürüm No.: v1.0 7 Haziran 2020'de düzenlendi |
Orijinal Yazar: Clyde A. Lettsome, PhD, PE, MEM |
Açıklama: Bu kod/çizim, bir elektronik klavyede veya piyano uygulamasında çalınan notanın yanı sıra yaklaşık frekansı da görüntüler. Bu proje için, analog çıkış |
ses modülü dedektörü Arduino Uno'nun A0 analog girişine gönderilir. Analog sinyal örneklenir ve nicelenir (sayısallaştırılır). Otokorelasyon, ağırlıklandırma ve ayar kodu, |
İlk 3 periyodu kullanarak temel frekansı bulun. Yaklaşık temel frekans daha sonra en yakın müzikal frekansı belirlemek için oktav 3, 4 ve 5 aralığındaki frekanslarla karşılaştırılır. |
not sıklığı. Son olarak en yakın frekans için tahmin edilen not ekrana yazdırılır. |
Lisans: Bu program ücretsiz bir yazılımdır; GNU Genel Kamu Lisansı (GPL) sürüm 3 veya daha sonraki herhangi bir şart altında yeniden dağıtabilir ve/veya değiştirebilirsiniz. |
Özgür Yazılım Vakfı tarafından yayınlandığı şekliyle seçtiğiniz sürümü. |
Notlar: Telif hakkı (c) 2020 by C. A. Lettsome Services, LLC |
Daha fazla bilgi için https://clydelettsome.com/blog/2020/06/07/my-weekend-project-musical-note-detector-using-an-arduino/ adresini ziyaret edin. |
*/ |
#define SAMPLES 128 //Arduino Uno için maksimum 128. |
#define SAMPLING_FREQUENCY 2048 //Fs = Nyquist'e göre, beklenen en yüksek frekansın 2 katı olmalıdır. |
#define OFSETSAMPLES 40 //kalibrasyon amacıyla kullanılır |
#define TUNER -3 //C3 130.50 olana kadar ayarlayın |
yüzer örneklemePeriod; |
imzasız uzun microSeconds; |
int X[ÖRNEKLER]; //gerçek değerleri tutmak için SAMPLES boyutunda vektör oluştur |
float autoCorr[ÖRNEKLER]; //sanal değerleri tutmak için SAMPLES boyutunda vektör oluştur |
float depolanmışNotFreq[12] = {130.81, 138.59, 146.83, 155.56, 164.81, 174.61, 185, 196, 207.65, 220, 233.08, 246.94}; |
int toplamOffSet = 0; |
int ofset[OFFSETSAMPLES]; // offset vektörü oluştur |
int avgOffSet; // offset vektörü oluştur |
int i, k, periodEnd, periodBegin, period, ayarlayıcı, noteLocation, octaveRange; |
float maxValue, minValue; |
uzun toplam; |
int eşik = 0; |
int numOfCycles = 0; |
kayan sinyalFrekans, sinyalFrekans2, sinyalFrekans3, sinyalFrekansTahmin, toplam; |
bayt durum_makinesi = 0; |
int samplePeriod = 0; |
geçersiz kurulum() |
{ |
Seri.başla(115200); //115200 Seri Monitör için Baud hızı |
} |
boşluk döngüsü() |
{ |
//***************************************************************** |
//Kalibrasyon Bölümü |
//***************************************************************** |
Serial.println("Kalibrasyon yapılıyor. Lütfen kalibrasyon sırasında nota çalmayınız."); |
için (i = 0; i < OFFSETSAMPLES; i++) |
{ |
offSet = analogRead(0); //Analog pin 0'dan (A0) değeri okur, kuantize eder ve gerçek terim olarak kaydeder. |
//Serial.println(offSet); //hiç ses çalınmadığında ses algılama modülünü yaklaşık olarak yarıya veya 512'ye ayarlamak için bunu kullanın. |
sumOffSet = toplamOffSet + ofset; |
} |
samplePeriod = 0; |
maxValue = 0; |
//***************************************************************** |
// A0'dan gelen girişi kabul etmeye hazırlanın |
//***************************************************************** |
avgOffSet = round(sumOffSet / OFFSETSAMPLES); |
Serial.println("Geri sayım yapılıyor."); |
gecikme(1000); // 1 saniye duraklat |
Seri.println("3"); |
gecikme(1000); // 1 saniye duraklat |
Seri.println("2"); |
gecikme(1000); // 1 için duraklat |
Seri.println("1"); |
gecikme(1000); // 1 saniye duraklat |
Serial.println("Notunuzu çalın!"); |
gecikme(250); //reaksiyon süresi için 1/4 saniye duraklat |
//***************************************************************** |
// SamplePeriod örnekleme periyodu ile A0'dan SAMPLES örnekleri toplayın |
//***************************************************************** |
samplePeriod = 1.0 / SAMPLING_FREQUENCY; //Mikrosaniye cinsinden süre |
için (i = 0; i < ÖRNEKLER; i++) |
{ |
mikroSaniye = mikros(); //Arduino kurulu mevcut betiği çalıştırmaya başladığından beri geçen mikrosaniye sayısını döndürür. |
X = analogRead(0); //Analog pin 0'dan (A0) değeri okur, kuantize eder ve gerçek terim olarak kaydeder. |
/*gerekirse örnekler arasında saniye cinsinden kalan bekleme süresi */ |
while (micros() < (microSeconds + (samplingPeriod * 1000000))) |
{ |
//hiçbir şey yapma sadece bekle |
} |
} |
//***************************************************************** |
//Otokorelasyon Fonksiyonu |
//***************************************************************** |
for (i = 0; i < ÖRNEK; i++) //i=gecikme |
{ |
toplam = 0; |
for (k = 0; k < ÖRNEKLER - i; k++) // Sinyali gecikmeli sinyalle eşleştirin |
{ |
toplam = toplam + (((X[k]) - avgOffSet) * ((X[k + i]) - avgOffSet)); //X[k] sinyaldir ve X[k+i] gecikmeli versiyondur |
} |
autoCorr = toplam / ÖRNEKLER; |
// İlk Tepe Algılama Durum Makinesi |
if (durum_makinesi==0 && i == 0) |
{ |
harman = autoCorr * 0,5; |
durum_makinesi = 1; |
} |
else if (state_machine == 1 && i>0 && thresh 0) //state_machine=1, birinci döngüyü kullanmak için 1 nokta bulun |
{ |
maxValue = autoCorr; |
} |
else if (state_machine == 1&& i>0 && thresh < autoCorr[i-1] && maxValue == autoCorr[i-1] && (autoCorr-autoCorr[i-1])<=0) |
{ |
periodBaşlangıç = i-1; |
durum_makinesi = 2; |
numOfCycles = 1; |
samplePerPeriod = (periodBegin - 0); |
periyot = samplePeriod; |
ayarlayıcı = TUNER+(50.04 * exp(-0.102 * samplePeriod)); |
sinyalFrekans = ((SAMPLING_FREQUENCY) / (samplesPerPeriod))-ayarlayıcı; // f = fs/N |
} |
else if (state_machine == 2 && i>0 && thresh 0) //state_machine=2, 1. ve 2. döngü için 2 periyot bulun |
{ |
maxValue = autoCorr; |
} |
else if (state_machine == 2&& i>0 && thresh < autoCorr[i-1] && maxValue == autoCorr[i-1] && (autoCorr-autoCorr[i-1])<=0) |
{ |
periyotBitiş = i-1; |
durum_makinesi = 3; |
numOfCycles = 2; |
samplePerPeriod = (periodEnd - 0); |
sinyalFrequency2 = ((numOfCycles*SAMPLING_FREQUENCY) / (samplesPerPeriod))-ayarlayıcı; // f = (2*fs)/(2*N) |
maxValue = 0; |
} |
else if (state_machine == 3 && i>0 && thresh 0) //state_machine=3, 1., 2. ve 3. döngü için 3 periyot bulun |
{ |
maxValue = autoCorr; |
} |
else if (state_machine == 3&& i>0 && thresh < autoCorr[i-1] && maxValue == autoCorr[i-1] && (autoCorr-autoCorr[i-1])<=0) |
{ |
periyotBitiş = i-1; |
durum_makinesi = 4; |
numOfCycles = 3; |
samplePerPeriod = (periodEnd - 0); |
sinyalFrequency3 = ((numOfCycles*SAMPLING_FREQUENCY) / (samplesPerPeriod))-ayarlayıcı; // f = (3*fs)/(3*N) |
} |
} |
//***************************************************************** |
//Sonuç Analizi |
//***************************************************************** |
if (samplesPeriod == 0) |
{ |
Serial.println("Hmm….. Emin değilim. Beni kandırmaya mı çalışıyorsun?"); |
} |
Başka |
{ |
// ağırlıklandırma fonksiyonunu hazırla |
toplam = 0; |
if (sinyal Frekansı !=0) |
{ |
toplam = 1; |
} |
if(sinyalFrekans2 !=0) |
{ |
toplam = toplam + 2; |
} |
if (signalFrequency3 !=0) |
{ |
toplam = toplam + 3; |
} |
//ağırlık fonksiyonunu kullanarak frekansı hesaplayın |
sinyalFrekansTahmin = ((1/toplam) * sinyalFrekans) + ((2/toplam) * sinyalFrekans2) + ((3/toplam) * sinyalFrekans3; // ağırlıklı bir frekans bul |
Serial.print("Çaldığınız nota yaklaşık olarak "); |
Serial.print(signalFrequencyGuess); // Frekans tahminini yazdır. |
Serial.println("Hz."); |
// tahmine göre oktav aralığını bul |
oktavaralığı=3; |
while (!(signalFrequencyGuess >= depolanmışNoteFreq[0]-7 && signalFrequencyGuess <= depolanmışNoteFreq[11]+7)) |
{ |
for(i = 0; ben < 12; ben++) |
{ |
depolananNotFreq = 2 * depolananNotFreq; |
} |
oktavaralığı++; |
} |
//En yakın notu bul |
minDeğer = 10000000; |
notKonum = 0; |
için (i = 0; i < 12; i++) |
{ |
if(minValue> abs(signalFrequencyGuess-storedNoteFreq)) |
{ |
minValue = abs(signalFrequencyGuess-storedNoteFreq); |
notKonum = i; |
} |
} |
//Notu yazdır |
Serial.print("Sanırım oynadınız"); |
if(noteLocation==0) |
{ |
Seri.print("C"); |
} |
else if(noteLocation==1) |
{ |
Serial.print("C#"); |
} |
else if(noteLocation==2) |
{ |
Seri.print("D"); |
} |
else if(noteLocation==3) |
{ |
Seri.print("D#"); |
} |
else if(noteLocation==4) |
{ |
Seri.print("E"); |
} |
else if(noteLocation==5) |
{ |
Seri.print("F"); |
} |
else if(noteLocation==6) |
{ |
Seri.print("F#"); |
} |
else if(noteLocation==7) |
{ |
Seri.print("G"); |
} |
else if(noteLocation==8) |
{ |
Serial.print("G#"); |
} |
else if(noteLocation==9) |
{ |
Seri.print("A"); |
} |
else if(noteLocation==10) |
{ |
Serial.print("A#"); |
} |
else if(noteLocation==11) |
{ |
Seri.print("B"); |
} |
Serial.println(octaveRange); |
} |
//***************************************************************** |
//Burada durun. Yeniden başlatmak için Arduino'daki sıfırlama düğmesine basın |
//***************************************************************** |
iken (1); |
} |
GitHub tarafından ❤ ile barındırılan rawgistfile1.txt dosyasını görüntüle
Adım 3: Müzik Notası Dedektörünü Kurun
Arduino IDE'ye yazılan veya yüklenen kod ile Arduino Uno'yu PC'ye bağlayın. Kodu derleyin ve Arduino'ya yükleyin. Devreyi müzik kaynağına yakın yerleştirin. Not: Tanıtım videosunda, müzik kaynağım olarak PC hoparlörleri ile birlikte tablette kurulu bir uygulama kullanıyorum. Arduino Board üzerindeki sıfırlama düğmesine basın ve ardından müzik kaynağında bir not çalın. Birkaç saniye sonra Müzik Nota Dedektörü çalınan notayı ve frekansını görüntüleyecektir.
Önerilen:
Raspberry Pi - TMD26721 Kızılötesi Dijital Yakınlık Dedektörü Java Eğitimi: 4 Adım
![Raspberry Pi - TMD26721 Kızılötesi Dijital Yakınlık Dedektörü Java Eğitimi: 4 Adım Raspberry Pi - TMD26721 Kızılötesi Dijital Yakınlık Dedektörü Java Eğitimi: 4 Adım](https://i.howwhatproduce.com/images/001/image-58-j.webp)
Raspberry Pi - TMD26721 Kızılötesi Dijital Yakınlık Dedektörü Java Eğitimi: TMD26721, tek bir 8 pimli yüzeye montaj modülünde eksiksiz bir yakınlık algılama sistemi ve dijital arayüz mantığı sağlayan bir kızılötesi dijital yakınlık dedektörüdür. Yakınlık algılama, gelişmiş sinyal-gürültü ve kesinlik. Profesyonel
Su Seviye Dedektörü: 7 Adım
![Su Seviye Dedektörü: 7 Adım Su Seviye Dedektörü: 7 Adım](https://i.howwhatproduce.com/images/001/image-61-j.webp)
Su Seviyesi Dedektörü: Ultrasonik sensör, radar sistemi ile aynı prensipte çalışır. Ultrasonik bir sensör, elektrik enerjisini akustik dalgalara dönüştürebilir ve bunun tersi de mümkündür. Ünlü HC SR04 ultrasonik sensör, 40kHz frekansında ultrasonik dalgalar üretir.Tipik
Zigbee Yatak Varlık Dedektörü: 8 Adım
![Zigbee Yatak Varlık Dedektörü: 8 Adım Zigbee Yatak Varlık Dedektörü: 8 Adım](https://i.howwhatproduce.com/images/001/image-350-j.webp)
Zigbee Yatak Varlığı Dedektörü: Bir süredir yatakta olduğumuzu algılamanın bir yolunu arıyordum. Bu, bu bilgiyi Homeassistant'ta kullanmak içindir. Bu bilgilerle geceleri ışıkları kapatmak için otomasyonlar yapabilirim veya örneğin evimde bir alarm sistemini aktif hale getirebilirim
Duman Dedektörü: 13 Adım
![Duman Dedektörü: 13 Adım Duman Dedektörü: 13 Adım](https://i.howwhatproduce.com/images/001/image-524-j.webp)
Duman Dedektörü: Merhaba arkadaşlar bugün duman dedektörüne bir bakalım Bir çoğunuz AVM'lere gittiniz çoğunlukla duman dedektörü denen bu cihaz dumanı algılar ve sprinkleri açar ve yangını durdurur.Fakat bu projede bu ufak bir değişiklik Bunun yerine
Arduino Müzik Nota Dedektörü: 3 Adım
![Arduino Müzik Nota Dedektörü: 3 Adım Arduino Müzik Nota Dedektörü: 3 Adım](https://i.howwhatproduce.com/images/007/image-20245-j.webp)
Arduino Müzik Nota Dedektörü: Sınırlı bellek ve işlem gücü nedeniyle özellikle Arduino'da sesli sinyalden müzik notalarını algılamak zordur. Genellikle nota, algılamayı zorlaştıran saf bir sinüs dalgası değildir. va'nın frekans dönüşümünü alırsak