Índice:
- Suprimentos
- Etapa 1: construir o hardware para o detector de notas musicais
- Etapa 2: programe o detector de notas musicais
- Etapa 3: configurar o detector de notas musicais
Vídeo: Detector de notas musicais: 3 etapas
2024 Autor: John Day | [email protected]. Última modificação: 2024-01-30 11:35
Surpreenda seus amigos e familiares com este projeto que detecta a nota tocada por um instrumento. Este projeto exibirá a frequência aproximada, bem como a nota musical tocada em um teclado eletrônico, aplicativo de piano ou qualquer outro instrumento.
Detalhes
Para este projeto, a saída analógica do detector do módulo de som é enviada para a entrada analógica A0 do Arduino Uno. O sinal analógico é amostrado e quantizado (digitalizado). Código de autocorrelação, ponderação e sintonia é usado para encontrar a frequência fundamental usando os primeiros 3 períodos. A frequência fundamental aproximada é então comparada às frequências nas oitavas 3, 4 e 5 para determinar a frequência de nota musical mais próxima. Finalmente, a nota adivinhada para a frequência mais próxima é impressa na tela.
Nota: Este instrutível se concentra apenas em como construir o projeto. Para obter mais informações sobre os detalhes e justificativas do projeto, visite este link: Mais informações
Suprimentos
- (1) Arduino Uno (ou Genuino Uno)
- (1) Módulo de detecção de som de alta sensibilidade do sensor de microfone DEVMO compatível
- (1) Placa de ensaio sem solda
- (1) Cabo USB-A para B
- Fios de ligação
- Fonte musical (piano, teclado ou app paino com alto-falantes)
- (1) Computador ou laptop
Etapa 1: construir o hardware para o detector de notas musicais
Usando um Arduino Uno, fios de conexão, uma placa de ensaio sem solda e um Módulo de detecção de som de alta sensibilidade com sensor de microfone DEVMO (ou similar) construa o circuito mostrado nesta imagem
Etapa 2: programe o detector de notas musicais
No IDE do Arduino, adicione o código a seguir.
gistfile1.txt
/* |
Nome do arquivo / esboço: MusicalNoteDetector |
Versão nº: v1.0 criada em 7 de junho de 2020 |
Autor Original: Clyde A. Lettsome, PhD, PE, MEM |
Descrição: Este código / esboço exibe a frequência aproximada, bem como a nota musical tocada em um teclado eletrônico ou aplicativo de piano. Para este projeto, a saída analógica do |
O detector de módulo de som é enviado para a entrada analógica A0 do Arduino Uno. O sinal analógico é amostrado e quantizado (digitalizado). Código de autocorrelação, ponderação e ajuste é usado para |
encontre a frequência fundamental usando os primeiros 3 períodos. A frequência fundamental aproximada é então comparada com as frequências nas oitavas 3, 4 e 5 de alcance para determinar o musical mais próximo |
frequência de nota. Finalmente, a nota adivinhada para a frequência mais próxima é impressa na tela. |
Licença: Este programa é um software livre; você pode redistribuí-lo e / ou modificá-lo sob os termos da GNU General Public License (GPL) versão 3, ou qualquer posterior |
versão de sua escolha, conforme publicada pela Free Software Foundation. |
Notas: Copyright (c) 2020 de C. A. Lettsome Services, LLC |
Para obter mais informações, visite |
*/ |
# define SAMPLES 128 // Max 128 para Arduino Uno. |
#define SAMPLING_FREQUENCY 2048 // Fs = Baseado em Nyquist, deve ser 2 vezes a maior frequência esperada. |
# define OFFSETSAMPLES 40 // usado para fins de calibração |
# define TUNER -3 // Ajuste até que C3 seja 130,50 |
float samplingPeriod; |
microssegundos longos sem sinal; |
int X [AMOSTRAS]; // cria um vetor de AMOSTRAS de tamanho para manter valores reais |
float autoCorr [AMOSTRAS]; // cria vetor de AMOSTRAS de tamanho para manter valores imaginários |
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 sumOffSet = 0; |
int offSet [OFFSETSAMPLES]; // cria vetor de deslocamento |
int avgOffSet; // cria vetor de deslocamento |
int i, k, periodEnd, periodBegin, período, ajustador, noteLocation, octaveRange; |
float maxValue, minValue; |
soma longa; |
limite interno = 0; |
int numOfCycles = 0; |
float signalFrequency, signalFrequency2, signalFrequency3, signalFrequencyGuess, total; |
byte estado_máquina = 0; |
int samplesPerPeriod = 0; |
void setup () |
{ |
Serial.begin (115200); // Taxa Baud 115200 para o Monitor Serial |
} |
void loop () |
{ |
//***************************************************************** |
// Seção de Calabração |
//***************************************************************** |
Serial.println ("Calabrando. Por favor, não toque nenhuma nota durante a calabração."); |
para (i = 0; i <OFFSETSAMPLES; i ++) |
{ |
offSet = analogRead (0); // Lê o valor do pino analógico 0 (A0), quantiza-o e salva-o como um termo real. |
//Serial.println(offSet); // use isso para ajustar o módulo de detecção de som para aproximadamente metade ou 512 quando nenhum som é reproduzido. |
sumOffSet = sumOffSet + offSet ; |
} |
samplesPerPeriod = 0; |
maxValue = 0; |
//***************************************************************** |
// Prepare-se para aceitar a entrada de A0 |
//***************************************************************** |
avgOffSet = round (sumOffSet / OFFSETSAMPLES); |
Serial.println ("Contagem regressiva."); |
atraso (1000); // pausa por 1 segundo |
Serial.println ("3"); |
atraso (1000); // pausa por 1 segundo |
Serial.println ("2"); |
atraso (1000); // pausa para 1 |
Serial.println ("1"); |
atraso (1000); // pausa por 1 segundo |
Serial.println ("Toque sua nota!"); |
atraso (250); // pausa por 1/4 de segundo para tempo de reação |
//***************************************************************** |
// Colete amostras de AMOSTRAS de A0 com período de amostragem de Período de amostragem |
//***************************************************************** |
samplingPeriod = 1.0 / SAMPLING_FREQUENCY; // Período em microssegundos |
para (i = 0; i <AMOSTRAS; i ++) |
{ |
microSegundos = micros (); // Retorna o número de microssegundos desde que a placa Arduino começou a executar o script atual. |
X = analogRead (0); // Lê o valor do pino analógico 0 (A0), quantiza-o e salva-o como um termo real. |
/ * tempo de espera restante entre as amostras, se necessário, em segundos * / |
while (micros () <(microSeconds + (samplingPeriod * 1000000))) |
{ |
// não faça nada, apenas espere |
} |
} |
//***************************************************************** |
// Função de autocorrelação |
//***************************************************************** |
para (i = 0; i <AMOSTRAS; i ++) // i = atraso |
{ |
soma = 0; |
for (k = 0; k <AMOSTRAS - i; k ++) // Corresponder o sinal ao sinal atrasado |
{ |
soma = soma + (((X [k]) - avgOffSet) * ((X [k + i]) - avgOffSet)); // X [k] é o sinal e X [k + i] é a versão atrasada |
} |
autoCorr = soma / AMOSTRAS; |
// Máquina de estado de detecção de primeiro pico |
if (state_machine == 0 && i == 0) |
{ |
thresh = autoCorr * 0,5; |
estado_máquina = 1; |
} |
else if (state_machine == 1 && i> 0 && thresh 0) // state_machine = 1, encontre 1 período para usar o primeiro ciclo |
{ |
maxValue = autoCorr ; |
} |
else if (state_machine == 1 && i> 0 && thresh <autoCorr [i-1] && maxValue == autoCorr [i-1] && (autoCorr -autoCorr [i-1]) <= 0) |
{ |
periodBegin = i-1; |
estado_máquina = 2; |
numOfCycles = 1; |
samplesPerPeriod = (periodBegin - 0); |
período = samplesPerPeriod; |
ajustador = TUNER + (50,04 * exp (-0,102 * samplesPerPeriod)); |
signalFrequency = ((SAMPLING_FREQUENCY) / (samplesPerPeriod)) - ajustador; // f = fs / N |
} |
else if (state_machine == 2 && i> 0 && thresh 0) // state_machine = 2, encontre 2 períodos para o 1º e 2º ciclo |
{ |
maxValue = autoCorr ; |
} |
else if (state_machine == 2 && i> 0 && thresh <autoCorr [i-1] && maxValue == autoCorr [i-1] && (autoCorr -autoCorr [i-1]) <= 0) |
{ |
periodEnd = i-1; |
estado_máquina = 3; |
numOfCycles = 2; |
samplesPerPeriod = (periodEnd - 0); |
signalFrequency2 = ((numOfCycles * SAMPLING_FREQUENCY) / (samplesPerPeriod)) - ajustador; // f = (2 * fs) / (2 * N) |
maxValue = 0; |
} |
else if (state_machine == 3 && i> 0 && thresh 0) // state_machine = 3, encontre 3 períodos para o 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) |
{ |
periodEnd = i-1; |
estado_máquina = 4; |
numOfCycles = 3; |
samplesPerPeriod = (periodEnd - 0); |
signalFrequency3 = ((numOfCycles * SAMPLING_FREQUENCY) / (samplesPerPeriod)) - ajustador; // f = (3 * fs) / (3 * N) |
} |
} |
//***************************************************************** |
// Análise de resultados |
//***************************************************************** |
if (samplesPerPeriod == 0) |
{ |
Serial.println ("Hmm….. Não tenho certeza. Você está tentando me enganar?"); |
} |
outro |
{ |
// prepara a função de ponderação |
total = 0; |
if (signalFrequency! = 0) |
{ |
total = 1; |
} |
if (signalFrequency2! = 0) |
{ |
total = total + 2; |
} |
if (signalFrequency3! = 0) |
{ |
total = total + 3; |
} |
// calcule a frequência usando a função de ponderação |
signalFrequencyGuess = ((1 / total) * signalFrequency) + ((2 / total) * signalFrequency2) + ((3 / total) * signalFrequency3); // encontre uma frequência ponderada |
Serial.print ("A nota que você tocou é aproximadamente"); |
Serial.print (signalFrequencyGuess); // Imprime a estimativa de frequência. |
Serial.println ("Hz."); |
// encontre a faixa de oitava com base na suposição |
octaveRange = 3; |
while (! (signalFrequencyGuess> = storedNoteFreq [0] -7 && signalFrequencyGuess <= storedNoteFreq [11] +7)) |
{ |
para (i = 0; i <12; i ++) |
{ |
storedNoteFreq = 2 * storedNoteFreq ; |
} |
octaveRange ++; |
} |
// Encontre a nota mais próxima |
minValue = 10000000; |
noteLocation = 0; |
para (i = 0; i <12; i ++) |
{ |
if (minValue> abs (signalFrequencyGuess-storedNoteFreq )) |
{ |
minValue = abs (signalFrequencyGuess-storedNoteFreq ); |
noteLocation = i; |
} |
} |
// Imprima a nota |
Serial.print ("Acho que você jogou"); |
if (noteLocation == 0) |
{ |
Serial.print ("C"); |
} |
else if (noteLocation == 1) |
{ |
Serial.print ("C #"); |
} |
else if (noteLocation == 2) |
{ |
Serial.print ("D"); |
} |
else if (noteLocation == 3) |
{ |
Serial.print ("D #"); |
} |
else if (noteLocation == 4) |
{ |
Serial.print ("E"); |
} |
else if (noteLocation == 5) |
{ |
Serial.print ("F"); |
} |
else if (noteLocation == 6) |
{ |
Serial.print ("F #"); |
} |
else if (noteLocation == 7) |
{ |
Serial.print ("G"); |
} |
else if (noteLocation == 8) |
{ |
Serial.print ("G #"); |
} |
else if (noteLocation == 9) |
{ |
Serial.print ("A"); |
} |
else if (noteLocation == 10) |
{ |
Serial.print ("A #"); |
} |
else if (noteLocation == 11) |
{ |
Serial.print ("B"); |
} |
Serial.println (octaveRange); |
} |
//***************************************************************** |
//Pare aqui. Aperte o botão reset no Arduino para reiniciar |
//***************************************************************** |
enquanto (1); |
} |
visualizar rawgistfile1.txt hospedado com ❤ por GitHub
Etapa 3: configurar o detector de notas musicais
Conecte o Arduino Uno ao PC com o código escrito ou carregado no IDE do Arduino. Compile e envie o código para o Arduino. Coloque o circuito perto da fonte de música. Nota: No vídeo de introdução, eu uso um aplicativo instalado no tablet em conjunto com os alto-falantes do PC como minha fonte de música. Aperte o botão de reset na placa Arduino e toque uma nota na fonte da música. Após alguns segundos, o detector de notas musicais exibirá a nota tocada e sua frequência.
Recomendado:
Luzes de Natal musicais automáticas DIY (MSGEQ7 + Arduino): 6 etapas (com imagens)
DIY Automatic Musical Christmas Lights (MSGEQ7 + Arduino): Então, todo ano eu digo que vou fazer isso e nunca vou fazer isso porque procrastino muito. 2020 é um ano de mudanças, então eu digo que este é o ano para fazer isso. Então, espero que você goste e faça suas próprias luzes de Natal musicais. Isso vai ser um s
Skittles musicais: 4 etapas
Skittles musicais: Uma coisa sobre ser avô é que você está sempre procurando maneiras novas e empolgantes de entreter seus maravilhosos netos; e de uma forma que também permite que você brinque com seus próprios hobbies. Entre no jogo de boliche musical. Usando um ATTiny13 (b
Sapatos musicais MIDI: 5 etapas (com imagens)
Sapatos musicais MIDI: Como muitas pessoas, muitas vezes me pego batendo os pés inconscientemente, seja por causa de uma música ou por algum hábito nervoso. Por mais divertido que seja, sempre senti como se algo estivesse faltando. Se eu pudesse desencadear os sons de, digamos, um
Detector de notas musicais do Arduino: 3 etapas
Detector de notas musicais do Arduino: detectar notas musicais do sinal de áudio é difícil de fazer, especialmente no Arduino, devido à memória limitada e ao poder de processamento. Geralmente, a nota não é uma onda senoidal pura que torna a detecção difícil. Se tomarmos a transformação de frequência de va
Roda da máquina de impressões musicais do programa de hoje à noite: 7 etapas
Roda da máquina de impressões musicais do Tonight Show: A inspiração dessa máquina vem de um segmento do Tonight Show estrelado por Jimmy Fallon, chamado de '' Roda das Impressões Musicais ''. Primeiro, você pressiona o botão na caixa e ele mostra um cantor e uma música aleatórios no painel LCD. Então você tem que imitar