Tartalomjegyzék:
- Szerző John Day [email protected].
- Public 2024-01-30 09:39.
- Utoljára módosítva 2025-01-23 14:47.
Lepje meg barátait és családját ezzel a projekttel, amely érzékeli a hangszer által játszott hangot. Ez a projekt megjeleníti a hozzávetőleges gyakoriságot, valamint az elektronikus billentyűzeten, zongoraalkalmazásban vagy bármely más hangszeren játszott hangot.
Részletek
Ehhez a projekthez a hangmodul -érzékelő analóg kimenete az Arduino Uno A0 analóg bemenetére kerül. Az analóg jel mintavételezése és kvantálása (digitalizálása) történik. Az autokorreláció, a súlyozás és a hangolási kód az alapvető frekvencia megtalálására szolgál az első 3 periódus használatával. A hozzávetőleges alapfrekvenciát ezután összehasonlítják a 3., 4. és 5. oktáv frekvenciájával, hogy meghatározzák a legközelebbi hangjegy gyakoriságát. Végül a legközelebbi frekvencia találgatott megjegyzése kerül a képernyőre.
Megjegyzés: Ez az utasítás csak a projekt felépítésére összpontosít. A részletekről és a tervezés indoklásáról bővebb információt ezen a linken talál: További információ
Kellékek
- (1) Arduino Uno (vagy Genuino Uno)
- (1) A DEVMO mikrofonérzékelő nagy érzékenységű hangérzékelő modullal kompatibilis
- (1) Forrasztás nélküli kenyértábla
- (1) USB-A-B kábel
- Jumper vezetékek
- Zenei forrás (zongora, billentyűzet vagy súlyalkalmazás hangszórókkal)
- (1) Számítógép vagy laptop
1. lépés: Készítse el a hangjegy -érzékelő hardverét
Az Arduino Uno, csatlakozóvezetékek, forrasztás nélküli kenyértábla és DEVMO mikrofonérzékelő nagy érzékenységű hangfelismerő modul (vagy hasonló) segítségével állítsa össze az ezen az ábrán látható áramkört
2. lépés: Programozza a hangjegy -érzékelőt
Az Arduino IDE -ben adja hozzá a következő kódot.
gistfile1.txt
| /* |
| Fájl/vázlat neve: MusicalNoteDetector |
| Verziószám: v1.0 Létrehozva: 2020. június 7 |
| Eredeti szerző: Clyde A. Lettsome, PhD, PE, MEM |
| Leírás: Ez a kód/vázlat megjeleníti a hozzávetőleges gyakoriságot, valamint az elektronikus billentyűzeten vagy zongoraalkalmazásban lejátszott hangot. Ehhez a projekthez az analóg kimenet a |
| hangmodul érzékelőt küld az Arduino Uno A0 analóg bemenetére. Az analóg jel mintavételezése és kvantálása (digitalizálása) történik. Az autokorrelációs, súlyozási és hangolási kódot használják |
| megtalálja az alapvető gyakoriságot az első 3 periódus használatával. A hozzávetőleges alapfrekvenciát ezután összehasonlítják a 3., 4. és 5. oktáv frekvenciájával, hogy meghatározzák a legközelebbi zenét |
| megjegyzés gyakorisága. Végül a legközelebbi frekvencia találgatott megjegyzése kerül a képernyőre. |
| Licenc: Ez a program ingyenes szoftver; újra terjesztheti és/vagy módosíthatja a GNU General Public License (GPL) 3. verziója vagy bármely későbbi feltétele szerint |
| az Ön által választott verzió, amint azt a Free Software Foundation közzétette. |
| Megjegyzések: Szerzői jog (c) 2020, C. A. Lettsome Services, LLC |
| További információ: |
| */ |
| #define MINTÁK 128 // Maximum 128 az Arduino Uno számára. |
| #define SAMPLING_FREQUENCY 2048 // Fs = Nyquist alapján kétszer a legmagasabb várható gyakoriságnak kell lennie. |
| #define OFFSETSAMPLES 40 // kalabázási célokra használják |
| #define TUNER -3 // Állítsa be, amíg a C3 értéke 130,50 |
| float samplingPeriod; |
| előjel nélküli hosszú mikroszekundumok; |
| int X [MINTÁK]; // MINTA méretű vektor készítése valós értékek tárolására |
| úszó autoCorr [MINTÁK]; // minták méretű vektor létrehozása képzeletbeli értékek tárolására |
| float storageNoteFreq [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 offSet [OFFSETSAMPLES]; // offset vektor létrehozása |
| int avgOffSet; // offset vektor létrehozása |
| int i, k, periodEnd, periodBegin, period, Adjuster, noteLocation, oktávRange; |
| float maxValue, minValue; |
| hosszú összeg; |
| int thresh = 0; |
| int numOfCycles = 0; |
| float signalFrequency, signalFrequency2, signalFrequency3, signalFrequencyGuess, total; |
| bájt állapot_gép = 0; |
| int mintákPerPeriod = 0; |
| üres beállítás () |
| { |
| Sorozat.kezdet (115200); // 115200 Baud arány a soros monitorhoz |
| } |
| üres hurok () |
| { |
| //***************************************************************** |
| // Kalabrációs szakasz |
| //***************************************************************** |
| Serial.println ("Calabrating. Kérjük, ne játsszon semmilyen hangot a calabration alatt."); |
| for (i = 0; i <OFFSETSAMPLES; i ++) |
| { |
| offSet = analóg olvasás (0); // Kiolvassa az értéket a 0 analóg tűből (A0), kvantálja és mentse el valós kifejezésként. |
| //Serial.println(offSet); // ezzel állíthatja be a hangérzékelő modult körülbelül felére vagy 512 -re, ha nincs hang. |
| sumOffSet = sumOffSet + offSet ; |
| } |
| samplePerPeriod = 0; |
| maxValue = 0; |
| //***************************************************************** |
| // Készüljön fel az A0 bemenetének elfogadására |
| //***************************************************************** |
| avgOffSet = kerek (sumOffSet / OFFSETSAMPLES); |
| Serial.println ("Visszaszámlálás."); |
| késleltetés (1000); // szünet 1 másodpercig |
| Serial.println ("3"); |
| késleltetés (1000); // szünet 1 másodpercig |
| Serial.println ("2"); |
| késleltetés (1000); // szünet 1 |
| Serial.println ("1"); |
| késleltetés (1000); // szünet 1 másodpercig |
| Serial.println ("Játszd a jegyzeted!"); |
| késleltetés (250); // szünet 1/4 másodperc a reakcióidő érdekében |
| //***************************************************************** |
| // SAMPLES minták gyűjtése az A0 -ból a mintavételi időszak mintavételi időszakával |
| //***************************************************************** |
| samplingPeriod = 1.0 / SAMPLING_FREQUENCY; // Periódus mikroszekundumokban |
| for (i = 0; i <MINTAK; i ++) |
| { |
| microSeconds = micros (); // Visszaadja a mikroszekundumok számát azóta, hogy az Arduino kártya elkezdte futtatni az aktuális szkriptet. |
| X = analógOlvasás (0); // Kiolvassa az értéket a 0 analóg tűből (A0), kvantálja és mentse el valós kifejezésként. |
| / *hátralévő várakozási idő a minták között, ha szükséges másodpercekben */ |
| míg (micros () <(microSeconds + (samplingPeriod * 1000000))) |
| { |
| // ne csinálj semmit csak várj |
| } |
| } |
| //***************************************************************** |
| // Autokorrelációs függvény |
| //***************************************************************** |
| for (i = 0; i <MINTAK; i ++) // i = késleltetés |
| { |
| összeg = 0; |
| for (k = 0; k <MINTÁK - i; k ++) // Párosítsa a jelet a késleltetett jellel |
| { |
| összeg = összeg + (((X [k]) - avgOffSet) * ((X [k + i]) - avgOffSet)); // X [k] a jel, X [k+i] pedig a késleltetett verzió |
| } |
| autoCorr = összeg / MINTA; |
| // Első csúcsérzékelő állapotgép |
| ha (állapot_gép == 0 && i == 0) |
| { |
| cséplés = autoCorr * 0,5; |
| állapot_gép = 1; |
| } |
| egyébként if (state_machine == 1 && i> 0 && thresh 0) // state_machine = 1, keressen 1 pontot az első ciklus használatához |
| { |
| maxValue = autoCorr ; |
| } |
| különben ha (állapot_gép == 1 && i> 0 && thresh <autoCorr [i-1] && maxValue == autoCorr [i-1] && (autoCorr -autoCorr [i-1]) <= 0) |
| { |
| periodBegin = i-1; |
| állapot_gép = 2; |
| numOfCycles = 1; |
| mintákPerPeriod = (periodBegin - 0); |
| időszak = mintákPerPeriod; |
| beállító = TUNER+(50,04 * exp (-0,102 * mintaperiódus)); |
| signalFrequency = ((SAMPLING_FREQUENCY) / (samplePerPeriod))-beállító; // f = fs/N |
| } |
| egyébként if (state_machine == 2 && i> 0 && thresh 0) // state_machine = 2, keress 2 periódust az 1. és a 2. ciklushoz |
| { |
| maxValue = autoCorr ; |
| } |
| különben ha (állapot_gép == 2 && i> 0 && thresh <autoCorr [i-1] && maxValue == autoCorr [i-1] && (autoCorr -autoCorr [i-1]) <= 0) |
| { |
| periodEnd = i-1; |
| állapot_gép = 3; |
| numOfCycles = 2; |
| mintákPerPeriod = (periodEnd - 0); |
| signalFrequency2 = (((számOfCycles*SAMPLING_FREQUENCY) / (samplePerPeriod))-beállító; // f = (2*fs)/(2*N) |
| maxValue = 0; |
| } |
| egyébként if (state_machine == 3 && i> 0 && thresh 0) // state_machine = 3, keress 3 periódust az 1., 2. és 3. ciklushoz |
| { |
| maxValue = autoCorr ; |
| } |
| egyébként ha (állapot_gép == 3 && i> 0 && thresh <autoCorr [i-1] && maxValue == autoCorr [i-1] && (autoCorr -autoCorr [i-1]) <= 0) |
| { |
| periodEnd = i-1; |
| állapot_gép = 4; |
| numOfCycles = 3; |
| mintákPerPeriod = (periodEnd - 0); |
| signalFrequency3 = (((számOfCycles*SAMPLING_FREQUENCY) / (samplePerPeriod))-beállító; // f = (3*fs)/(3*N) |
| } |
| } |
| //***************************************************************** |
| // Eredményelemzés |
| //***************************************************************** |
| if (samplePerPeriod == 0) |
| { |
| Serial.println ("Hmm ….. Nem vagyok biztos benne. Meg akar csalni?"); |
| } |
| más |
| { |
| // előkészíti a súlyozási függvényt |
| összesen = 0; |
| ha (signalFrequency! = 0) |
| { |
| összesen = 1; |
| } |
| ha (signalFrequency2! = 0) |
| { |
| összesen = összesen + 2; |
| } |
| ha (signalFrequency3! = 0) |
| { |
| összesen = összesen + 3; |
| } |
| // a gyakoriság kiszámítása a súlyozási funkció segítségével |
| signalFrequencyGuess = ((1/összesen) * jelFrekvencia) + ((2/összesen) * jelFrekvencia2) + ((3/összesen) * jelFrekvencia3); // súlyozott gyakoriság keresése |
| Serial.print ("A lejátszott hang kb."); |
| Serial.print (signalFrequencyGuess); // Nyomtassa ki a gyakorisági tippet. |
| Soros.println ("Hz"); |
| // oktávtartomány megtalálása a találgatás alapján |
| oktávRange = 3; |
| while (! (signalFrequencyGuess> = storageNoteFreq [0] -7 && signalFrequencyGuess <= storageNoteFreq [11] +7)) |
| { |
| mert (i = 0; i <12; i ++) |
| { |
| storageNoteFreq = 2 * storageNoteFreq ; |
| } |
| oktávRange ++; |
| } |
| // Keresse meg a legközelebbi jegyzetet |
| minValue = 10000000; |
| noteLocation = 0; |
| mert (i = 0; i <12; i ++) |
| { |
| if (minValue> abs (signalFrequencyGuess-storageNoteFreq )) |
| { |
| minValue = abs (signalFrequencyGuess-storageNoteFreq ); |
| noteLocation = i; |
| } |
| } |
| // Nyomtassa ki a jegyzetet |
| Serial.print ("Azt hiszem, játszottál"); |
| if (noteLocation == 0) |
| { |
| Soros.nyomtatás ("C"); |
| } |
| egyébként ha (noteLocation == 1) |
| { |
| Serial.print ("C#"); |
| } |
| egyébként ha (noteLocation == 2) |
| { |
| Serial.print ("D"); |
| } |
| egyébként ha (noteLocation == 3) |
| { |
| Serial.print ("D#"); |
| } |
| egyébként ha (noteLocation == 4) |
| { |
| Serial.print ("E"); |
| } |
| egyébként ha (noteLocation == 5) |
| { |
| Serial.print ("F"); |
| } |
| egyébként ha (noteLocation == 6) |
| { |
| Serial.print ("F#"); |
| } |
| egyébként ha (noteLocation == 7) |
| { |
| Serial.print ("G"); |
| } |
| egyébként ha (noteLocation == 8) |
| { |
| Serial.print ("G#"); |
| } |
| egyébként ha (noteLocation == 9) |
| { |
| Serial.print ("A"); |
| } |
| egyébként ha (noteLocation == 10) |
| { |
| Serial.print ("A#"); |
| } |
| egyébként ha (noteLocation == 11) |
| { |
| Serial.print ("B"); |
| } |
| Serial.println (octaveRange); |
| } |
| //***************************************************************** |
| //Állj meg itt. Az újraindításhoz nyomja meg az Arduino reset gombját |
| //***************************************************************** |
| míg (1); |
| } |
nézd meg a rawgistfile1.txt fájlt, amelyet a GitHub ❤ üzemeltet
3. lépés: Állítsa be a hangjegy -érzékelőt
Csatlakoztassa az Arduino Uno -t a számítógéphez az Arduino IDE -be írt vagy betöltött kóddal. Fordítsa össze és töltse fel a kódot az Arduino -ba. Helyezze az áramkört a zeneforrás közelébe. Megjegyzés: A bemutatkozó videóban a táblagépre telepített alkalmazást használom a számítógép hangszóróival együtt zeneforrásként. Nyomja meg az Arduino Board alaphelyzetbe állító gombját, majd játssza le a zenei forrást. Néhány másodperc múlva a hangjegy -érzékelő megjeleníti a lejátszott hangot és annak gyakoriságát.
Ajánlott:
DC - DC feszültség Lépés lekapcsoló mód Buck feszültségátalakító (LM2576/LM2596): 4 lépés
DC-DC feszültség Lépés lekapcsoló üzemmód Buck feszültségátalakító (LM2576/LM2596): A rendkívül hatékony bakkonverter készítése nehéz feladat, és még a tapasztalt mérnököknek is többféle kivitelre van szükségük, hogy a megfelelőt hozzák létre. egy DC-DC áramátalakító, amely csökkenti a feszültséget (miközben növeli
Akusztikus levitáció az Arduino Uno-val Lépésről lépésre (8 lépés): 8 lépés
Akusztikus lebegés az Arduino Uno-val Lépésről lépésre (8 lépés): ultrahangos hangátvivők L298N Dc női adapter tápegység egy egyenáramú tűvel Arduino UNOBreadboard és analóg portok a kód konvertálásához (C ++)
Élő 4G/5G HD videó streamelés DJI drónról alacsony késleltetéssel [3 lépés]: 3 lépés
Élő 4G/5G HD videó streaming a DJI Drone-tól alacsony késleltetéssel [3 lépés]: Az alábbi útmutató segít abban, hogy szinte bármilyen DJI drónról élő HD minőségű videó streameket kapjon. A FlytOS mobilalkalmazás és a FlytNow webes alkalmazás segítségével elindíthatja a videó streamingjét a drónról
Bolt - DIY vezeték nélküli töltő éjszakai óra (6 lépés): 6 lépés (képekkel)
Bolt - DIY vezeték nélküli töltés éjszakai óra (6 lépés): Az induktív töltés (más néven vezeték nélküli töltés vagy vezeték nélküli töltés) a vezeték nélküli áramátvitel egyik típusa. Elektromágneses indukciót használ a hordozható eszközök áramellátásához. A leggyakoribb alkalmazás a Qi vezeték nélküli töltő
4 lépés az akkumulátor belső ellenállásának méréséhez: 4 lépés
4 lépés az akkumulátor belső ellenállásának mérésére: Íme a 4 egyszerű lépés, amelyek segítenek mérni az akkumulátor belső ellenállását
