Sommario:
- Forniture
- Passaggio 1: costruire l'hardware per il rilevatore di note musicali
- Passaggio 2: programma il rilevatore di note musicali
- Passaggio 3: impostare il rilevatore di note musicali
Video: Rilevatore di note musicali: 3 passaggi
2024 Autore: John Day | [email protected]. Ultima modifica: 2024-01-30 10:00
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