듀얼 아두이노로 연주하는 '일 vento d'oro(죠르노 테마)' – 정밀한 음정과 타이밍 구현
부품 및 소모품
| 부품 |
수량 |
| Arduino UNO |
2개 |
| MOSFET 트랜지스터 (스위칭용) |
2개 |
| 스피커: 3W, 4옴 |
4개 |
| 저항 1k옴 (0.25W) |
2개 |
| SparkFun 브레드보드 파워 서플라이 스틱 5V/3.3V |
1개 |
| 점퍼 와이어 (일반) |
1세트 |
필요한 도구 및 장비
소프트웨어 및 온라인 서비스
프로젝트 개요
이 프로젝트는 두 대의 아두이노 보드를 사용하여 죠죠의 기묘한 모험 5부의 메인 테마인 'Il Vento D'oro (황금의 바람)'를 정밀한 음정과 타이밍으로 재생하는 방법을 보여줍니다.
작동 원리
- 메인 보드(Primary Arduino): 핀 2에서 트리거 펄스를 출력하여 서브 보드와 동기화
- 서브 보드(Secondary Arduino): 핀 3에서 트리거 신호를 수신하여 연주를 시작
- 각 보드는 전용 파형 배열을 실행하며, 높은 옥타브의 음은 두 번째 아두이노에서 연주하여 주파수 클리핑을 방지
- 내장
tone() 함수와 간단한 디지털 핸드셰이크로 실시간 동기화 달성
소스 코드
파트 1: 메인 아두이노 (Primary)
#include "Color.h"
int S[] = {
Pink1, 0, Pink1, 0, Pink1, Blue1, 0, Pink1, 0, Orange2, 0, Pink1, 0, Green1, Blue1, 0,
Pink1, 0, Pink1, 0, Pink1, Blue1, 0, Pink1, 0, LGreen2, 0, Yellow2, 0, Orange2, Blue1, 0,
Pink1, 0, Pink1, 0, Pink1, Blue1, 0, Pink1, 0, Orange2, 0, Pink1, 0, Green1, Blue1, 0,
Pink1, 0, Pink1, 0, Pink1, Blue1, Pink1, Orange2, 0, LGreen2, 0, Yellow2, 0, Orange2, Blue1, 0,
Pink1, 0, Pink1, 0, Pink1, Blue1, 0, Pink1, 0, Orange2, 0, Pink1, 0, Green1, Blue1, 0,
Pink1, 0, Pink1, 0, Pink1, 0, Blue1, Pink1, 0, 0, 0, 0, Pink1, 0, Orange2, 0, Yellow2,
LGreen2, 0, Green2, 0, Blue2, 0, Green2, 0, Blue2, Purple2, 0, Pink2, 0, Purple2, 0,
Blue2, Green2, 0, Yellow2, 0, Orange2, LBlue1, 0, Blue1, 0, Purple1, 0, Pink1, 0,
Orange2, 0, Yellow2, LGreen2, 0, Green2, 0, Blue2, 0, Green2, 0, Blue2, Purple2, 0,
Pink2, 0, Blue2, Pink2, Blue2, 0, Purple2, Pink2, 0, LBlue1, 0, LBlue1, Blue1, Blue1,
Purple1, 0, Pink1, 0, Orange2, 0, Yellow2, LGreen2, 0, Green2, 0, Blue2, 0, Green2, 0,
Blue2, Purple2, 0, Pink2, 0, Purple2, 0, Blue2, Green2, 0, Yellow2, 0, Orange2, LBlue1, 0,
Blue1, 0, Purple1, 0, Pink1, 0, Orange2, DOrange2, Pink1, 0, Blue1, 0, 0, Pink1, 0, 0,
Pink1, 0, 0, 0, Green1, 0, Blue1, 0, Pink1, 0, DOrange2, 0, 0, Blue1, 0, 0, Pink1, 0,
0, 0, 0, 0, Orange2, DOrange2, Pink1, 0, Blue1, 0, 0, Pink1, 0, 0, Pink1, 0, 0,
Green1, 0, 0, DOrange2, 0, Orange2, 0, DOrange2, 0, 0, Blue1, 0, DOrange1, Yellow1,
Green1, DOrange1, Green1, LBlue1, Pink1, Orange2, DOrange2, Pink1, 0, Blue1, 0, 0,
Pink1, 0, 0, Pink1, 0, 0, 0, Green1, 0, Blue1, 0, Pink1, 0, DOrange2, 0, 0, Blue1, 0,
0, Pink1, 0, 0, 0, 0, 0, Orange2, DOrange2, Pink1, 0, Blue1, Orange2, 0, Green2,
Yellow2, Orange2, Pink1, 0, Blue2, LBlue2, 0, Green2, Orange2, DOrange2, 0, Pink1,
Blue1, Pink1, 0, Blue1, Pink1, 0, Blue1, Pink1, 0, Blue1, Pink1, 0, Blue1, Pink1,
Orange2, 0, Green2, 0, 0, 0, 0, 0, Orange2, 0, 0, 0, 0, 0, 0, Orange2, Yellow2,
LGreen2, 0, 0, Yellow2, 0, 0, Orange2, 0, DOrange2, 0, 0, Orange2, 0, 0, Yellow2, 0,
Green2, 0, 0, 0, 0, 0, Pink2, 0, 0, 0, 0, 0, Pink1, 0, DOrange2, 0, Orange2, 0, 0,
Yellow2, 0, 0, Orange2, 0, DOrange2, 0, 0, Blue2, 0, 0, DGreen2, 0, Green2, 0, 0,
0, 0, 0, Orange2, 0, 0, 0, 0, 0, 0, Orange2, Yellow2, LGreen2, 0, 0, Yellow2, 0, 0,
Orange2, 0, DOrange2, 0, 0, Orange2, 0, 0, Yellow2, 0, Green2, 0, 0, 0, 0, 0, Pink2,
0, 0, 0, 0, 0, Green2, 0, Purple2, 0, Pink2, 0, 0, DGreen2, 0, 0, Green2, 0, LGreen2,
0, 0, Pink2, 0, 0, Green2, 0, Green2
};
int L = sizeof(S);
int nds = 10;
void setup() {
Serial.begin(115200);
pinMode(2, OUTPUT); // 트리거 출력 핀
L = L / 2;
Serial.println(L);
Tone();
}
void loop() {}
void Tone() {
digitalWrite(2, HIGH); // 서브 보드에 시작 신호 전송
for (int n = 0; n < L; n++) {
int nd = 1000 / nds;
tone(6, S[n], nd); // 핀 6에서 음 재생
int d = nd * 1.2;
delay(d);
noTone(6);
}
}
파트 2: 서브 아두이노 (Secondary)
#include "Color.h"
int S[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
Pink2, 0, Pink2, 0, Pink2, Blue2, 0, Pink2, 0, Orange3, 0, Pink2, 0, Green2, Blue2, 0,
Pink2, 0, Pink2, 0, Pink2, Blue2, 0, Pink2, 0, LGreen3, 0, Yellow3, 0, Orange3, Blue2, 0,
Pink2, 0, Pink2, 0, Pink2, Blue2, 0, Pink2, 0, Orange3, 0, Pink2, 0, Green2, Blue2, 0,
Pink2, 0, Pink2, 0, Pink2, 0, Blue2, Pink2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
Orange3, DOrange3, Pink2, 0, Blue2, 0, 0, Pink2, 0, 0, Pink2, 0, 0, 0, Green2, 0, Blue2,
0, Pink2, 0, DOrange3, 0, 0, Blue2, 0, 0, Pink2, 0, 0, 0, 0, 0, Orange3, DOrange3, Pink2,
0, Blue2, 0, 0, Pink2, 0, 0, Pink2, 0, 0, Green2, 0, 0, DOrange3, 0, Orange3, 0, DOrange3,
0, 0, Blue2, 0, DOrange2, Yellow2, Green2, DOrange2, Green2, LBlue2, Pink2, Orange3,
DOrange3, Pink2, 0, Blue2, 0, 0, Pink2, 0, 0, Pink2, 0, 0, 0, Green2, 0, Blue2, 0, Pink2,
0, DOrange3, 0, 0, Blue2, 0, 0, Pink2, 0, 0, 0, 0, 0, Orange3, DOrange3, Pink2, 0, Blue2,
Orange3, 0, Green3, Yellow3, Orange3, Pink2, 0, Blue3, LBlue3, 0, Green3, Orange3, DOrange3,
0, Pink2, Blue2, Pink2, 0, Blue2, Pink2, 0, Blue2, Pink2, 0, Blue2, Pink2, 0, Blue2, Pink2,
Orange3, 0, Green2, 0, 0, 0, 0, 0, Orange2, 0, 0, 0, 0, 0, 0, Orange2, Yellow2, LGreen2,
0, 0, Yellow2, 0, 0, Orange2, 0, DOrange2, 0, 0, Orange2, 0, 0, Yellow2, 0, Green2, 0,
0, 0, 0, 0, Pink2, 0, 0, 0, 0, 0, Pink1, 0, DOrange2, 0, Orange2, 0, 0, Yellow2, 0, 0,
Orange2, 0, DOrange2, 0, 0, Blue2, 0, 0, DGreen2, 0, Green2, 0, 0, 0, 0, 0, Orange2, 0,
0, 0, 0, 0, 0, Orange2, Yellow2, LGreen2, 0, 0, Yellow2, 0, 0, Orange2, 0, DOrange2, 0,
0, Orange2, 0, 0, Yellow2, 0, Green2, 0, 0, 0, 0, 0, Pink2, 0, 0, 0, 0, 0, Pink2, 0,
DOrange3, 0, Orange3, 0, 0, DGreen3, 0, 0, Green3, 0, LGreen3, 0, 0, Orange3, 0, 0,
Purple2, 0, Pink2
};
int L = sizeof(S);
int nds = 10;
void setup() {
Serial.begin(115200);
pinMode(3, INPUT_PULLUP); // 트리거 입력 핀 (풀업)
L = L / 2;
Serial.println(L);
}
void loop() {
if (!digitalRead(3)) { // 트리거 신호 감지 시 연주 시작
Tone();
}
}
void Tone() {
for (int n = 0; n < L; n++) {
int nd = 1000 / nds;
tone(6, S[n], nd);
int d = nd * 1.2;
delay(d);
noTone(6);
}
}
회로도
스피커 연결 회로도 (Fritzing 파일: speaker_setup_kNNawzl740.fzz)
두 아두이노 각각에 스피커 2개씩 연결, MOSFET으로 드라이브
핵심 포인트
- Color.h 헤더 파일에 음계 상수(Pink1, Blue1, Orange2 등)가 정의되어 있어야 함
- 메인 보드의 핀 2 → 서브 보드의 핀 3 연결로 동기화
- 각 보드의 핀 6에 스피커 연결 (MOSFET 드라이브 회로 필요)
- 전원: 브레드보드 파워 서플라이로 5V 공급