Tocando melodias usando a função Tone() do Arduino
O Arduino é uma excelente maneira de simplificar e acelerar seus projetos de microcontroladores, graças à sua comunidade de desenvolvedores que fizeram quase tudo parecer simples. Existem muitos projetos Arduino aqui para você experimentar e se divertir. Alguns de seus projetos podem precisar de alguma ação sonora para notificar algo ou apenas para impressionar os espectadores. E se eu lhe disser que quase todas as músicas-tema que podem ser tocadas em um piano podem ser imitadas em seu Arduino com a ajuda de um programa simples e um alto-falante Piezo barato?
Neste tutorial vamos aprender como é simples e fácil Tocar Melodia no Piezo Buzzer ou Alto-falante usando a função Arduino tone(). No final deste tutorial você poderá tocar alguns tons famosos de Pirates of Caribbean, Crazy Frog, Super Mario e Titanic. Você também aprenderá a tocar qualquer música de piano com o Arduino. Confira o vídeo no final.
Conteudo
Hardware Necessário:
- Arduino (qualquer versão – UNO é usado aqui)
- Alto-falante Piezo/Buzzer ou qualquer outro alto-falante de 8ohm.
- Protoboard
- Fios de conexão
- PushBotton
- resistor de 1k (opcional)
Entendendo a função Tone() do Arduino:
Antes de podermos entender como funciona um tom () devemos saber como funciona uma campainha Piezo. Podemos ter aprendido sobre cristais piezo em nossa escola, não é nada mais que um cristal que converte vibrações mecânicas em eletricidade ou vice-versa. Aqui aplicamos uma corrente variável (frequência) para a qual o cristal vibra produzindo som. Portanto, para fazer a campainha Piezo fazer algum ruído, temos que fazer o cristal elétrico Piezo vibrar, o tom e o tom do ruído dependem da rapidez com que o cristal vibra. Portanto, o tom e o tom podem ser controlados variando a frequência da corrente.
Ok, então como obtemos uma frequência variável do Arduino? É aqui que entra a função tone(). O tone() pode gerar uma determinada frequência em um pino específico. A duração do tempo também pode ser mencionada, se necessário. A sintaxe para tone() é
Sintaxe
tone(pino, frequência) tone(pin,o frequência, duração)
Parâmetros
pino: o pino no qual gerar o tom frequência: a frequência do tom em hertz - unsigned int duração: a duração do tom em milissegundos (opcional) - unsigned long
Os valores de pin podem ser qualquer um dos seus pins digitais. Eu usei o pino número 8 aqui. A frequência que pode ser gerada depende do tamanho do temporizador em sua placa Arduino. Para UNO e a maioria das outras placas comuns, a frequência mínima que pode ser produzida é 31Hz e a frequência máxima que pode ser produzida é 65535Hz. No entanto, nós humanos podemos ouvir apenas frequências entre 2000Hz e 5000Hz.
O arquivo de cabeçalho pitches.h:
Agora, sabemos como produzir algum ruído usando a função arduino tone(). Mas, como sabemos que tipo de tom será gerado para cada frequência?
O Arduino nos deu uma tabela de notas que iguala cada frequência a um tipo específico de nota musical. Esta tabela de notas foi originalmente escrita por Brett Hagman, em cujo trabalho o comando tone() foi baseado. Usaremos esta tabela de notas para tocar nossos temas. Se você é alguém familiarizado com partituras, deve ser capaz de entender essa tabela, para outros como eu, esses são apenas mais um bloco de código.
#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
O código acima é fornecido no arquivo de cabeçalho pitches.h neste arquivo zip, você só precisa baixar e incluir este arquivo em nosso código Arduino conforme fornecido no final deste tutorial ou usar o código fornecido no arquivo zip.
Tocando notas musicais no Arduino:
Para tocar uma melodia decente usando Arduino, devemos saber o que constitui essas melodias. Os três principais fatores necessários para tocar um tema são
- Valor da nota
- Duração da Nota
- Tempo
Temos o arquivo de cabeçalho pitches.h para tocar qualquer valor de nota, agora devemos descobrir a duração específica da nota para tocá-la. O tempo nada mais é do que a rapidez com que a melodia deve ser tocada. Depois de saber o valor da nota e a duração da nota, você pode usá-los com o tone() como
tone(pinName, Note Value, Note Duration);
Para os timbres tocados neste tutorial eu dei a você o valor da nota e a duração da nota dentro do arquivo de cabeçalho “themes.h” usando o qual você pode tocá-los em seus projetos. Mas se você tiver algum tom específico em sua mina e quiser tocá-lo em seu projeto, continue lendo…. Caso contrário, pule este tópico e pule para o próximo.
Para tocar qualquer tom específico, você precisa obter a partitura dessa música específica e converter a partitura para o sketch do Arduino lendo o valor da nota e a duração da nota. Se você é um estudante de música, seria um pedaço de bolo para você, senão gastaria algum tempo e quebraria sua cabeça como eu fiz. Mas no final do dia, quando seu tom tocar na campainha Piezo, você verá que seu esforço vale a pena.
Uma vez que você tenha o valor da nota e a duração da nota, carregue-os no programa dentro do arquivo de cabeçalho “themes.h” como mostrado abaixo
//##############**"HE IS A PIRATE" Theme song of Pirates of caribbean**##############// int Pirates_note[] = { NOTE_D4, NOTE_D4, NOTE_D4, NOTE_D4, NOTE_D4, NOTE_D4, NOTE_D4, NOTE_D4, NOTE_D4, NOTE_D4, NOTE_D4, NOTE_D4, NOTE_D4, NOTE_D4, NOTE_D4, NOTE_D4, NOTE_D4, NOTE_D4, NOTE_D4, NOTE_D4, NOTE_D4, NOTE_D4, NOTE_D4, NOTE_D4, NOTE_A3, NOTE_C4, NOTE_D4, NOTE_D4, NOTE_D4, NOTE_E4, NOTE_F4, NOTE_F4, NOTE_F4, NOTE_G4, NOTE_E4, NOTE_E4, NOTE_D4, NOTE_C4, NOTE_C4, NOTE_D4, 0, NOTE_A3, NOTE_C4, NOTE_B3, NOTE_D4, NOTE_B3, NOTE_E4, NOTE_F4, NOTE_F4, NOTE_C4, NOTE_C4, NOTE_C4, NOTE_C4, NOTE_D4, NOTE_C4, NOTE_D4, 0, 0, NOTE_A3, NOTE_C4, NOTE_D4, NOTE_D4, NOTE_D4, NOTE_F4, NOTE_G4, NOTE_G4, NOTE_G4, NOTE_A4, NOTE_A4, NOTE_A4, NOTE_A4, NOTE_G4, NOTE_A4, NOTE_D4, 0, NOTE_D4, NOTE_E3, NOTE_F4, NOTE_F4, NOTE_G4, NOTE_A4, NOTE_D4, 0, NOTE_D4, NOTE_F4, NOTE_E4, NOTE_E4, NOTE_F4, NOTE_D4 }; int Pirates_duration[] = { 4,8,4,8,4,8,8,8,8,4,8,4,8,4,8,8,8,8,4,8,4,8, 4,8,8,8,8,4,4,8,8,4,4,8,8,4,4,8,8, 8,4,8,8,8,4,4,8,8,4,4,8,8,4,4,8,4, 4,8,8,8,8,4,4,8,8,4,4,8,8,4,4,8,8, 8,4,8,8,8,4,4,4,8,4,8,8,8,4,4,8,8 }; //###########End of He is a Pirate song#############//
O bloco de código acima mostra o valor da nota e a duração da nota do tema “Ele é um pirata” do filme Piratas do Caribe. Você pode adicionar seu tema da mesma forma.
Esquema e Hardware:
O esquema deste projeto do Arduino Tone Generator Project é mostrado na figura abaixo:
A conexão é bem simples temos um alto falante Piezo que é conectado ao pino 8 e Terra do Arduino através de um resistor de 1K. Este resistor de 1k é um resistor limitador de corrente, que é usado para manter a corrente dentro dos limites seguros. Também temos quatro interruptores para selecionar a melodia necessária. Uma extremidade do interruptor é conectada ao terra e a outra extremidade é conectada aos pinos 2, 3, 4 e 5, respectivamente. As chaves terão resistores de pull up habilitados internamente usando o software. Como o circuito é bastante simples, ele pode ser conectado usando uma placa de pão, conforme mostrado abaixo:
Explicação do programa Arduino:
Depois de entender o conceito, o programa Arduino é bastante simples. O código completo é fornecido no final do tutorial. Se você não estiver familiarizado com a adição de arquivos de cabeçalho, você pode baixar o código como um arquivo ZIP aqui e enviá-lo diretamente para o seu Arduino.
Os dois acima são os arquivos de cabeçalho que devem ser adicionados. “pitches.h” é usado para igualar cada nota musical a uma frequência específica e “themes.h” contém o valor da nota e a duração da nota de todos os quatro tons.
#include "pitches.h" #include "themes.h"
Uma função é criada para reproduzir cada tom quando necessário. Aqui quando a função Play_Pirates() é chamada o tom “He is a Pirate” será tocado. Esta função consiste na função tone que produz a frequência no pino número 8. O noTone(8) é chamado para parar a música uma vez que é tocada. Se você quiser tocar seu próprio tom, altere Pirates_note e Pirates_duration para os novos valores de nota e duração que você salvou no valor “themes.h”
void Play_Pirates() { for (int thisNote = 0; thisNote < (sizeof(Pirates_note)/sizeof(int)); thisNote++) { int noteDuration = 1000 / Pirates_duration[thisNote];//converte duração para atraso de tempo tone(8, Pirates_note[thisNote], noteDuration); int pauseBetweenNotes = noteDuration * 1.05; //Aqui 1.05 é o tempo, aumente para tocar mais devagar delay(pauseBetweenNotes); noTone(8); } }
Os pinos 2, 3, 4 e 5 são usados para selecionar o tom específico a ser tocado. Esses pinos são mantidos altos por padrão usando os resistores internos de pull up usando a linha de código acima. Quando o botão é pressionado, ele é puxado para o chão.
pinMode(2, INPUT_PULLUP); pinMode(3, INPUT_PULLUP); pinMode(4, INPUT_PULLUP); pinMode(5, INPUT_PULLUP);
O bloco de código abaixo é usado para tocar a música quando um botão é pressionado. Ele lê o valor digital de cada botão e quando fica baixo (zero) assume que o botão está pressionado e toca o respectivo tom chamando a função desejada.
if (digitalRead(2)==0) { Serial.println("Selected -> 'He is a Pirate' "); Play_Pirates(); } if (digitalRead(3)==0) { Serial.println("Selected -> 'Crazy Frog' "); Play_CrazyFrog(); } if (digitalRead(4)==0) { Serial.println("Selected -> 'Mario UnderWorld' "); Play_MarioUW(); } if (digitalRead(5)==0) { Serial.println("Selected -> 'He is a Pirate' "); Play_Pirates(); }
Funcionamento deste circuito Arduino do Melody Player:
Quando seu código e hardware estiverem prontos, basta gravar o programa em seu Arduino e você poderá tocar o tom simplesmente pressionando os botões. Se você tiver algum problema, dê uma olhada no seu monitor serial para depuração ou use a seção de comentários para relatar o problema e ficarei feliz em ajudá-lo.
Espero que você tenha gostado do projeto e que o use em algum de seu projeto ou crie um novo tom para o seu projeto. Se sim, sinta-se à vontade para compartilhar seu trabalho na seção de comentários.
Código
#include "pitches.h" //add Equivalent frequency for musical note #include "themes.h" //add Note vale and duration void Play_Pirates() { for (int thisNote = 0; thisNote < (sizeof(Pirates_note)/sizeof(int)); thisNote++) { int noteDuration = 1000 / Pirates_duration[thisNote];//converte duração para atraso de tempo tone(8, Pirates_note[thisNote], noteDuration); int pauseBetweenNotes = noteDuration * 1.05; //Aqui 1.05 é o tempo, aumente para tocar mais devagar delay(pauseBetweenNotes); noTone(8); //stop music on pin 8 } } void Play_CrazyFrog() { for (int thisNote = 0; thisNote < (sizeof(CrazyFrog_note)/sizeof(int)); thisNote++) { int noteDuration = 1000 / CrazyFrog_duration[thisNote]; //converte duração para atraso de tempo tone(8, CrazyFrog_note[thisNote], noteDuration); int pauseBetweenNotes = noteDuration * 1.30;//Aqui 1.30 é o tempo, diminua para tocar mais rápido delay(pauseBetweenNotes); noTone(8); //stop music on pin 8 } } void Play_MarioUW() { for (int thisNote = 0; thisNote < (sizeof(MarioUW_note)/sizeof(int)); thisNote++) { int noteDuration = 1000 / MarioUW_duration[thisNote];//converte duração para atraso de tempo tone(8, MarioUW_note[thisNote], noteDuration); int pauseBetweenNotes = noteDuration * 1.80; delay(pauseBetweenNotes); noTone(8); //para a música no pino 8 } } void Play_Titanic() { for (int thisNote = 0; thisNote < (sizeof(Titanic_note)/sizeof(int)); thisNote++) { int noteDuration = 1000 / Titanic_duration[thisNote];//converte duração para atraso de tempo tone(8, Titanic_note[thisNote], noteDuration); int pauseBetweenNotes = noteDuration * 2.70; delay(pauseBetweenNotes); noTone(8); //stop music on pin 8 } } void setup() { pinMode(2, INPUT_PULLUP); //Button 1 with internal pull up pinMode(3, INPUT_PULLUP); //Button 2 with internal pull up pinMode(4, INPUT_PULLUP); //Button 3 with internal pull up pinMode(5, INPUT_PULLUP); //Button 4 with internal pull up Serial.begin(9600); } void loop() { if (digitalRead(2)==0) { Serial.println("Selected -> 'He is a Pirate' "); Play_Pirates(); } if (digitalRead(3)==0) { Serial.println("Selected -> 'Crazy Frog' "); Play_CrazyFrog(); } if (digitalRead(4)==0) { Serial.println("Selected -> 'Mario UnderWorld' "); Play_MarioUW(); } if (digitalRead(5)==0) { Serial.println("Selected -> 'Titanic' "); Play_Titanic(); } }