Tocando notas musicais com o Arduino
Como tocar notas musicais com o Arduino
Em um projeto anterior mostramos como tocar sons utilizando o Arduino. Agora, vamos mostrar como selecionar as frequências a serem reproduzidas para que sejam tocadas notas musicais com Arduino específicas – assim, poderemos criar sequências melódicas e tocar músicas simples.
Ao reproduzirmos sequências de música dessa forma com o Arduino, é interessante o uso de um arquivo de definição que mapeie as diversas frequências sonoras para os nomes das notas musicais. Assim, é muito mais fácil escrever as melodias a serem reproduzidas, e isso também torna o código mais limpo e fácil de manter.
As notas musicais são representadas por letras, que representam o tom (frequência) de cada nota. Assim, para as notas de Dó a Si usamos as seguintes letras como representação:
- C = Dó
- D = Ré
- E = Mi
- F = Fá
- G = Sol
- A = Lá
- B = Si
Também podemos ter algumas notas intermediárias, meio tom acima (“sustenido”, representado por #) ou meio tom abaixo (“bemol”, representado pelo símbolo ♭). Por exemplo, um som de frequência intermediária entre um dó e um ré pode ser representado por C# (dó sustenido) ou ainda por D♭ (ré bemol). Na prática, pode existir uma minúscula diferença entre essas notas, mas para todos os efeitos vamos considerá-las como iguais.
O IDE do Arduino inclui um arquivo de cabeçalho, de nome “pitches.h“, que efetua o mapeamento das frequências (em Hertz) com as notas musicais correspondentes, de modo que não é necessário criar essa mapeamento – devemos apenas entender como o arquivo é estruturado e como utilizá-lo.
Para incluir o arquivo pitches.h em um projeto devemos copiá-lo para a pasta do sketch, fechar o IDE e abri-lo de novo, e então incluir o seguinte comando no início de seu sketch:
#include "pitches.h"
Você pode baixar o arquivo pitches.h clicando aqui.
Ao copiarmos o arquivo e incluirmos essa linha de comandos em um sketch, será aberto uma nova aba no IDE, ao lado do arquivo principal de código, como podemos ver na ilustração a seguir:
E a seguir temos o conteúdo completo do arquivo pitches.h, que é bastante simples, consistindo na definição de uma constante para cada nota musical, seguida do valor de sua frequência sonora:
/************************************************* * Public Constants *************************************************/
#define NOTE_B0 31 #define NOTE_C1 33 #define NOTE_CS1 35 #define NOTE_D1 37 #define NOTE_DS1 39 #define NOTE_E1 41 #define NOTE_F1 44 #define NOTE_FS1 46 #define NOTE_G1 49 #define NOTE_GS1 52 #define NOTE_A1 55 #define NOTE_AS1 58 #define NOTE_B1 62 #define NOTE_C2 65 #define NOTE_CS2 69 #define NOTE_D2 73 #define NOTE_DS2 78 #define NOTE_E2 82 #define NOTE_F2 87 #define NOTE_FS2 93 #define NOTE_G2 98 #define NOTE_GS2 104 #define NOTE_A2 110 #define NOTE_AS2 117 #define NOTE_B2 123 #define NOTE_C3 131 #define NOTE_CS3 139 #define NOTE_D3 147 #define NOTE_DS3 156 #define NOTE_E3 165 #define NOTE_F3 175 #define NOTE_FS3 185 #define NOTE_G3 196 #define NOTE_GS3 208 #define NOTE_A3 220 #define NOTE_AS3 233 #define NOTE_B3 247 #define NOTE_C4 262 #define NOTE_CS4 277 #define NOTE_D4 294 #define NOTE_DS4 311 #define NOTE_E4 330 #define NOTE_F4 349 #define NOTE_FS4 370 #define NOTE_G4 392 #define NOTE_GS4 415 #define NOTE_A4 440 #define NOTE_AS4 466 #define NOTE_B4 494 #define NOTE_C5 523 #define NOTE_CS5 554 #define NOTE_D5 587 #define NOTE_DS5 622 #define NOTE_E5 659 #define NOTE_F5 698 #define NOTE_FS5 740 #define NOTE_G5 784 #define NOTE_GS5 831 #define NOTE_A5 880 #define NOTE_AS5 932 #define NOTE_B5 988 #define NOTE_C6 1047 #define NOTE_CS6 1109 #define NOTE_D6 1175 #define NOTE_DS6 1245 #define NOTE_E6 1319 #define NOTE_F6 1397 #define NOTE_FS6 1480 #define NOTE_G6 1568 #define NOTE_GS6 1661 #define NOTE_A6 1760 #define NOTE_AS6 1865 #define NOTE_B6 1976 #define NOTE_C7 2093 #define NOTE_CS7 2217 #define NOTE_D7 2349 #define NOTE_DS7 2489 #define NOTE_E7 2637 #define NOTE_F7 2794 #define NOTE_FS7 2960 #define NOTE_G7 3136 #define NOTE_GS7 3322 #define NOTE_A7 3520 #define NOTE_AS7 3729 #define NOTE_B7 3951 #define NOTE_C8 4186 #define NOTE_CS8 4435 #define NOTE_D8 4699 #define NOTE_DS8 4978
Por exemplo, a nota Lá central, que possui uma frequência de 440 Hz, é definida no arquivo com a linha:
#define NOTE_A4 440
Desta forma, sempre que quisermos reproduzir essa nota específica, podemos usar a constante de nome NOTE_A4 no código. O número que vem logo após o nome da nota (“4”, no caso) se refere à oitava da nota reproduzida – podemos reproduzir sons até a 8ª oitava usando esse arquivo de definições.
Podemos também realizar alterações no arquivo, para incluir notas de frequências mais altas ou ainda trocar os nomes das constantes, se assim o desejarmos.
O Circuito
Para exemplificar a reprodução das notas, vamos usar um circuito bem simples, que consiste em um pequeno alto-falante ou buzzer conectado ao Arduino, como podemos ver no esquemático a seguir:
Este circuito consiste apenas em um Arduino, um alto-falante e um resistor. O resistor, em série com o alto-falante, é muito importante para limitar a corrente que circulará no circuito, pois os pinos do Arduino só podem fornecer no máximo 40 mA, e se uma corrente maior do que isso for exigida, poderá ocasionar danos ao seu microcontrolador.
O valor do resistor pode ser calculado usando-se a Lei de Ohm. Sabemos que R = U / I, sendo que o valor da tensão fornecida pelo Arduino é de 5V, e a corrente máxima, como citado, é de 40mA. Portando, o valor mínimo do resistor deverá ser:
R = 5 / 0,04 = 125Ω
Como o alto-falante possui resistência interna, geralmente de 8Ω, então o resistor em série precisará ter, na verdade, 125Ω – 8Ω = 117Ω. Este valor não existe comercialmente, de modo que teremos de usar o valor mais próximo encontrado no mercado, que é de 150Ω.
Tocando as notas musicais em sequência
Vamos agora criar uma pequena aplicação que permita reproduzir notas selecionadas em sequência. Não vamos prestar atenção ao tempo das notas no momento, pois isso será abordado em nosso próximo tutorial. Usaremos a função tone() para reproduzir as notas desejadas.
Suponha que você queira tocar as seguintes notas no Arduino, nesta ordem:
C D E F G A B C
Ou seja, uma escala de uma oitava de dó a dó. Para executá-la, basta escolher a oitava desejada (altura do som) e então usar os nomes das constantes definidas no arquivo de cabeçalho para reproduzi-las.
Digite o código a seguir em seu programa principal para tocar essa escala sequencialmente:
#include "pitches.h" int falante = 7; int tempo = 500; // Array com as notas na ordem em que devem ser tocadas: int notas[] = { NOTE_C4, NOTE_D4, NOTE_E4, NOTE_F4, NOTE_G4, NOTE_A4, NOTE_B4, NOTE_C5 }; void setup() { // nada a fazer aqui } void loop() { // Tocar cada nota do array durante o tempo especificado: for (int i = 0; i < 8; i++) { tone(falante, notas[i], tempo); delay(tempo); } }
Neste exemplo, criamos um array para armazenar as notas, de modo que para tocá-las na sequência basta iterar pelo array, executando o tom de cada uma de suas posições com a função tone(). Note que acrescentei uma chamada à função delay() dentro do laço for.
Essa chamada é para que haja tempo da função tone() terminar de tocar a nota passada a ela, pois como esa função pode ser executada em segundo plano, corremos o risco do laço for iterar e chamar a função tone() novamente, tocando outro som antes do som anterior ter finalizado, e assim cumulativamente até que o som tocado não seja mais inteligível.
A função delay() deve executar uma pausa com a mesma duração do som tocado.
Note também que o som gerado é uma onda quadrada, pois o Arduino não é capaz de gerar ondas sinusoidais, do tipo que ouvimos no mundo real. Por isso, o timbre do som irá lembrar aquelas melodias de videogames de 8 bits, dos anos 80.
Para gerar sons mais realistas precisamos de um circuito conversor digital-analógico (DAC), o qual está presente por padrão apenas no Arduino Due. Para outros modelos, será necessário construir o circuito – o que faremos em uma lição futura.
Você pode experimentar alterar as notas tocadas trocando-as ou acrescentando mais notas no array, lembrando sempre de ajustar o laço for de acordo, pois ele deve iterar pelo número de itens presentes no array. Caso queira acrescentar uma pausa (momento de silêncio), basta usar o valor 0 (zero) na posição desejada dentro do array.
É isso aí! No próximo tutorial vamos fazer o Arduino tocar uma música inteira, além de implementar um controle de volume simples em nosso circuito.
Até!
Parabéns pelo texto muito explicativo, ainda não consegui fazer rodar no meu buzzer porém logo logo farei, o site é de ótima qualidade, até estranhei n ter nenhum comentário nessa postagem tão genial
Muito obrigado Leonardo!
Chic o gerador de notas musicais com arduino!….
Parabéns pelo trabalho,uma pena que não seja polifônico!
Parabéns pelos trabalhos
Obrigado Carlinhos!
Boa noite amigo. Excelente seu artigo, parabéns! Eu pretendo automatizar um avião de brinquedo de minha neta, colocando sensor de obstáculos e motores. Pretendo colocar também som de avião mas não acho um código de exemplo em lugar nenhum. Você tem ideia de onde eu poderia conseguir? Desde já agradeço.