Spisu treści:
- Kieszonkowe dzieci
- Krok 1: Zbuduj sprzęt dla wykrywacza nut
- Krok 2: Zaprogramuj wykrywacz nut
- Krok 3: Skonfiguruj wykrywacz nut
Wideo: Wykrywacz nut: 3 kroki
2024 Autor: John Day | [email protected]. Ostatnio zmodyfikowany: 2024-01-30 11:27
Zaskocz swoich przyjaciół i rodzinę dzięki temu projektowi, który wykrywa nutę graną przez instrument. Ten projekt wyświetli przybliżoną częstotliwość, a także nutę graną na klawiaturze elektronicznej, aplikacji na fortepian lub dowolnym innym instrumencie.
Detale
W tym projekcie wyjście analogowe z detektora modułu dźwiękowego jest przesyłane do wejścia analogowego A0 Arduino Uno. Sygnał analogowy jest próbkowany i kwantyzowany (cyfryzowany). Kod autokorelacji, ważenia i strojenia jest używany do znalezienia podstawowej częstotliwości przy użyciu pierwszych 3 okresów. Przybliżona częstotliwość podstawowa jest następnie porównywana z częstotliwościami w zakresie oktaw 3, 4 i 5 w celu określenia najbliższej częstotliwości nuty muzycznej. Na koniec na ekranie wyświetlana jest odgadnięta nuta dla najbliższej częstotliwości.
Uwaga: ta instrukcja koncentruje się tylko na tym, jak zbudować projekt. Aby uzyskać więcej informacji o szczegółach i uzasadnieniu projektu, odwiedź ten link: Więcej informacji
Kieszonkowe dzieci
- (1) Arduino Uno (lub Genuino Uno)
- (1) Czujnik mikrofonu DEVMO Kompatybilny z modułem wykrywania dźwięku o wysokiej czułości
- (1) Płytka chlebowa bez lutowania
- (1) kabel USB-A do B
- Przewody połączeniowe
- Źródło muzyczne (fortepian, klawiatura lub aplikacja paino z głośnikami)
- (1) Komputer lub laptop
Krok 1: Zbuduj sprzęt dla wykrywacza nut
Za pomocą Arduino Uno, przewodów połączeniowych, płytki stykowej bez lutowania i modułu wykrywania dźwięku o wysokiej czułości DEVMO (lub podobnego) skonstruuj obwód pokazany na tym obrazie
Krok 2: Zaprogramuj wykrywacz nut
W Arduino IDE dodaj następujący kod.
plik_gist1.txt
/* |
Nazwa pliku/szkicu: MusicalNoteDetector |
Wersja nr: v1.0 Utworzono 7 czerwca 2020 r. |
Autor oryginalny: Clyde A. Lettsome, PhD, PE, MEM |
Opis: ten kod/szkic wyświetla przybliżoną częstotliwość oraz nutę graną na klawiaturze elektronicznej lub w aplikacji na fortepian. W tym projekcie wyjście analogowe z |
detektor modułu dźwiękowego jest wysyłany na wejście analogowe A0 Arduino Uno. Sygnał analogowy jest próbkowany i kwantyzowany (cyfryzowany). Kod autokorelacji, ważenia i strojenia służy do |
znajdź częstotliwość podstawową używając pierwszych 3 okresów. Przybliżona częstotliwość podstawowa jest następnie porównywana z częstotliwościami w zakresie oktaw 3, 4 i 5 w celu określenia najbliższego musicalu |
częstotliwość nut. Na koniec na ekranie wyświetlana jest odgadnięta nuta dla najbliższej częstotliwości. |
Licencja: Ten program jest darmowym oprogramowaniem; możesz go redystrybuować i/lub modyfikować zgodnie z warunkami licencji GNU General Public License (GPL) w wersji 3 lub dowolnej późniejszej |
wybraną przez Ciebie wersję opublikowaną przez Free Software Foundation. |
Uwagi: Copyright (c) 2020 przez CA Lettsome Services, LLC |
Więcej informacji na stronie |
*/ |
#define SAMPLES 128 //Max 128 dla Arduino Uno. |
#define SAMPLING_FREQUENCY 2048 //Fs = Na podstawie Nyquista, musi być 2 razy większa od oczekiwanej częstotliwości. |
#define OFFSETSAMPLES 40 //używane do celów kalibracyjnych |
#define TUNER -3 //Dostosuj, aż C3 wyniesie 130,50 |
okres próbkowania pływaka; |
długie mikrosekundy bez znaku; |
int X[PRÓBKI]; //utwórz wektor o rozmiarze SAMPLES do przechowywania rzeczywistych wartości |
zmiennoprzecinkowa autoKorr[PRÓBKI]; //utwórz wektor o rozmiarze SAMPLES do przechowywania urojonych wartości |
zmiennoprzecinkowa przechowywanaCzęst.noty[12] = {130,81, 138,59, 146,83, 155,56, 164,81, 174,61, 185, 196, 207,65, 220, 233,08, 246,94}; |
int sumOffSet = 0; |
int przesunięte[PRÓBKI PRZESUNIĘCIA]; //utwórz wektor przesunięcia |
int avgOffset; //utwórz wektor przesunięcia |
int i, k, koniec okresu, początek okresu, okres, regulator, lokalizacja notatki, zakres oktawy; |
float maxValue, minValue; |
długa suma; |
int próg = 0; |
int liczba cykli = 0; |
float częstotliwość sygnału, częstotliwość sygnału2, częstotliwość sygnału3, częstotliwość sygnałuGuess, suma; |
bajt stan_maszyna = 0; |
int samplePerPeriod = 0; |
pusta konfiguracja() |
{ |
Serial.początek(115200); //115200 Szybkość transmisji dla monitora szeregowego |
} |
pusta pętla() |
{ |
//***************************************************************** |
//Sekcja Kalibracji |
//***************************************************************** |
Serial.println("Kalibracja. Proszę nie odtwarzać żadnych notatek podczas kalibrowania."); |
dla (i = 0; i <PRÓBKI PRZESUNIĘCIA; i++) |
{ |
offset = odczyt analogowy(0); //Odczytuje wartość z pinu analogowego 0 (A0), kwantyzuje ją i zapisuje jako rzeczywisty termin. |
//Serial.println(offSet); //użyj tego, aby ustawić moduł wykrywania dźwięku na około połowę lub 512, gdy dźwięk nie jest odtwarzany. |
sumOffSet = sumOffSet + offSet; |
} |
samplePerPeriod = 0; |
maxWartość = 0; |
//***************************************************************** |
//Przygotuj się do przyjęcia danych wejściowych z A0 |
//***************************************************************** |
avgOffSet = round(sumOffSet / OFFSETSAMPLES); |
Serial.println("Odliczanie."); |
opóźnienie (1000); //pauza na 1 sekundę |
Serial.println("3"); |
opóźnienie (1000); //pauza na 1 sekundę |
Serial.println("2"); |
opóźnienie (1000); //pauza na 1 |
Serial.println("1"); |
opóźnienie (1000); //pauza na 1 sekundę |
Serial.println("Odtwórz swoją notatkę!"); |
opóźnienie(250); //pauza na 1/4 sekundy dla czasu reakcji |
//***************************************************************** |
//Pobierz próbki z A0 z próbnym okresem próbkowaniaOkres próbkowania |
//***************************************************************** |
Okres próbkowania = 1,0 / CZĘSTOTLIWOŚĆ PRÓBOWANIA; //Okres w mikrosekundach |
dla (i = 0; i < PRÓBKI; i++) |
{ |
mikrosekundy = mikros(); //Zwraca liczbę mikrosekund od rozpoczęcia bieżącego skryptu na płycie Arduino. |
X = odczyt analogowy(0); //Odczytuje wartość z pinu analogowego 0 (A0), kwantyzuje ją i zapisuje jako rzeczywisty termin. |
/*pozostały czas oczekiwania między próbkami, jeśli to konieczne w sekundach */ |
while (mikros() < (mikrosekundy + (okres próbkowania * 1000000))) |
{ |
//nic nie rób tylko czekaj |
} |
} |
//***************************************************************** |
//Funkcja autokorelacji |
//***************************************************************** |
for (i = 0; i < PRÓBKI; i++) //i=opóźnienie |
{ |
suma = 0; |
for (k = 0; k < PRÓBKI - i; k++) //Dopasuj sygnał z opóźnionym sygnałem |
{ |
suma = suma + (((X[k]) - avgOffSet) * ((X[k + i]) - avgOffSet)); //X[k] to sygnał, a X[k+i] to wersja opóźniona |
} |
autoCorr = suma / PRÓBKI; |
// Maszyna stanu pierwszego wykrycia szczytu |
if (state_machine==0 && i == 0) |
{ |
thresh = autoCorr * 0,5; |
maszyna_stanowa = 1; |
} |
w przeciwnym razie if (state_machine == 1 && i>0 && thresh 0) //state_machine=1, znajdź 1 okres na użycie pierwszego cyklu |
{ |
maxValue = autoCorr; |
} |
else if (state_machine == 1&& i>0 && thresh < autoCorr[i-1] && maxValue == autoCorr[i-1] && (autoCorr-autoCorr[i-1])<=0) |
{ |
Początek okresu = i-1; |
maszyna_stanowa = 2; |
liczbaCykli = 1; |
samplePerPeriod = (okresPoczątek - 0); |
okres = samplePerPeriod; |
regulator = TUNER+(50.04 * exp(-0.102 * samplePerPeriod)); |
signalFrequency = ((SAMPLING_FREQUENCY) / (samplesPerPeriod))-regulator; // f = fs/N |
} |
else if (state_machine == 2 && i>0 && thresh 0) //state_machine=2, znajdź 2 okresy dla 1. i 2. cyklu |
{ |
maxValue = autoCorr; |
} |
else if (state_machine == 2&& i>0 && thresh < autoCorr[i-1] && maxValue == autoCorr[i-1] && (autoCorr-autoCorr[i-1])<=0) |
{ |
koniec okresu = i-1; |
maszyna_stanowa = 3; |
liczbaCykli = 2; |
samplePerPeriod = (periodEnd - 0); |
signalFrequency2 = ((numOfCycles*SAMPLING_CREQUENCY) / (samplesPerPeriod))-regulator; // f = (2*fs)/(2*N) |
maxWartość = 0; |
} |
else if (state_machine == 3 && i>0 && thresh 0) //state_machine=3, znajdź 3 okresy dla 1., 2. i 3. cyklu |
{ |
maxValue = autoCorr; |
} |
else if (state_machine == 3&& i>0 && thresh < autoCorr[i-1] && maxValue == autoCorr[i-1] && (autoCorr-autoCorr[i-1])<=0) |
{ |
koniec okresu = i-1; |
maszyna_stanowa = 4; |
liczbaCykli = 3; |
samplePerPeriod = (periodEnd - 0); |
signalFrequency3 = ((numOfCycles*SAMPLING_CREQUENCY) / (samplesPerPeriod))-regulator; // f = (3*fs)/(3*N) |
} |
} |
//***************************************************************** |
//Analiza wyników |
//***************************************************************** |
jeśli (próbki na okres == 0) |
{ |
Serial.println("Hmm….. Nie jestem pewien. Próbujesz mnie oszukać?"); |
} |
w przeciwnym razie |
{ |
//przygotuj funkcję ważenia |
suma = 0; |
jeśli (częstotliwość sygnału !=0) |
{ |
suma = 1; |
} |
if(Częstotliwość Sygnału2 !=0) |
{ |
suma = suma + 2; |
} |
jeśli (Częstotliwość Sygnału3 !=0) |
{ |
suma = suma + 3; |
} |
//oblicz częstotliwość za pomocą funkcji ważenia |
częstotliwośćsygnałuGuess = ((1/całkowita) * częstotliwośćsygnału) + ((2/całkowita) * częstotliwośćsygnału2) + ((3/całkowita) * częstotliwośćsygnału3); //znajdź częstotliwość ważoną |
Serial.print("Zagrana nuta to około "); |
Serial.print(ZgadywanieCzęstotliwości Sygnału); //Wydrukuj przewidywaną częstotliwość. |
Serial.println("Hz."); |
//znajdź zakres oktaw na podstawie przypuszczenia |
oktawaZakres=3; |
while (!(signalFrequencyGuess >= zapisany NoteFreq[0]-7 && signalFrequencyGuess <= zapisanyNoteFreq[11]+7)) |
{ |
dla(i = 0; i < 12; i++) |
{ |
zapisanyCzęstUwag = 2 * zapisanyCzęstUwag; |
} |
zakres oktawy++; |
} |
//Znajdź najbliższą notatkę |
minWartość = 10000000; |
uwagaLokalizacja = 0; |
dla (i = 0; i < 12; i++) |
{ |
if(minValue> abs(sygnałCzęstotliwośćGuess-przechowywanaCzęstoUwagi)) |
{ |
minValue = abs(zapisanaCzęstotliwośćSygnałówGuess-NoteFreq); |
uwagaLokalizacja = ja; |
} |
} |
//Wydrukuj notatkę |
Serial.print("Myślę, że grałeś"); |
if(noteLokalizacja==0) |
{ |
Serial.print("C"); |
} |
inaczej if(noteLocation==1) |
{ |
Serial.print("C#"); |
} |
inaczej if(noteLocation==2) |
{ |
Serial.print("D"); |
} |
w przeciwnym razie, jeśli(noteLocation==3) |
{ |
Serial.print("D#"); |
} |
inaczej if(noteLocation==4) |
{ |
Serial.print("E"); |
} |
inaczej if(noteLocation==5) |
{ |
Serial.print("F"); |
} |
inaczej if(noteLocation==6) |
{ |
Serial.print("F#"); |
} |
inaczej if(noteLocation==7) |
{ |
Serial.print("G"); |
} |
inaczej if(noteLocation==8) |
{ |
Serial.print("G#"); |
} |
inaczej if(noteLocation==9) |
{ |
Serial.print("A"); |
} |
w przeciwnym razie, jeśli(noteLocation==10) |
{ |
Serial.print("A#"); |
} |
inaczej if(noteLocation==11) |
{ |
Serial.print("B"); |
} |
Serial.println(zakres oktawy); |
} |
//***************************************************************** |
//Zatrzymaj się tutaj. Naciśnij przycisk resetowania na Arduino, aby ponownie uruchomić |
//***************************************************************** |
natomiast (1); |
} |
wyświetl rawgistfile1.txt hostowany z ❤ przez GitHub
Krok 3: Skonfiguruj wykrywacz nut
Podłącz Arduino Uno do komputera za pomocą kodu zapisanego lub załadowanego w Arduino IDE. Skompiluj i prześlij kod do Arduino. Umieść obwód blisko źródła muzyki. Uwaga: w filmie wprowadzającym używam aplikacji zainstalowanej na tablecie w połączeniu z głośnikami komputera jako źródła muzyki. Naciśnij przycisk resetowania na płycie Arduino, a następnie odtwórz notatkę na źródle muzyki. Po kilku sekundach Musical Note Detector wyświetli odtwarzaną nutę i jej częstotliwość.
Zalecana:
Wykrywacz metalu DIY Arduino Pin Pointer: 3 kroki
Wykrywacz metalu DIY Arduino Pin Pointer: Tradycyjny wykrywacz metalu może zlokalizować zakopany przedmiot i podać przybliżone położenie obiektu pod ziemią Pinpointer umożliwia ustalenie lokalizacji obiektu, wykonanie mniejszego otworu podczas kopania i wyodrębnienie przedmiotu . Może też
Wykrywacz dystansu społecznego: 4 kroki
Wykrywacz dystansu społecznego: To urządzenie pomaga utrzymać odległość 1 metra od ludzi (lub ryzykujesz utratę słuchu)
Wykrywacz napięcia Arduino AC 220V/110V: 3 kroki
Wykrywacz napięcia Arduino AC 220 V / 110 V: Czasami, gdy mamy projekt inteligentnego domu, potrzebujemy również systemu do monitorowania, czy urządzenie naprawdę się włącza, czy też możemy chcieć stworzyć system tylko do wykrywania i rejestrowania, czy maszyna lub urządzenie jest włączone. Ten problem można rozwiązać za pomocą
Wykrywacz nut Arduino: 3 kroki
Wykrywacz nut Arduino: Wykrywanie nut z sygnału audio jest trudne do wykonania, szczególnie w przypadku Arduino ze względu na ograniczoną pamięć i moc obliczeniową. Ogólnie rzecz biorąc, nuta nie jest czystą falą sinusoidalną, co utrudnia wykrycie. Jeśli weźmiemy transformację częstotliwości va
Wykrywacz dymu IOT: Zaktualizuj istniejący wykrywacz dymu za pomocą IOT: 6 kroków (ze zdjęciami)
IOT Smoke Detector: Update Existing Smoke Detector With IOT: List of contributor,Inventor:Tan Siew Chin, Tan Yit Peng, Tan Wee Heng Kierownik: Dr Chia Kim Seng Wydział Inżynierii Mechatroniki i Robotyki, Wydział Inżynierii Elektrycznej i Elektronicznej, Universiti Tun Hussein Onn Malezja.Dystrybuuj