Spisu treści:
2025 Autor: John Day | [email protected]. Ostatnio zmodyfikowany: 2025-01-23 15:02
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
