Tocando uma melodia com o Arduino: Ode à Alegria, de Beethoven
Tocando uma melodia com o Arduino: Ode à Alegria, de Beethoven
Anteriormente mostramos como tocar notas musicais específicas usando o Arduino, inclusive com a reprodução de uma escala musical pré-determinada. Neste novo projeto, vamos aplicar essas técnicas para reproduzir uma melodia bastante conhecida, a Ode à Alegria, parte da Nona Sinfonia de Beethoven. É uma melodia simples, portanto indicada para esta tarefa. Posteriormente iremos alterar nosso código para tocar músicas mais complexas e mais longas.
A figura abaixo mostra a partitura da melodia que iremos reproduzir:
Circuito
A figura a seguir mostra o circuito a ser utilizado, que é o mesmo que empregamos no projeto anterior, “tocando uma escala musical com Arduino“:
Precisaremos apenas de um Arduino (qualquer versão), um alto-falante ou buzzer, e um resistor de 150Ω, além de fios conectores e uma matriz de contatos pequena.
Código
Neste programa precisamos incluir o arquivo de cabeçalho pitches.h, o qual já utilizamos em um projeto anterior, e que contém o mapeamento das frequências das notas musicais para um nome de constante. Porém, aqui, eu modifiquei o conteúdo do arquivo, eliminando a palavra “NOTE” que aparece em cada nome de nota, e deixando apenas o padrão _XY, com X sendo o nome da nota em notação musical, e Y o número da oitava. Assim por exemplo, a nota NOTE_C4 será representada apenas por _C4. Fiz isso para simplificar e diminuir o tamanho do código, pois ele terá muitas dezenas de notas, e pode ficar confuso.
Vamos ao código da aplicação:
#include "pitches.h" int falante = 8; float bpm = 80; int T; int minima, seminima, seminimaAumentada, colcheia; int nota[] = { _B4, _B4, _C5, _D5, _D5, _C5, _B4, _A4, _G4, _G4, _A4, _B4, _B4, _A4, _A4, _B4, _B4, _C5, _D5, _D5, _C5, _B4, _A4, _G4, _G4, _A4, _B4, _A4, _G4, _G4, _A4, _A4, _B4, _G4, _A4, _B4, _C5, _B4, _G4, _A4, _B4, _C5, _B4, _A4, _G4, _A4, _D4, _B4, _B4, _C5, _D5, _D5, _C5, _B4, _A4, _G4, _G4, _A4, _B4, _A4, _G4, _G4 }; /* Tempos: 1 = colcheia 2 = seminima 3 = seminima + colcheia 4 = minima */ int tempo[] ={ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 1, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 1, 4, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 1, 4 }; void setup() { minima = round((1 / (bpm / 60)) * 1000 * 2); seminima = round((1 / (bpm / 60)) * 1000); seminimaAumentada = round((1 / (bpm / 60)) * 1500); colcheia = round((1 / (bpm / 60)) * 500); // Serial.begin(9600); // para debug } void loop() { // Tocar cada nota durante o tempo especificado: for (int i = 0; i < 62; i++) { switch (tempo[i]) { case 1: T = colcheia; break; case 2: T = seminima; break; case 3: T = seminimaAumentada; break; case 4: T = minima; break; } /* Visualizando os tempos (para debug): Serial.println(minima); Serial.println(seminima); Serial.println(seminimaAumentada); Serial.println(colcheia); */ tone(falante, nota[i], T); delay(T); } }
Explicando o código
Neste código usaremos as seguintes variáveis:
- falante – Variável para armazenar o número do pino onde está conectado o alto-falante ou buzzer.
- bpm – Nesta variável vamos armazenar um número que indicará o andamento da música (sua “velocidade”). bpm significa “batidas por minuto”.
- T – A variável T receberá o valor do tempo que deve ser aplicado a cada nota durante sua execução (duração da nota).
- minima, seminima, seminimaAumentada, colcheia – Essas variáveis determinam o valor da duração para cada tipo de nota, pois algumas notas possuem duração mais longa do que outras.
Também criaremos dois arrays (vetores) para armazenar as notas e seus respectivos tempos de duração:
- O array nota[] contém as notas da melodia a ser reproduzida, na sequência correta, como fizemos no artigo sobre escalas musicais no Arduino.
- O array tempo[] armazenará um número que será usado para calcular a duração de cada nota tocada, também na sequência correta de reprodução da melodia. Assim, a primeira posição deste array possui a duração da nota na primeira posição no array nota[], e assim sucessivamente.
No array tempo[] utilizamos números para representar as durações das notas tocadas. Em nosso código, o número 1 simboliza uma colcheia, o valor 2 representa uma seminima, o valor 3 uma semínima aumentada ( 1 tempo e 1/2), e o valor 4 representa uma mínima (2 tempos).
Na rotina de setup é calculado o valor de tempo em milissegundos de cada tipo de nota, de acordo com o andamento (variável bpm). A duração de cada nota depende do andamento da música, que é dado pelo valor armazenado em bpm. Assim, valores maiores de bpm farão a música ser executada mais rapidamente, e vice-versa.
Na rotina de loop usamos uma estrutura de decisão Switch / Case para determinar a duração a ser aplicada a cada nota tocada, de acordo com o valor armazenado no array tempo[] e com a duração de cada tipo de nota, calculada na rotina de setup.
E, finalmente, chamamos a função tone() para executar a nota na posição i do array nota[], usando a duração T determinada, e a função delay() na sequência faz o Arduino aguardar a nota ser executada antes de reproduzir a próxima nota da música.
Após carregar o código, basta esperar alguns instantes e a melodia da Ode à Alegria (Ode to Joy) de Beethoven será reproduzida no alto-falante.
É isso aí!
Até a próxima!
Olá!
Está dando um erro:
‘_B4’ was not declared in this scope