Toque 'Parabéns pra Você' com Polifonia de 3 Vias no Arduino Nano – Demo de Melodia Infinita com Sincronização de Luzes
Componentes e Materiais
| 1× Arduino Nano R3 |
Aplicativos e Serviços Online
- Arduino IDE
Sobre o Projeto
Toque o tema "Parabéns pra Você" em polifonia no Arduino Nano com três buzzers em uma única mini protoboard.
Primeiro - Demonstração
Conecte este dispositivo em qualquer fonte de alimentação USB (não apenas um computador) e ele tocará a melodia "Parabéns pra Você" indefinidamente... quase... até você enjoar completamente =]
A propósito, as luzes piscam em sincronia com cada mudança de nota em um canal/buzzer correspondente.
Esquemáticos
A ideia era fazer um dispositivo super compacto com (quase) nenhuma solda.
Consegui encaixar tudo o que era necessário em uma protoboard minúscula assim:


Os furos são interconectados dentro da protoboard desta forma:

O truque aqui é que a placa Arduino Nano encaixa em tal protoboard PERFEITAMENTE, permitindo-nos conectar componentes adicionais em ambos os lados da protoboard.
Desculpem, pessoal... sou preguiçoso demais para desenhar diagramas aqui, mas este caso é TÃO simples que tenho certeza que estes close-ups serão mais que suficientes para descobrir tudo =]







Como podem ver, estou usando uma placa Arduino Nano v3.0 da Gravitech, mas qualquer similar serve. Os buzzers e LEDs aqui são MUITO comuns. Não precisam corresponder a parâmetros especiais.
Os resistores aqui são de 100 Ohm... embora o "padrão" comum para proteção contra sobrecarga de LED seja 220 Ohm... mas quem liga... ¯\_(ツ)_/¯
A única coisa que provavelmente não é tão óbvia nestas fotos é que os pinos dos buzzers são inseridos na protoboard desta forma:

Note também que o central é maior que os outros - isso porque este é usado para o canal de música "baixo" ☝🏻
... só brincando! ^__^ Todos eles chiados como um coro de ratos loucos sem diferença em suas capacidades sonoras =]
Então você pode usar três buzzers idênticos se quiser, sem problemas, no entanto terá que colocá-los em posições ligeiramente diferentes na protoboard e também alterar os números dos pinos de saída no código do programa de acordo com a nova posição dos buzzers.
Também note outro pequeno "hack" aqui... afinal estamos no Hackster ou não? =] Estou usando vários pinos I/O do Arduino aqui como pinos de terra para buzzers e LEDs 😱😱. Sim... isso mesmo. Na verdade, se você definir um estado "LOW" para qualquer pino I/O do Arduino no seu programa, então você pode usar esses pinos exatamente da mesma forma que usa os pinos GND padrão nas placas Arduino. Legal, né? ;)
Sobre o Programa...
O código completo do sketch da Arduino IDE é fornecido abaixo. No entanto, você terá que instalar uma biblioteca adicional "Tone" para poder compilar o sketch, que pode ser baixada aqui:
(se aparecer uma janela pop-up com uma "proposta" de registro, apenas feche com o botão "x" no canto)
A maneira mais fácil de instalar esta biblioteca é: no menu principal da Arduino IDE escolha Sketch → Incluir Biblioteca → Adicionar Biblioteca .ZIP... e então selecione seu arquivo zip baixado... fácil ¯\_(ツ)_/¯
Esta biblioteca é necessária para realizar a geração simultânea de vários tons em um único controlador (ela usa alguns timers de hardware adicionais e interrupções de hardware "por baixo dos panos" para alcançar este objetivo). Simplificando, é uma espécie de "multitarefa caipira" em um único núcleo de processador sem nenhum SO =]
A propósito, aqui está o autor da biblioteca (valeu, cara! =] ):
... e a página do GitHub da biblioteca:
AVISO 🙂 :
Francamente falando, meu código de programa aqui é bastante volumoso e difícil de ler. Isso se deve principalmente à necessidade de "malabarismo" com três threads de melodia "independentes" simultaneamente a partir de apenas um fluxo de comandos linear. Pensei seriamente em refatorar o código depois para separar as melodias umas das outras e poder usá-lo no futuro para tocar músicas diferentes... mas provavelmente não vou =]
Boa sorte. Qualquer feedback é apreciado.
Obrigado por ler até o fim =]
Código
Happy_birthday Arduino
Não esqueça de instalar a biblioteca Tone!!
#include <Tone.h>
Tone solo;
Tone bass;
Tone rythm;
const int t = 600; // duração de semínima
const int tt = t*2;
const int t14 = round(t*1/4);
const int t24 = round(t*2/4);
const int t34 = round(t*3/4);
const int bassLedPin = 15; // pino de sinal do LED do baixo (aka A1)
const int rythmLedPin = 17; // pino de sinal do LED do ritmo (aka A3)
const int soloLedPin = 19; // pino de sinal do LED do solo (aka A5)
void wait(Tone t) {
while (t.isPlaying()) { }
}
int bassLedState = LOW;
void switchBassLed() {
if (bassLedState == LOW) bassLedState = HIGH;
else bassLedState = LOW;
digitalWrite(bassLedPin, bassLedState);
}
int rythmLedState = LOW;
void switchRythmLed() {
if (rythmLedState == LOW) rythmLedState = HIGH;
else rythmLedState = LOW;
digitalWrite(rythmLedPin, rythmLedState);
}
int soloLedState = LOW;
void switchSoloLed() {
if (soloLedState == LOW) soloLedState = HIGH;
else soloLedState = LOW;
digitalWrite(soloLedPin, soloLedState);
}
void setup(void) {
pinMode(14, OUTPUT); // pino terra do LED (aka A0)
pinMode(16, OUTPUT); // pino terra do LED (aka A2)
pinMode(18, OUTPUT); // pino terra do LED (aka A4)
pinMode(bassLedPin, OUTPUT); // pino de sinal do LED do baixo
pinMode(rythmLedPin, OUTPUT); // pino de sinal do LED do ritmo
pinMode(soloLedPin, OUTPUT); // pino de sinal do LED do solo
pinMode(2, OUTPUT); // pino terra do buzzer solo
pinMode(9, OUTPUT); // pino terra do buzzer ritmo
solo.begin(6); // pino de sinal do buzzer solo
bass.begin(12); // pino de sinal do buzzer baixo
rythm.begin(0); // pino de sinal do buzzer ritmo
solo.play(NOTE_D4, t34);
switchSoloLed();
wait(solo);
solo.play(NOTE_D4, t14);
switchSoloLed();
wait(solo);
}
void loop(void) {
bass.play(NOTE_G3, t);
switchBassLed();
rythm.play(NOTE_G4, t24);
switchRythmLed();
solo.play(NOTE_E4, t);
switchSoloLed();
wait(rythm);
rythm.play(NOTE_B4, t14);
switchRythmLed();
wait(rythm);
rythm.play(NOTE_D5, t14);
switchRythmLed();
wait(rythm);
bass.play(NOTE_B3, t);
switchBassLed();
rythm.play(NOTE_G4, t24);
switchRythmLed();
solo.play(NOTE_D4, t);
switchSoloLed();
wait(rythm);
rythm.play(NOTE_B4, t14);
switchRythmLed();
wait(rythm);
rythm.play(NOTE_D5, t14);
switchRythmLed();
wait(rythm);
bass.play(NOTE_D4, t);
switchBassLed();
rythm.play(NOTE_G4, t24);
switchRythmLed();
solo.play(NOTE_G4, t);
switchSoloLed();
wait(rythm);
rythm.play(NOTE_B4, t14);
switchRythmLed();
wait(rythm);
rythm.play(NOTE_D5, t14);
switchRythmLed();
wait(rythm);
bass.play(NOTE_D4, t);
switchBassLed();
rythm.play(NOTE_D5, t24);
switchRythmLed();
solo.play(NOTE_FS4, tt);
switchSoloLed();
wait(rythm);
rythm.play(NOTE_FS5, t14);
switchRythmLed();
wait(rythm);
rythm.play(NOTE_A5, t14);
switchRythmLed();
wait(rythm);
bass.play(NOTE_FS4, t);
switchBassLed();
rythm.play(NOTE_D5, t24);
switchRythmLed();
wait(rythm);
rythm.play(NOTE_FS5, t14);
switchRythmLed();
wait(rythm);
rythm.play(NOTE_A5, t14);
switchRythmLed();
wait(rythm);
bass.play(NOTE_A4, t);
switchBassLed();
rythm.play(NOTE_D5, t24);
switchRythmLed();
solo.play(NOTE_D4, t34);
switchSoloLed();
wait(rythm);
rythm.play(NOTE_FS5, t14);
switchRythmLed();
wait(rythm);
rythm.play(NOTE_A5, t14);
switchRythmLed();
solo.play(NOTE_D4, t14);
switchSoloLed();
wait(rythm);
bass.play(NOTE_D4, t);
switchBassLed();
rythm.play(NOTE_D5, t24);
switchRythmLed();
solo.play(NOTE_E4, t);
switchSoloLed();
wait(rythm);
rythm.play(NOTE_FS5, t14);
switchRythmLed();
wait(rythm);
rythm.play(NOTE_A5, t14);
switchRythmLed();
wait(rythm);
bass.play(NOTE_FS4, t);
switchBassLed();
rythm.play(NOTE_D5, t24);
switchRythmLed();
solo.play(NOTE_D4, t);
switchSoloLed();
wait(rythm);
rythm.play(NOTE_FS5, t14);
switchRythmLed();
wait(rythm);
rythm.play(NOTE_A5, t14);
switchRythmLed();
wait(rythm);
bass.play(NOTE_A4, t);
switchBassLed();
rythm.play(NOTE_D5, t24);
switchRythmLed();
solo.play(NOTE_A4, t);
switchSoloLed();
wait(rythm);
rythm.play(NOTE_FS5, t14);
switchRythmLed();
wait(rythm);
rythm.play(NOTE_A5, t14);
switchRythmLed();
wait(rythm);
bass.play(NOTE_G3, t);
switchBassLed();
rythm.play(NOTE_G4, t24);
switchRythmLed();
solo.play(NOTE_G4, tt);
switchSoloLed();
wait(rythm);
rythm.play(NOTE_B4, t14);
switchRythmLed();
wait(rythm);
rythm.play(NOTE_D5, t14);
switchRythmLed();
wait(rythm);
bass.play(NOTE_B3, t);
switchBassLed();
rythm.play(NOTE_G4, t24);
switchRythmLed();
wait(rythm);
rythm.play(NOTE_B4, t14);
switchRythmLed();
wait(rythm);
rythm.play(NOTE_D5, t14);
switchRythmLed();
wait(rythm);
bass.play(NOTE_D4, t);
switchBassLed();
rythm.play(NOTE_G4, t24);
switchRythmLed();
solo.play(NOTE_D4, t34);
switchSoloLed();
wait(rythm);
rythm.play(NOTE_B4, t14);
switchRythmLed();
wait(rythm);
rythm.play(NOTE_D5, t14);
switchRythmLed();
solo.play(NOTE_D4, t14);
switchSoloLed();
wait(rythm);
bass.play(NOTE_G3, t);
switchBassLed();
rythm.play(NOTE_G4, t24);
switchRythmLed();
solo.play(NOTE_D5, t);
switchSoloLed();
wait(rythm);
rythm.play(NOTE_B4, t14);
switchRythmLed();
wait(rythm);
rythm.play(NOTE_D5, t14);
switchRythmLed();
wait(rythm);
bass.play(NOTE_B3, t);
switchBassLed();
rythm.play(NOTE_G4, t24);
switchRythmLed();
solo.play(NOTE_B4, t);
switchSoloLed();
wait(rythm);
rythm.play(NOTE_B4, t14);
switchRythmLed();
wait(rythm);
rythm.play(NOTE_D5, t14);
switchRythmLed();
wait(rythm);
bass.play(NOTE_D4, t);
switchBassLed();
rythm.play(NOTE_G4, t24);
switchRythmLed();
solo.play(NOTE_G4, t);
switchSoloLed();
wait(rythm);
rythm.play(NOTE_B4, t14);
switchRythmLed();
wait(rythm);
rythm.play(NOTE_D5, t14);
switchRythmLed();
wait(rythm);
bass.play(NOTE_C4, t);
switchBassLed();
rythm.play(NOTE_C5, t24);
switchRythmLed();
solo.play(NOTE_FS4, t);
switchSoloLed();
wait(rythm);
rythm.play(NOTE_E5, t14);
switchRythmLed();
wait(rythm);
rythm.play(NOTE_G5, t14);
switchRythmLed();
wait(rythm);
bass.play(NOTE_E4, t);
switchBassLed();
rythm.play(NOTE_C5, t24);
switchRythmLed();
solo.play(NOTE_E4, t);
switchSoloLed();
wait(rythm);
rythm.play(NOTE_E5, t14);
switchRythmLed();
wait(rythm);
rythm.play(NOTE_G5, t14);
switchRythmLed();
wait(rythm);
bass.play(NOTE_G4, t);
switchBassLed();
rythm.play(NOTE_C5, t24);
switchRythmLed();
solo.play(NOTE_C5, t34);
switchSoloLed();
wait(rythm);
rythm.play(NOTE_E5, t14);
switchRythmLed();
wait(rythm);
rythm.play(NOTE_G5, t14);
switchRythmLed();
solo.play(NOTE_C5, t14);
switchSoloLed();
wait(rythm);
bass.play(NOTE_G3, t);
switchBassLed();
rythm.play(NOTE_G4, t24);
switchRythmLed();
solo.play(NOTE_B4, t);
switchSoloLed();
wait(rythm);
rythm.play(NOTE_B4, t14);
switchRythmLed();
wait(rythm);
rythm.play(NOTE_D5, t14);
switchRythmLed();
wait(rythm);
bass.play(NOTE_D3, t);
switchBassLed();
rythm.play(NOTE_G4, t24);
switchRythmLed();
solo.play(NOTE_G4, t);
switchSoloLed();
wait(rythm);
rythm.play(NOTE_B4, t14);
switchRythmLed();
wait(rythm);
rythm.play(NOTE_D5, t14);
switchRythmLed();
wait(rythm);
bass.play(NOTE_FS3, t);
switchBassLed();
rythm.play(NOTE_D5, t24);
switchRythmLed();
solo.play(NOTE_A4, t);
switchSoloLed();
wait(rythm);
wait(rythm);
rythm.play(NOTE_FS5, t14);
switchRythmLed();
wait(rythm);
rythm.play(NOTE_A5, t14);
switchRythmLed();
wait(rythm);
bass.play(NOTE_G3, t);
switchBassLed();
rythm.play(NOTE_G4, t24);
switchRythmLed();
solo.play(NOTE_G4, tt);
switchSoloLed();
wait(rythm);
rythm.play(NOTE_B4, t14);
switchRythmLed();
wait(rythm);
rythm.play(NOTE_D5, t14);
switchRythmLed();
wait(rythm);
bass.play(NOTE_B3, t);
switchBassLed();
rythm.play(NOTE_G4, t24);
switchRythmLed();
wait(rythm);
rythm.play(NOTE_B4, t14);
switchRythmLed();
wait(rythm);
rythm.play(NOTE_D5, t14);
switchRythmLed();
wait(rythm);
solo.play(NOTE_D4, t34);
switchSoloLed();
wait(solo);
solo.play(NOTE_D4, t14);
switchSoloLed();
wait(solo);
}
Processo de manufatura
- Sensor K30 CO₂: Monitoramento de Qualidade do Ar Interno em Tempo Real
- Facilitando Comunicação Surdo-Cego com 1Sheeld e Arduino
- Mealheiro Inteligente: Controlar Aceitador de Moedas com Arduino Nano
- Kit Arduino Nano: CrazyCircuits, Sensores DFRobot e Ferramentas – Crie Projetos com Confiança
- Controlar um LED via Bluetooth com Arduino – Guia DIY Simples
- Integrando Sensor de Impressão Digital Capacitivo DFRobot com Arduino ou ESP8266
- Projeto HMI Interativo com Nextion, Arduino Mega e Sensores
- Braço Robótico 6 GDL Controlado por Nunchuk com Arduino Mega
- Controle Dois Motores de Passo com Arduino Nano e Joystick – Tutorial Simples
- Contador Geiger Portátil com Arduino Nano: Construa o Seu