아두이노 나노로 3채널 폴리포니 '생일 축하 노래' 연주 - LED 동기화 데모
부품 및 소모품
앱 및 온라인 서비스
프로젝트 소개
아두이노 나노 한 대와 미니 브레드보드 위에 부저 3개로 '생일 축하 노래'를 3성부 폴리포니(다성음악)로 연주하는 초소형 장치입니다. 어떤 USB 전원(컴퓨터뿐만 아니라 보조배터리 등)에 꽂아도 노래를 무한 반복 재생합니다. 질릴 때까지요!
각 음이 바뀔 때마다 해당 채널/부저의 LED가 깜빡이며 시각적으로도 동기화됩니다.
회로도 및 브레드보드 배치
납땜 없이 모든 부품을 작은 브레드보드에 꽂아 만들었습니다. 아두이노 나노 v3.0(그라비테크 제품 사용, 호환 보드면 무관)이 브레드보드에 딱 맞게 들어가 양옆에 부품을 꽂을 수 있습니다.
핵심 포인트:
- 부저 3개와 LED 3개, 저항(100옴, 보통 220옴 권장지만 100옴 사용)을 브레드보드에 배치
- 부저 핀은 브레드보드 열 방향에 맞춰 꽂음(가운데 부저가 조금 큰데, 베이스 채널용이라 크기만 다를 뿐 성능 차이는 없음)
- 아두이노 I/O 핀을 GND 대용으로 사용: 핀을
LOW로 설정하면 그라운드 역할을 합니다. 이를 이용해 부저와 LED의 그라운드 핀을 아두이노 I/O 핀(14, 16, 18번 = A0, A2, A4)에 연결했습니다.
프로그램 설명
아래 전체 스케치 코드를 사용하려면 Tone 라이브러리가 필요합니다. GitHub 또는 직접 다운로드 후 아두이노 IDE의 스케치 → 라이브러리 포함 → .ZIP 라이브러리 추가로 설치하세요.
이 라이브러리는 하드웨어 타이머와 인터럽트를 이용해 단일 코어에서 여러 톤을 동시에 생성하는 '레드넥 멀티태스킹'을 구현합니다.
코드는 세 개의 독립적인 멜로디 스레드를 하나의 선형 흐름으로 처리하려다 보니 다소 길고 복잡합니다. 리팩토링하면 다양한 곡에 재사용 가능하겠지만, 현재는 '생일 축하 노래' 전용입니다.
코드 (Happy_birthday.ino)
#include <Tone.h>
Tone solo;
Tone bass;
Tone rythm;
const int t = 600; // 4분음표 길이
const int tt = t * 2; // 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; // A1
const int rythmLedPin = 17; // A3
const int soloLedPin = 19; // A5
void wait(Tone t) { while (t.isPlaying()) { } }
int bassLedState = LOW;
void switchBassLed() { bassLedState = !bassLedState; digitalWrite(bassLedPin, bassLedState); }
int rythmLedState = LOW;
void switchRythmLed() { rythmLedState = !rythmLedState; digitalWrite(rythmLedPin, rythmLedState); }
int soloLedState = LOW;
void switchSoloLed() { soloLedState = !soloLedState; digitalWrite(soloLedPin, soloLedState); }
void setup() {
pinMode(14, OUTPUT); pinMode(16, OUTPUT); pinMode(18, OUTPUT); // LED 그라운드 핀 (A0, A2, A4)
pinMode(bassLedPin, OUTPUT);
pinMode(rythmLedPin, OUTPUT);
pinMode(soloLedPin, OUTPUT);
pinMode(2, OUTPUT); // 솔로 부저 그라운드
pinMode(9, OUTPUT); // 리듬 부저 그라운드
solo.begin(6); // 솔로 부저 신호 핀
bass.begin(12); // 베이스 부저 신호 핀
rythm.begin(0); // 리듬 부저 신호 핀
// 시작 음
solo.play(NOTE_D4, t34); switchSoloLed(); wait(solo);
solo.play(NOTE_D4, t14); switchSoloLed(); wait(solo);
}
void loop() {
// 생일 축하 노래 멜로디 시퀀스 (bass, rythm, solo 3채널 동시 연주)
// 각 채널별로 play() 호출 후 LED 토글, wait()로 동기화
// ... (전체 멜로디 코드는 원본 참조, 약 300줄 분량)
// 예시: 첫 마디
bass.play(NOTE_G3, t); switchBassLed();
rythm.play(NOTE_G4, t24); switchRythmLed();
solo.play(NOTE_E4, t); switchSoloLed(); wait(rythm);
// ... 이하 생략 (전체 코드는 GitHub 또는 원문 참조)
}
참고 자료