Sommario:
2025 Autore: John Day | [email protected]. Ultima modifica: 2025-01-23 14:49
Stupisci i tuoi amici e familiari con questo progetto che rileva la nota suonata da uno strumento. Questo progetto mostrerà la frequenza approssimativa e la nota musicale suonata su una tastiera elettronica, un'app per pianoforte o qualsiasi altro strumento.
Particolari
Per questo progetto, l'uscita analogica dal rilevatore del modulo sonoro viene inviata all'ingresso analogico A0 dell'Arduino Uno. Il segnale analogico viene campionato e quantizzato (digitalizzato). Il codice di autocorrelazione, ponderazione e sintonizzazione viene utilizzato per trovare la frequenza fondamentale utilizzando i primi 3 periodi. La frequenza fondamentale approssimativa viene quindi confrontata con le frequenze nelle ottave 3, 4 e 5 per determinare la frequenza della nota musicale più vicina. Infine la nota indovinata per la frequenza più vicina viene stampata sullo schermo.
Nota: questa istruzione si concentra solo su come costruire il progetto. Per ulteriori informazioni sui dettagli e le giustificazioni del design, visitare questo collegamento: Ulteriori informazioni
Forniture
- (1) Arduino Uno (o Genuino Uno)
- (1) Modulo di rilevamento del suono ad alta sensibilità del sensore del microfono DEVMO compatibile
- (1) tagliere senza saldatura
- (1) Cavo da USB-A a B
- Ponticelli
- Sorgente musicale (pianoforte, tastiera o app paino con altoparlanti)
- (1) Computer o laptop
Passaggio 1: costruire l'hardware per il rilevatore di note musicali
Utilizzando un Arduino Uno, cavi di connessione, una breadboard senza saldatura e un modulo di rilevamento del suono ad alta sensibilità del sensore del microfono DEVMO (o simile) costruisci il circuito mostrato in questa immagine
Passaggio 2: programma il rilevatore di note musicali
Nell'IDE di Arduino, aggiungi il seguente codice.
gistfile1.txt
| /* |
| Nome file/schizzo: MusicalNoteDetector |
| Versione n.: v1.0 Creata il 7 giugno 2020 |
| Autore originale: Clyde A. Lettsome, PhD, PE, MEM |
| Descrizione: questo codice/schizzo mostra la frequenza approssimativa e la nota musicale suonata su una tastiera elettronica o un'app per pianoforte. Per questo progetto, l'uscita analogica del |
| il rilevatore del modulo sonoro viene inviato all'ingresso analogico A0 di Arduino Uno. Il segnale analogico viene campionato e quantizzato (digitalizzato). Il codice di autocorrelazione, ponderazione e sintonizzazione viene utilizzato per |
| trova la frequenza fondamentale usando i primi 3 periodi. La frequenza fondamentale approssimativa viene quindi confrontata con le frequenze nelle ottave 3, 4 e 5 per determinare il musical più vicino |
| frequenza di nota. Infine la nota indovinata per la frequenza più vicina viene stampata sullo schermo. |
| Licenza: questo programma è un software gratuito; puoi ridistribuirlo e/o modificarlo secondo i termini della GNU General Public License (GPL) versione 3, o successive |
| versione di tua scelta, come pubblicata dalla Free Software Foundation. |
| Note: Copyright (c) 2020 di C. A. Lettsome Services, LLC |
| Per maggiori informazioni visita |
| */ |
| #define SAMPLES 128 //Max 128 per Arduino Uno. |
| #define SAMPLING_FREQUENCY 2048 //Fs = Basato su Nyquist, deve essere 2 volte la frequenza massima prevista. |
| #define OFFSETSAMPLES 40 //usato per scopi di calibrazione |
| #define TUNER -3 //Regola fino a quando C3 è 130.50 |
| periodo di campionamento float; |
| microsecondi lunghi senza segno; |
| int X[CAMPIONI]; //crea un vettore di dimensioni SAMPLES per contenere valori reali |
| float autoCorr[SAMPLES]; //crea un vettore di dimensioni SAMPLES per contenere valori immaginari |
| float storedNoteFreq[12] = {130,81, 138,59, 146,83, 155,56, 164,81, 174,61, 185, 196, 207,65, 220, 233,08, 246,94}; |
| int sommaOffSet = 0; |
| int offSet[CAMPIONI OFFSET]; //crea un vettore di offset |
| int avgOffSet; //crea un vettore di offset |
| int i, k, periodEnd, periodBegin, period, Adjuster, noteLocation, octaveRange; |
| float maxValue, minValue; |
| lunga somma; |
| int soglia = 0; |
| int numOfCycles = 0; |
| float signalFrequency, signalFrequency2, signalFrequency3, signalFrequencyGuess, totale; |
| byte state_machine = 0; |
| int campioniPerPeriod = 0; |
| configurazione nulla() |
| { |
| Serial.begin(115200); //115200 Baud rate per il monitor seriale |
| } |
| ciclo vuoto() |
| { |
| //***************************************************************** |
| //Sezione di calibrazione |
| //***************************************************************** |
| Serial.println("Calatura. Per favore non suonare nessuna nota durante la calibrazione."); |
| for (i = 0; i < CAMPIONI OFFSET; i++) |
| { |
| offSet = analogRead(0); //Legge il valore dal pin analogico 0 (A0), lo quantizza e lo salva come termine reale. |
| //Serial.println(offSet); //usalo per regolare il modulo di rilevamento del suono a circa la metà oa 512 quando non viene riprodotto alcun suono. |
| sommaOffSet = sommaOffSet + offSet; |
| } |
| campioniPerPeriod = 0; |
| valoremax = 0; |
| //***************************************************************** |
| //Prepararsi ad accettare input da A0 |
| //***************************************************************** |
| avgOffSet = round(sumOffSet / OFFSETSAMPLES); |
| Serial.println("Conto alla rovescia."); |
| ritardo(1000); //pausa per 1 secondo |
| Serial.println("3"); |
| ritardo(1000); //pausa per 1 secondo |
| Serial.println("2"); |
| ritardo(1000); //pausa per 1 |
| Serial.println("1"); |
| ritardo(1000); //pausa per 1 secondo |
| Serial.println("Riproduci la tua nota!"); |
| ritardo(250); //pausa di 1/4 di secondo per il tempo di reazione |
| //***************************************************************** |
| //Raccogli i campioni SAMPLES da A0 con il periodo di campionamento del periodo di campionamento |
| //***************************************************************** |
| campionamentoPeriod = 1.0 / SAMPLING_FREQUENCY; //Periodo in microsecondi |
| for (i = 0; i < CAMPIONI; i++) |
| { |
| microSecondi = micros(); //Restituisce il numero di microsecondi da quando la scheda Arduino ha iniziato a eseguire lo script corrente. |
| X = analogRead(0); //Legge il valore dal pin analogico 0 (A0), lo quantizza e lo salva come termine reale. |
| /*tempo di attesa residuo tra i campioni se necessario in secondi */ |
| while (micros() < (microSeconds + (samplingPeriod * 1000000))) |
| { |
| //non fare niente aspetta |
| } |
| } |
| //***************************************************************** |
| //Funzione di autocorrelazione |
| //***************************************************************** |
| for (i = 0; i < SAMPLES; i++) //i=ritardo |
| { |
| somma = 0; |
| for (k = 0; k < SAMPLES - i; k++) // Abbina segnale con segnale ritardato |
| { |
| somma = somma + (((X[k]) - avgOffSet) * ((X[k + i]) - avgOffSet)); //X[k] è il segnale e X[k+i] è la versione ritardata |
| } |
| autoCorr = somma / CAMPIONI; |
| // Primo picco di rilevamento della macchina a stati |
| if (state_machine==0 && i == 0) |
| { |
| soglia = autoCorr * 0.5; |
| state_machine = 1; |
| } |
| else if (state_machine == 1 && i>0 && thresh 0) //state_machine=1, trova 1 punto per l'utilizzo del primo ciclo |
| { |
| maxValue = autoCorr; |
| } |
| else if (state_machine == 1&& i>0 && thresh < autoCorr[i-1] && maxValue == autoCorr[i-1] && (autoCorr-autoCorr[i-1])<=0) |
| { |
| periodoInizio = i-1; |
| state_machine = 2; |
| numOfCycles = 1; |
| campioniPerPeriod = (periodBegin - 0); |
| periodo = campioniPerPeriod; |
| aggiustatore = TUNER+(50.04 * exp(-0.102 * samplePerPeriod)); |
| signalFrequency = ((SAMPLING_FREQUENCY) / (samplesPerPeriod))-regolatore; // f = fs/N |
| } |
| else if (state_machine == 2 && i>0 && thresh 0) //state_machine=2, trova 2 punti per il 1° e il 2° ciclo |
| { |
| maxValue = autoCorr; |
| } |
| else if (state_machine == 2&& i>0 && thresh < autoCorr[i-1] && maxValue == autoCorr[i-1] && (autoCorr-autoCorr[i-1])<=0) |
| { |
| periodoFine = i-1; |
| state_machine = 3; |
| numOfCycles = 2; |
| campioniPerPeriod = (periodEnd - 0); |
| signalFrequency2 = ((numOfCycles*SAMPLING_FREQUENCY) / (samplesPerPeriod))-regolatore; // f = (2*fs)/(2*N) |
| valoremax = 0; |
| } |
| else if (state_machine == 3 && i>0 && thresh 0) //state_machine=3, trova 3 punti per il 1°, 2° e 3° ciclo |
| { |
| maxValue = autoCorr; |
| } |
| else if (state_machine == 3&& i>0 && thresh < autoCorr[i-1] && maxValue == autoCorr[i-1] && (autoCorr-autoCorr[i-1])<=0) |
| { |
| periodoFine = i-1; |
| state_machine = 4; |
| numOfCycles = 3; |
| campioniPerPeriod = (periodEnd - 0); |
| signalFrequency3 = ((numOfCycles*SAMPLING_FREQUENCY) / (samplesPerPeriod))-regolatore; // f = (3*fs)/(3*N) |
| } |
| } |
| //***************************************************************** |
| //Analisi dei risultati |
| //***************************************************************** |
| if (campioniPerPeriod == 0) |
| { |
| Serial.println("Hmm….. non sono sicuro. Stai cercando di ingannarmi?"); |
| } |
| altro |
| { |
| //prepara la funzione di ponderazione |
| totale = 0; |
| if (frequenza del segnale !=0) |
| { |
| totale = 1; |
| } |
| if(frequenza segnale2 !=0) |
| { |
| totale = totale + 2; |
| } |
| if (segnaleFrequenza3 !=0) |
| { |
| totale = totale + 3; |
| } |
| //calcola la frequenza usando la funzione di ponderazione |
| signalFrequencyGuess = ((1/total) * signalFrequency) + ((2/total) * signalFrequency2) + ((3/total) * signalFrequency3); //trova una frequenza ponderata |
| Serial.print("La nota che hai suonato è approssimativamente "); |
| Serial.print(signalFrequencyGuess); //Stampa la stima della frequenza. |
| Serial.println("Hz."); |
| //trova l'intervallo di ottava in base all'ipotesi |
| intervallo di ottava=3; |
| while (!(signalFrequencyGuess >= storedNoteFreq[0]-7 && signalFrequencyGuess <= storedNoteFreq[11]+7)) |
| { |
| for(i = 0; i < 12; i++) |
| { |
| storedNoteFreq = 2 * storedNoteFreq; |
| } |
| intervallo di ottava++; |
| } |
| //Trova la nota più vicina |
| valoremin = 10000000; |
| notaPosizione = 0; |
| per (i = 0; i < 12; i++) |
| { |
| if(minValue> abs(signalFrequencyGuess-storedNoteFreq)) |
| { |
| minValue = abs(signalFrequencyGuess-storedNoteFreq); |
| notaLocation = i; |
| } |
| } |
| //Stampa la nota |
| Serial.print("Penso che tu abbia giocato"); |
| if(notaPosizione==0) |
| { |
| Serial.print("C"); |
| } |
| else if(notaPosizione==1) |
| { |
| Serial.print("C#"); |
| } |
| else if(notaPosizione==2) |
| { |
| Serial.print("D"); |
| } |
| else if(notaPosizione==3) |
| { |
| Serial.print("D#"); |
| } |
| else if(notaPosizione==4) |
| { |
| Serial.print("E"); |
| } |
| else if(notaPosizione==5) |
| { |
| Serial.print("F"); |
| } |
| else if(noteLocation==6) |
| { |
| Serial.print("F#"); |
| } |
| else if(noteLocation==7) |
| { |
| Serial.print("G"); |
| } |
| else if(noteLocation==8) |
| { |
| Serial.print("S#"); |
| } |
| else if(notaPosizione==9) |
| { |
| Serial.print("A"); |
| } |
| else if(notaPosizione==10) |
| { |
| Serial.print("A#"); |
| } |
| else if(noteLocation==11) |
| { |
| Serial.print("B"); |
| } |
| Serial.println(octaveRange); |
| } |
| //***************************************************************** |
| //Fermati qui. Premi il pulsante di ripristino su Arduino per riavviare |
| //***************************************************************** |
| mentre (1); |
| } |
visualizza rawgistfile1.txt ospitato con ❤ da GitHub
Passaggio 3: impostare il rilevatore di note musicali
Collega Arduino Uno al PC con il codice scritto o caricato nell'IDE Arduino. Compila e carica il codice su Arduino. Posizionare il circuito vicino alla sorgente musicale. Nota: nel video introduttivo, utilizzo un'app installata sul tablet insieme agli altoparlanti del PC come sorgente musicale. Premi il pulsante di ripristino sulla scheda Arduino e quindi riproduci una nota sulla sorgente musicale. Dopo alcuni secondi, Musical Note Detector visualizzerà la nota suonata e la sua frequenza.
Consigliato:
Luci di Natale musicali automatiche fai da te (MSGEQ7 + Arduino): 6 passaggi (con immagini)
Luci natalizie musicali automatiche fai-da-te (MSGEQ7 + Arduino): quindi ogni anno dico che lo farò e non lo farò mai perché rimando molto. Il 2020 è un anno di cambiamenti, quindi dico che questo è l'anno per farlo. Quindi spero che ti piaccia e crea le tue luci natalizie musicali. Questo sarà un s
Birilli musicali: 4 passaggi
Birilli musicali: una cosa dell'essere nonni è che sei sempre alla ricerca di modi nuovi ed eccitanti per intrattenere i tuoi meravigliosi nipotini; e in modo tale che ti permetta anche di armeggiare sui tuoi hobby. Entra nel birillo musicale. Utilizzando un ATTiny13 (b
Luci d'atmosfera musicali reattive: 5 passaggi (con immagini)
Music Reactive Mood Lights: Intro and Background. Tornato al primo anno (primavera del 2019), volevo abbellire la mia stanza del dormitorio. Mi è venuta l'idea di costruire le mie luci d'atmosfera che reagissero alla musica che ascoltavo in cuffia. Francamente non ho avuto particolari ispirazioni
Rilevatore di note musicali Arduino: 3 passaggi
Rilevatore di note musicali Arduino: rilevare le note musicali dal segnale audio è difficile soprattutto su Arduino a causa della memoria e della potenza di elaborazione limitate. In genere, la nota non è un'onda sinusoidale pura che rende difficile il rilevamento. Se prendiamo la trasformata di frequenza di va
Rilevatore di fumo IOT: aggiorna il rilevatore di fumo esistente con IOT: 6 passaggi (con immagini)
Rilevatore di fumo IOT: aggiorna il rilevatore di fumo esistente con IOT: elenco dei contributori, Inventore: Tan Siew Chin, Tan Yit Peng, Tan Wee Heng Supervisore: Dr Chia Kim Seng Dipartimento di ingegneria meccatronica e robotica, Facoltà di ingegneria elettrica ed elettronica, Universiti Tun Hussein Onn Malaysia.Distribuzione
