1. 아두이노 보드를 사용한 부저 제어 실습 (1)
블랙베리에 있는 부저를 제어하는 실습을 하기에 앞서 부저의 작동 원리에 대해 알아보겠습니다.
부저 내부에는 얇은 판이 있습니다. 피에조 효과에 의해 이 얇은 판에 전압을 가하면 얇은 판에는 기계적인 변형이 생기게 됩니다.
또한 소리의 높낮이는 음파의 진동수(주파수)에 따라 달라집니다.
이 점들을 이용해서 우리는 부저(의 내부에 있는 얇은 판)에 특정한 주파수의 전압을 인가하면 신호에 따라 얇은 판이 진동하면서 공기를 진동시켜 원하는 높이의 음을 낼 수 있게 됩니다.

부저를 제어해 소리를 내는 실습을 하기 위해서는 부저가 연결된 핀에서 특정 주파수를 가진 신호를 발생시키는 기능이 필요합니다. 이를 위해 이번 실습에서는 아두이노에서 제공하는 tone 함수를 사용할 것입니다. tone 함수는 핀에 특정 주파수(50% 듀티 사이클)의 구형파를 발생시키는 함수입니다.

2. 아두이노 보드를 사용한 부저 제어 실습 (2)

(4) 이전에 연주된 음계를 저장하는 변수를 선언합니다.
3. 아두이노 보드를 사용한 부저 제어 실습 (3)

소리를 출력하는데 사용된 함수들은 아래와 같습니다.
tone(pin, freq) : 특정 핀에 특정 주파수의 구형파를 발생시키는 함수입니다.
noTone(pin) : 특정 핀에 tone 함수에 의해 시작된 구형파 발생을 멈추는 함수입니다.
setup 에서는 아래와 같은 동작을 합니다.
delay 함수는 음을 지속하기 위해 사용됩니다.
블랙베리에 프로그램을 업로드하면 음악이 연주됩니다.
////////////// 부저
#define BUZZER_PIN 5
#define OCTAVE_4_DO 262
#define OCTAVE_4_RE 294
#define OCTAVE_4_MI 330
#define OCTAVE_4_SOL 392
#define OCTAVE_4_LA 440
#define OCTAVE_4_TI 494
#define OCTAVE_5_DO 523
#define WHOLE_NOTE 1300
#define HALF_NOTE WHOLE_NOTE/2
#define QUATER_NOTE WHOLE_NOTE/4
#define DOTTED_QUATER_NOTE WHOLE_NOTE*3/8
#define EIGHTH_NOTE WHOLE_NOTE/8
#define SIXTEENTH_NOTE WHOLE_NOTE/16
#define SHORT_DELAY 10
int melody[] = {OCTAVE_4_MI, OCTAVE_4_RE, OCTAVE_4_DO, OCTAVE_4_RE,
OCTAVE_4_MI, OCTAVE_4_MI, OCTAVE_4_MI,
OCTAVE_4_RE, OCTAVE_4_RE, OCTAVE_4_RE,
OCTAVE_4_MI, OCTAVE_4_SOL, OCTAVE_4_SOL,
OCTAVE_4_MI, OCTAVE_4_RE, OCTAVE_4_DO, OCTAVE_4_RE,
OCTAVE_4_MI, OCTAVE_4_MI, OCTAVE_4_MI,
OCTAVE_4_RE, OCTAVE_4_RE, OCTAVE_4_MI, OCTAVE_4_RE,
OCTAVE_4_DO};
int note[] = {DOTTED_QUATER_NOTE, EIGHTH_NOTE, QUATER_NOTE, QUATER_NOTE,
QUATER_NOTE, QUATER_NOTE, HALF_NOTE,
QUATER_NOTE, QUATER_NOTE, HALF_NOTE,
QUATER_NOTE, QUATER_NOTE, HALF_NOTE,
DOTTED_QUATER_NOTE, EIGHTH_NOTE, QUATER_NOTE, QUATER_NOTE,
QUATER_NOTE, QUATER_NOTE, HALF_NOTE,
QUATER_NOTE, QUATER_NOTE, QUATER_NOTE, QUATER_NOTE,
WHOLE_NOTE};
int prevNote = 0;
void setup() {
if (sizeof(melody) != sizeof(note))
while(1) {}; // 두 배열의 사이즈가 다르면 연주할 수 없음
for (int i = 0 ; i < sizeof(melody)/sizeof(int) ; i++) {
if (prevNote == melody[i]) { // 현재 출력하려는 음이 이전 음과 같을 때
noTone(BUZZER_PIN); // 잠깐 끊어서 구분함
delay(SHORT_DELAY);
}
tone(BUZZER_PIN, melody[i]);
delay(note[i]);
prevNote = melody[i];
}
noTone(BUZZER_PIN);
}
void loop() {
}
아래의 소스는 몇 가지 사운드를 출력하는 예제입니다. 실행해 보고 마음에 드는 것을 사용해 보세요.
/*
[부저 경고음 통합 예제]
- 질문에서 준 멜로디(작은별/학교종 느낌) 1회 재생
- 작업 이벤트용 경고음 함수들(발견/단계완료/전체완료/경고/오류/위험/확인요청/시작)
- setup()에서 순서대로 테스트 재생
BUZZER_PIN = 5
*/
#include <Arduino.h>
////////////// 부저
#define BUZZER_PIN 5
// 음계(질문 예제 + 확장)
#define OCTAVE_4_DO 262
#define OCTAVE_4_RE 294
#define OCTAVE_4_MI 330
#define OCTAVE_4_SOL 392
#define OCTAVE_4_LA 440
#define OCTAVE_4_TI 494
#define OCTAVE_5_DO 523
#define C4 262
#define D4 294
#define E4 330
#define F4 349
#define G4 392
#define A4 440
#define B4 494
#define C5 523
#define E5 659
#define G5 784
// 박자(질문 예제)
#define WHOLE_NOTE 1300
#define HALF_NOTE (WHOLE_NOTE/2)
#define QUATER_NOTE (WHOLE_NOTE/4)
#define DOTTED_QUATER_NOTE (WHOLE_NOTE*3/8)
#define EIGHTH_NOTE (WHOLE_NOTE/8)
#define SIXTEENTH_NOTE (WHOLE_NOTE/16)
#define SHORT_DELAY 10
// 경고음용 gap
#define GAP_SHORT 20
#define GAP_MED 80
#define GAP_LONG 200
// ===== 공통 유틸 =====
void beep(int freq, int dur, int gap = GAP_SHORT) {
tone(BUZZER_PIN, freq);
delay(dur);
noTone(BUZZER_PIN);
delay(gap);
}
void beepSeparated(int freq, int dur, int gap = GAP_SHORT) {
noTone(BUZZER_PIN);
delay(10);
tone(BUZZER_PIN, freq);
delay(dur);
noTone(BUZZER_PIN);
delay(gap);
}
// ===== 작업 이벤트용 경고음 패턴들 =====
// 1) 작업 시작
void soundStart() {
beep(C4, SIXTEENTH_NOTE);
beep(E4, SIXTEENTH_NOTE);
beep(G4, EIGHTH_NOTE, GAP_MED);
}
// 2) 특정한 것 발견
void soundFound() {
beepSeparated(E5, SIXTEENTH_NOTE);
beepSeparated(E5, SIXTEENTH_NOTE, GAP_MED);
}
// 3) 단계 완료/성공
void soundStepDone() {
beep(C4, EIGHTH_NOTE);
beep(E4, EIGHTH_NOTE);
beep(C5, QUATER_NOTE, GAP_LONG);
}
// 4) 전체 작업 완료
void soundAllDone() {
beep(C4, EIGHTH_NOTE);
beep(G4, EIGHTH_NOTE);
beep(C5, EIGHTH_NOTE);
beep(G4, EIGHTH_NOTE);
beep(C5, QUATER_NOTE, GAP_LONG);
}
// 5) 주의/경고(짧-짧-길 x3)
void soundWarning() {
for (int i = 0; i < 3; i++) {
beep(A4, SIXTEENTH_NOTE);
beep(A4, SIXTEENTH_NOTE);
beep(A4, EIGHTH_NOTE, GAP_MED);
}
delay(GAP_LONG);
}
// 6) 오류/실패(하강 + 길게)
void soundError() {
beep(C5, EIGHTH_NOTE);
beep(G4, EIGHTH_NOTE);
beep(E4, HALF_NOTE, GAP_LONG);
}
// 7) 긴급/위험(사이렌 느낌)
void soundDanger() {
for (int i = 0; i < 6; i++) {
beep(G5, SIXTEENTH_NOTE, GAP_SHORT);
beep(E5, SIXTEENTH_NOTE, GAP_SHORT);
}
delay(GAP_LONG);
}
// 8) 사용자 확인 필요
void soundNeedConfirm() {
beep(F4, EIGHTH_NOTE, GAP_MED);
beep(F4, EIGHTH_NOTE, GAP_LONG);
}
void setup() {
// 아래는 테스트용: 이벤트 경고음들을 순서대로 들려줌
soundStart(); delay(500);
soundFound(); delay(500);
soundStepDone(); delay(500);
soundWarning(); delay(500);
soundError(); delay(500);
soundDanger(); delay(500);
soundAllDone(); delay(500);
soundNeedConfirm(); delay(500);
// 끝
noTone(BUZZER_PIN);
}
void loop() {
// 실제 프로젝트에서는 여기서 조건에 따라
// soundFound(), soundError() 같은 함수를 호출하면 됩니다.
}
'소프트웨어 > Arduino' 카테고리의 다른 글
| 아두이노 디지털 출력을 사용한 LED 제어 실습 #1 (0) | 2026.03.11 |
|---|---|
| Arduino Control (Jellibi AGV) - 서보(Servo) 모터와 부저(Buzzer) (0) | 2026.03.09 |
| Jellibi 기초 제어 실습 (0) | 2026.03.09 |
| 로봇 젤리비 AGV 2 소개 및 Arduino Software 설치 (0) | 2026.03.09 |
| PSD를 사용한 측정 및 거리 출력 실습 (0) | 2026.03.09 |