Display de Luz e Som com Arduino: Hino Nacional dos EUA
Componentes e Materiais
| Componente | Quantidade | Observações |
|---|---|---|
| Arduino Nano R3 (ATmega328P, old bootloader) | 1 | |
| Buzzer (16Ω usado no projeto) | 1 | Qualquer buzzer serve |
| Push-buttons 6x6x6mm (ou 12mm) | 2 | Um para hino, outro para "Charge" |
| Chave rocker (liga/desliga) | 1 | Para alimentação externa |
| Resistores 330Ω | 3 | Para LEDs (limita corrente a ~13-20mA) |
| LEDs (2 vermelhos, 2 brancos, 2 azuis) | 6 | Vermelho 2.2V, outros 3.2V |
| Mini protoboard soldável (ou perfurada) | 1 | |
| Bateria 9V (com suporte) | 1 | Ou 4x AA, ou USB |
Ferramentas
- Ferro de solda
Sobre o Projeto
Projeto que toca o Hino Nacional dos EUA (The Star-Spangled Banner) com acompanhamento de LEDs sincronizados, além do som "Charge" (tocado em estádios). Dois botões controlam as músicas; quando nenhum é pressionado, LEDs fazem efeito "twinkle" aleatório.
Vídeo demo: https://youtu.be/C2jyn80Mjus
Estrutura do Código
- Uso intensivo de funções para modularizar notas e controle de LEDs
- Função
SingleDWwithNote()toca nota + acende LED correspondente com suporte a staccato - Pitch aumenta progressivamente a cada execução do hino (reset no reboot)
- Botão "Charge" usa interrupção (pino D3 no Nano)
Conexões (Resumo)
- Buzzer: Pino D9
- LEDs Vermelhos: Pino D6 (2 em paralelo)
- LEDs Brancos: Pino D7 (2 em paralelo)
- LEDs Azuis: Pino D8 (2 em paralelo)
- Botão Início (Hino): D5 (INPUT_PULLUP)
- Botão Charge: D3 (INPUT_PULLUP, interrupção)
- Alimentação: Bateria 9V → VIN/GND do Nano
Detalhes Musicais
- BPM base: 104 (quarter note = 577ms)
- Notas mapeadas: Bb3 (233Hz) até F5 (698Hz)
- Staccato: x=0.92, y=0.08 (nota 92% on, 8% rest)
- Retard (ralentando) no final: n *= 1.08 depois 1.20
- Transposição final: todas as notas × 1.06³ (3 semitons acima)
Código Completo
/* Star Spangled Banner com LEDs
Criado por Ryan Aebi, Junho 2018 */
// --- Pinos ---
const int ChargeButton = 3; // D3 (interrupção)
const int StartButton = 5; // D5
const int BuzzerPin = 9; // D9
const int RedLED = 6; // D6
const int WhiteLED = 7; // D7
const int BlueLED = 8; // D8
// --- Variáveis de tempo ---
int n = 1000;
int DurationOn = n, DurationRest = n;
float x = 0.66, y = 0.34; // Para twinkle
int Twinkle_Rate = 250; // Taxa do efeito aleatório
// --- Estados dos botões ---
int StartButtonState, ChargeButtonState;
// --- Frequências das notas (Hz) ---
int Note1 = 233; // Bb3
int Note2 = 294; // D4
int Note3 = 330; // E4
int Note4 = 349; // F4
int Note5 = 392; // G4
int Note6 = 440; // A4
int Note7 = 466; // Bb4
int Note8 = 523; // C5
int Note9 = 587; // D5
int Note10 = 622; // Eb5
int Note11 = 698; // F5
// --- Função: Som "Charge" ---
void Charge() {
n = 600;
digitalWrite(RedLED, HIGH); tone(BuzzerPin, 392, n/3); delay(n/3); digitalWrite(RedLED, LOW); delay(70);
digitalWrite(WhiteLED, HIGH); tone(BuzzerPin, 523, n/3); delay(n/3); digitalWrite(WhiteLED, LOW); delay(70);
digitalWrite(BlueLED, HIGH); tone(BuzzerPin, 659, n/3); delay(n/3); digitalWrite(BlueLED, LOW); delay(70);
digitalWrite(RedLED, HIGH); digitalWrite(WhiteLED, HIGH); digitalWrite(BlueLED, HIGH);
tone(BuzzerPin, 784, n*3/4); delay(n*3/4);
digitalWrite(BlueLED, LOW); digitalWrite(RedLED, LOW); digitalWrite(WhiteLED, LOW); delay(70);
digitalWrite(BlueLED, HIGH); tone(BuzzerPin, 659, n/4); delay(n/4); digitalWrite(BlueLED, LOW); delay(70);
digitalWrite(RedLED, HIGH); digitalWrite(WhiteLED, HIGH); digitalWrite(BlueLED, HIGH);
tone(BuzzerPin, 784, n*2); delay(n*2);
digitalWrite(BlueLED, LOW); digitalWrite(RedLED, LOW); digitalWrite(WhiteLED, LOW); delay(70);
}
// --- Função auxiliar: Nota + LED + Staccato ---
void SingleDWwithNote(int HZ, int TurnOn, int Duration, int Staccato) {
if (Staccato == 1) DurationOn = Duration * x;
else DurationOn = Duration;
digitalWrite(TurnOn, HIGH);
tone(BuzzerPin, HZ, DurationOn);
delay(DurationOn);
digitalWrite(TurnOn, LOW);
if (Staccato == 1) {
DurationRest = Duration * y;
delay(DurationRest);
}
}
// --- Função: Hino Nacional EUA ---
void USNationalAnthem() {
n = 577; // 60000/104 BPM
x = 0.92; y = 0.08; // Staccato forte
// Barras 1-5 (Linha 1)
SingleDWwithNote(Note4, RedLED, n*3/4, 1);
SingleDWwithNote(Note2, WhiteLED, n/4, 1);
SingleDWwithNote(Note1, RedLED, n, 1);
SingleDWwithNote(Note2, WhiteLED, n, 1);
SingleDWwithNote(Note4, RedLED, n, 1);
SingleDWwithNote(Note7, WhiteLED, n*2, 1);
SingleDWwithNote(Note9, BlueLED, n*3/4, 1);
SingleDWwithNote(Note8, WhiteLED, n/4, 1);
SingleDWwithNote(Note7, RedLED, n, 1);
SingleDWwithNote(Note2, WhiteLED, n, 1);
SingleDWwithNote(Note3, BlueLED, n, 1);
SingleDWwithNote(Note4, RedLED, n*2, 1);
SingleDWwithNote(Note4, RedLED, n/2, 1);
SingleDWwithNote(Note4, RedLED, n/2, 1);
// Barras 6-9 (Linha 2)
SingleDWwithNote(Note9, BlueLED, n*3/2, 1);
SingleDWwithNote(Note8, WhiteLED, n/2, 1);
SingleDWwithNote(Note7, RedLED, n, 1);
SingleDWwithNote(Note6, BlueLED, n*2, 1);
SingleDWwithNote(Note5, WhiteLED, n/2, 1);
SingleDWwithNote(Note6, BlueLED, n/2, 1);
SingleDWwithNote(Note7, RedLED, n, 1);
SingleDWwithNote(Note7, RedLED, n, 1);
SingleDWwithNote(Note4, BlueLED, n, 1);
SingleDWwithNote(Note2, WhiteLED, n, 1);
SingleDWwithNote(Note1, BlueLED, n, 1);
SingleDWwithNote(Note4, RedLED, n*3/4, 1);
SingleDWwithNote(Note2, WhiteLED, n/4, 1);
// Barras 10-13 (Linha 3) - Repete início com variação
SingleDWwithNote(Note1, RedLED, n, 1);
SingleDWwithNote(Note2, WhiteLED, n, 1);
SingleDWwithNote(Note4, RedLED, n, 1);
SingleDWwithNote(Note7, WhiteLED, n*2, 1);
SingleDWwithNote(Note9, BlueLED, n*3/4, 1);
SingleDWwithNote(Note8, WhiteLED, n/4, 1);
SingleDWwithNote(Note7, RedLED, n, 1);
SingleDWwithNote(Note2, WhiteLED, n, 1);
SingleDWwithNote(Note3, BlueLED, n, 1);
SingleDWwithNote(Note4, RedLED, n*2, 1);
SingleDWwithNote(Note4, RedLED, n/2, 1);
SingleDWwithNote(Note4, RedLED, n/2, 1);
// Barras 14-17 (Linha 4, fim página 1)
SingleDWwithNote(Note9, BlueLED, n*3/2, 1);
SingleDWwithNote(Note8, WhiteLED, n/2, 1);
SingleDWwithNote(Note7, RedLED, n, 1);
SingleDWwithNote(Note6, BlueLED, n*2, 1);
SingleDWwithNote(Note5, WhiteLED, n/2, 1);
SingleDWwithNote(Note6, BlueLED, n/2, 1);
SingleDWwithNote(Note7, RedLED, n, 1);
SingleDWwithNote(Note7, RedLED, n, 1);
SingleDWwithNote(Note4, BlueLED, n, 1);
SingleDWwithNote(Note2, WhiteLED, n, 1);
SingleDWwithNote(Note1, RedLED, n, 1);
SingleDWwithNote(Note9, BlueLED, n/2, 1);
SingleDWwithNote(Note9, BlueLED, n/2, 1);
// Barras 18-21 (Linha 5, início página 2)
SingleDWwithNote(Note9, BlueLED, n, 1);
SingleDWwithNote(Note10, RedLED, n, 1);
SingleDWwithNote(Note11, WhiteLED, n, 1);
SingleDWwithNote(Note11, WhiteLED, n*2, 1);
SingleDWwithNote(Note10, RedLED, n/2, 1);
SingleDWwithNote(Note9, BlueLED, n/2, 1);
SingleDWwithNote(Note8, WhiteLED, n, 1);
SingleDWwithNote(Note9, BlueLED, n, 1);
SingleDWwithNote(Note10, RedLED, n, 1);
SingleDWwithNote(Note10, RedLED, n*2, 1);
SingleDWwithNote(Note10, RedLED, n, 1);
// Barras 22-25 (Linha 6)
SingleDWwithNote(Note9, WhiteLED, n*3/2, 1);
SingleDWwithNote(Note8, BlueLED, n/2, 1);
SingleDWwithNote(Note7, WhiteLED, n, 1);
SingleDWwithNote(Note6, RedLED, n*2, 1);
SingleDWwithNote(Note5, BlueLED, n/2, 1);
SingleDWwithNote(Note6, RedLED, n/2, 1);
SingleDWwithNote(Note7, WhiteLED, n, 1);
SingleDWwithNote(Note2, BlueLED, n, 1);
SingleDWwithNote(Note3, RedLED, n, 1);
SingleDWwithNote(Note4, WhiteLED, n*2, 1);
SingleDWwithNote(Note4, RedLED, n, 1);
n = n * 1.08; // Retard: 96 BPM
// Barras 26-28 (Linha 7)
SingleDWwithNote(Note7, WhiteLED, n, 1);
SingleDWwithNote(Note7, WhiteLED, n, 1);
SingleDWwithNote(Note7, WhiteLED, n/2, 1);
SingleDWwithNote(Note6, BlueLED, n/2, 1);
SingleDWwithNote(Note5, RedLED, n, 1);
SingleDWwithNote(Note5, RedLED, n, 1);
SingleDWwithNote(Note5, RedLED, n, 1);
SingleDWwithNote(Note8, WhiteLED, n, 1);
SingleDWwithNote(Note10, RedLED, n/2, 1);
SingleDWwithNote(Note9, BlueLED, n/2, 1);
SingleDWwithNote(Note8, WhiteLED, n/2, 1);
SingleDWwithNote(Note7, RedLED, n/2, 1);
// Barras 29-30
SingleDWwithNote(Note7, RedLED, n, 1);
SingleDWwithNote(Note6, BlueLED, n*2, 1);
SingleDWwithNote(Note4, RedLED, n/2, 1);
SingleDWwithNote(Note4, RedLED, n/2, 1);
SingleDWwithNote(Note7, BlueLED, n*3/2, 1);
SingleDWwithNote(Note8, WhiteLED, n/2, 1);
SingleDWwithNote(Note9, BlueLED, n/2, 1);
SingleDWwithNote(Note10, RedLED, n/2, 1);
n = n * 1.2; // Grande retard final
// Barras 31-34 (Fim)
SingleDWwithNote(Note11, WhiteLED, n*2, 1); // "Free" - nota longa
SingleDWwithNote(Note7, RedLED, n/2, 1);
SingleDWwithNote(Note8, WhiteLED, n/2, 1);
SingleDWwithNote(Note9, BlueLED, n*3/2, 1);
SingleDWwithNote(Note10, RedLED, n/2, 1);
SingleDWwithNote(Note8, WhiteLED, n, 1);
SingleDWwithNote(Note7, RedLED, n*3, 1); // "Brave" - nota final longa
// Transposição: sobe 3 semitons (×1.06³) para próxima execução
for (int i = 1; i <= 11; i++) {
int* notePtr = (i==1)?&Note1:(i==2)?&Note2:(i==3)?&Note3:(i==4)?&Note4:
(i==5)?&Note5:(i==6)?&Note6:(i==7)?&Note7:(i==8)?&Note8:
(i==9)?&Note9:(i==10)?&Note10:&Note11;
*notePtr = *notePtr * 1.06 * 1.06 * 1.06;
}
}
// --- Função: Efeito Twinkle (LEDs aleatórios) ---
void Twinkle(int Twinkle_Time) {
Twinkle_Time = Twinkle_Time / Twinkle_Rate; // Normaliza
for (; Twinkle_Time > 0; Twinkle_Time--) {
int B = random(1, 4); // 1, 2 ou 3
int C = random(1, 4);
if (B == 1) digitalWrite(RedLED, HIGH);
if (B == 2) digitalWrite(WhiteLED, HIGH);
if (B == 3) digitalWrite(BlueLED, HIGH);
if (C == 1) digitalWrite(RedLED, HIGH);
if (C == 2) digitalWrite(WhiteLED, HIGH);
if (C == 3) digitalWrite(BlueLED, HIGH);
delay(Twinkle_Rate);
if (B == 1) digitalWrite(RedLED, LOW);
if (B == 2) digitalWrite(WhiteLED, LOW);
if (B == 3) digitalWrite(BlueLED, LOW);
if (C == 1) digitalWrite(RedLED, LOW);
if (C == 2) digitalWrite(WhiteLED, LOW);
if (C == 3) digitalWrite(BlueLED, LOW);
}
}
// --- Setup ---
void setup() {
pinMode(ChargeButton, INPUT_PULLUP);
pinMode(StartButton, INPUT_PULLUP);
pinMode(RedLED, OUTPUT);
pinMode(WhiteLED, OUTPUT);
pinMode(BlueLED, OUTPUT);
pinMode(BuzzerPin, OUTPUT);
digitalWrite(RedLED, LOW);
digitalWrite(WhiteLED, LOW);
digitalWrite(BlueLED, LOW);
}
// --- Loop Principal ---
void loop() {
StartButtonState = digitalRead(StartButton); // LOW = pressionado
ChargeButtonState = digitalRead(ChargeButton); // LOW = pressionado
if (StartButtonState == LOW) {
USNationalAnthem();
} else if (ChargeButtonState == LOW) {
Charge();
} else {
Twinkle(Twinkle_Rate); // Efeito aleatório contínuo
}
}
Esquemáticos e Fotos
O projeto inclui diagramas Fritzing (protoboard e soldado), fotos da montagem interna e planilha de custos com links de compra.
Processo de manufatura
- Circuito com Chave: Guia Prático para Circuitos Elétricos Básicos
- A Evolução e Artesanato das Luzes Natalinas: Das Tradições Antigas à Engenharia Moderna
- Lenços Umedecidos: Como Loção Melhora Conforto e Desempenho
- Acceed IGS‑9822DGP: Switch Gigabit de 12 Portas com 4 Portas SFP – Solução de Rede Industrial de Alto Desempenho
- Monitoramento Preciso de Temperatura em Closet de Servidores com Raspberry Pi
- Painel de Chaves e LEDs para Microsoft Flight Simulator 2020 com Arduino
- Dominando Switch-Case em C++: Sintaxe, Uso e Exemplos Práticos
- Entendendo Switch-Case em C: Sintaxe, Exemplos e Boas Práticas
- Java Switch-Case Explicado: Sintaxe, Exemplos e Boas Práticas
- MEP National Network™ Faz Parceria com Fabricantes de Minorias para Impulsionar Crescimento