[실습] 버저(Buzzer)를 이용한 작은별 동요 실행
필기자
23시간 37분전
49
0
본문
버저(Buzzer)를 이용한 작은별 동요 실행
목 적
1. 버저(Buzzer) 액츄레이터 모듈 설치

2. 버저(Buzzer) 액츄레이터 구동 및 응용

[문제: 부저를 이용한 동요 재생 실습]

목 적
- 라즈베리파이에 버저(Buzzer) 액추레이터 사용법을 이해한다.
- 버저(Buzzer) 액추레이터를 응용하여 단음 작은별 동요를 실행한다.
1. 버저(Buzzer) 액츄레이터 모듈 설치
2. 버저(Buzzer) 액츄레이터 구동 및 응용
2. 버저(Buzzer) 액츄레이터 구동 및 응용
1. 버저(Buzzer) 액츄레이터 모듈 설치
- 액티브 버저 모듈
- 액티브 버저 모듈은 전기 신호를 받았을 때 소리를 내는 장치임.
- 내장된 발진 회로를 가지고 있어서 단순히 전원을 공급하면 특정 주파수로 소리를 낼 수 있음.
- 액티브 버저는 로봇, 알람 시스템, 사용자 인터페이스 피드백 등 다양한 응용 프로그램에 사용됨.
- 기본 사양
- 전원 공급: 일반적으로 3.3V 또는 5V DC
- 소비 전류: 약 30mA
- 작동 주파수: 주로 2kHz 내외
- 가청 주파수 : 20Hz ~ 20,000Hz(20kHz)
- 소리 크기: 약 85 dB 정도
- GPIO 연결
- VCC : 3.3V 또는 5V Power(핀 1 또는 2)
- GND : Ground 접지(핀 2)
- IN : 입력 핀으로 LOW 또는 HIGH 신호에 따라 버저가 활성화됨
- GPIO 17(핀 11)
2. 버저(Buzzer) 액츄레이터 구동 및 응용
- 기본 구동 프로그램 : 라즈베리파이 가상환경에서 파이썬 코딩
- VSCode에서 buzzer.py 파일 생성
- GPIO 17핀(핀 11)을 출력 모드로 설정
- GPIO 17핀을 순회하면 On/Off 코딩

#twinkle_buzzer.py
import RPi.GPIO as GPIO
import time
# GPIO 모드 설정
GPIO.setmode(GPIO.BCM)
# 사용할 GPIO 핀의 번호를 설정한다. 여기서는 17번 핀을 사용한다.
BUZZER_PIN = 17
GPIO.setup(BUZZER_PIN, GPIO.OUT)
try:
while True:
# 부저를 켠다.
GPIO.output(BUZZER_PIN, GPIO.HIGH)
print("Buzzer on")
time.sleep(1) # 1초 동안 대기
# 부저를 끈다.
GPIO.output(BUZZER_PIN, GPIO.LOW)
print("Buzzer off")
time.sleep(1) # 1초 동안 대기
except KeyboardInterrupt:
# 프로그램 종료 시 GPIO 핀 상태를 초기화한다.
GPIO.cleanup()
- 계이름 응용 구동 프로그램 : 라즈베리파이 가상환경에서 파이썬 코딩
- VSCode에서 buzzer_melody.py 파일 생성
- 주파수 대역과 음 지속 시간을 이용하여 계이름(도레미파...시도) 소리 출력
import RPi.GPIO as GPIO
import time
# GPIO 모드 설정
GPIO.setmode(GPIO.BCM)
# Buzzer 핀 설정
BUZZER_PIN = 17
GPIO.setup(BUZZER_PIN, GPIO.OUT)
pwm = None
# PWM 인스턴스 생성 및 초기 주파수 설정
pwm = GPIO.PWM(BUZZER_PIN, 100) #부저의 경우 MAX 2000(2kHz), 출력 범위(약 1Hz ~ 10kHz)
pwm.start(0)
# 주요 음표의 주파수 (단위: Hz)
notes = {
'C4': 261.63,
'D4': 293.66,
'E4': 329.63,
'F4': 349.23,
'G4': 392.00,
'A4': 440.00,
'B4': 493.88,
'C5': 523.25 # 추가된 높은 도 음표
}
# 간단한 멜로디 (음표와 지속 시간)
melody = [('C4', 0.5), ('D4', 0.5), ('E4', 0.5), ('F4', 0.5),
('G4', 0.5), ('A4', 0.5), ('B4', 0.5), ('C5', 0.5)] # 마지막 음을 높은 도로 변경
def play(note, duration):
pwm.ChangeFrequency(notes[note])
pwm.ChangeDutyCycle(50) # 켜짐
time.sleep(duration) # 음표 지속 시간
pwm.ChangeDutyCycle(0) # 꺼짐
try:
for note, duration in melody:
play(note, duration)
time.sleep(0.1) # 음표 사이의 간격
finally:
if pwm is not None:
try:
pwm.stop()
except:
pass
del pwm # __del__ 호출 시 오류 방지
GPIO.cleanup()
- PWM(Pulse Width Modulation) 이론
| 용어 | 설명 |
|---|---|
| PWM (펄스폭 변조) | 디지털 핀에서 출력 신호의 ON/OFF 비율을 조절하여 아날로그처럼 동작하게 하는 방식 |
| DutyCycle(듀티 사이클) | 하나의 주기 내에서 ON(신호 High) 상태가 차지하는 비율(%) 예: 50%면 ON/OFF 비율이 1:1 (음색이 변함, 예: 10%는 얇고 날카로운 소리, 90%는 두껍고 탁한 소리) |
| Frequency(주파수) | 1초당 반복되는 PWM 신호의 횟수(Hz) |
| 응용 분야 | 모터 속도 조절, LED 밝기 조절, 부저(Buzzer) 음정 제어 등 |
- 소리의 원리
| 항목 | 설명 |
|---|---|
| 진동수(Hz) | 초당 공기의 압력이 몇 번 변화하는가 |
| 주파수 ↑ | 음의 높이가 높아짐 (예: 도 → 미 → 솔) |
| 주파수 ↓ | 음의 높이가 낮아짐 |
| 부저(PWM) | 전기적 ON/OFF로 진동을 만들어 공기를 흔듦 |
| 귀 | 공기 진동(파동)을 받아 음높이로 인식 |
| 가청 주파수 | 약 20Hz ~ 20,000Hz |
- PWM에서 LED 밝기 조절 공식
- 전압, 전류, 저항, 전력
- 전압 (V) → 수압 (물을 밀어주는 힘)
- 전류 (A) → 수량 (실제 흐르는 물의 양)
- 저항 (Ω) → 파이프 좁기 (굵을수록 저항 작음, 좁을수록 저항 큼)
- 전력 (W) → 물레방아 회전력 (실제 일하는 양)
- 공급 전압 Vsupply = 3.3V (라즈베리파이 GPIO 기준), 저항 R = 50Ω (GPIO 내부 저항), 듀티사이클 80%
- LED 순방향 전압(Vf)은 색상마다 다름 (데이터시트 KY-009 5050 RGB 기준)
- 빨강: 1.8V ~ 2.4V (대표값 2.0V)
- 초록: 2.8V ~ 3.6V (데이터시트 기준, 실사용 시 약 2.7V로 낮아짐)
- 파랑: 2.8V ~ 3.6V (데이터시트 기준, 실사용 시 약 2.7V로 낮아짐)
- LED 밝기 단위 : mcd (밀리칸델라)
- mcd는 특정 방향으로 얼마나 밝게 빛나는지를 나타내는 광도 단위이다.
- 데이터시트 기준값 (KY-009 5050 RGB, 20mA 기준)
- 빨강: 300 ~ 500 mcd
- 초록: 500 ~ 700 mcd
- 파랑: 200 ~ 400 mcd
- 단, 데이터시트 mcd 값은 20mA 정격 전류 기준이므로, 이 실습(GPIO 내부 저항만 사용, 전류 다름)에서는 데이터시트 값을 그대로 적용할 수 없다.
- 정확한 밝기(mcd)와 평균 전류의 비례 관계는 직접 실험으로 측정해야 한다.
- 조도계 (lux meter) 준비
- LED와 조도계 거리 고정
- 듀티사이클 10% ~ 100% 단계별 변화
- 각 단계별 조도 (lux) 측정
- 평균 전류 vs 조도 그래프 작성
- 전압, 전류, 저항, 전력
- 순간 전류 (옴의 법칙):
I = (Vsupply − Vf) / R - 평균 전류 (옴의 법칙 × 듀티사이클) ∝ LED 밝기 :
Iavg = I × 듀티사이클
※ 색상별 순간 전류 (3.3V 기준, R = 50Ω GPIO 내부 저항)
| 색상 | Vf (데이터시트) | Vf (실사용 추정) | 순간 전류 I (mA) I = (3.3 − Vf) / 50 |
mcd (데이터시트, 20mA 기준) |
|---|---|---|---|---|
| 빨강 | 1.8V ~ 2.4V | 2.0V | (3.3 − 2.0) / 50 = 26mA | 300 ~ 500 mcd |
| 초록 | 2.8V ~ 3.6V | 약 2.7V ※ | (3.3 − 2.7) / 50 = 12mA | 500 ~ 700 mcd |
| 파랑 | 2.8V ~ 3.6V | 약 2.7V ※ | (3.3 − 2.7) / 50 = 12mA | 200 ~ 400 mcd |
※ 초록/파랑은 데이터시트 기준 Vf가 3.2V이지만, LED는 비선형 소자이므로 전류가 낮아지면 실제 Vf도 함께 낮아진다. 3.3V GPIO 환경에서는 약 2.7V 수준에서 동작점이 형성되어 정상 발광한다.
※ Keyes CNT1 모듈은 전류 제한 저항이 내장되어 있지 않으므로, GPIO 내부 저항(약 50Ω)만으로 전류가 제한된다. 빨강의 경우 GPIO 핀 권장 전류(16mA)를 초과하므로, 정식 회로 설계 시에는 외부 저항(150Ω 권장) 추가를 권장한다.
※ 위 mcd 값은 20mA 정격 전류 기준이며, 실습 환경의 전류와 다르므로 실제 밝기는 데이터시트 값과 다를 수 있다. 정확한 밝기 측정이 필요한 경우 조도계를 이용한 직접 실험이 필요하다.
빨강 LED 기준 듀티사이클별 평균 전류 (I = 26mA)
| 듀티사이클 (%) | 순간 전류 (mA) I = (3.3−2.0)/50 |
평균 전류 (mA) Iavg = I × 듀티 |
|---|---|---|
| 10% | 26 | 26 × 0.1 = 2.6 |
| 20% | 26 | 26 × 0.2 = 5.2 |
| 30% | 26 | 26 × 0.3 = 7.8 |
| 40% | 26 | 26 × 0.4 = 10.4 |
| 50% | 26 | 26 × 0.5 = 13.0 |
| 60% | 26 | 26 × 0.6 = 15.6 |
| 70% | 26 | 26 × 0.7 = 18.2 |
| 80% | 26 | 26 × 0.8 = 20.8 |
| 90% | 26 | 26 × 0.9 = 23.4 |
| 100% | 26 | 26 × 1.0 = 26.0 |
[문제: 부저를 이용한 동요 재생 실습]
- 다음 작은별 악보를 보고 부저 프로그램을 완성하여라.

import RPi.GPIO as GPIO
import time
# GPIO 설정
GPIO.setmode(GPIO.BCM)
BUZZER_PIN = 27
GPIO.setup(BUZZER_PIN, GPIO.OUT)
# PWM 초기화
pwm = GPIO.PWM(BUZZER_PIN, 100)
pwm.start(0)
one_beat = 0.4 # 1박 = 0.4초 -> 60 / 0.4 = 150 BPM
# 음표 주파수 (Hz)
notes = {
'C4': 261.63,
'D4': 293.66,
'E4': 329.63,
'F4': 349.23,
'G4': 392.00,
'A4': 440.00,
'B4': 493.88,
'C5': 523.25,
}
# 반짝반짝 작은별 멜로디 (one_beat 기준으로 구성)
melody = [
('C4', 1), ('C4', 1), ('G4', 1), ('G4', 1),
('A4', 1), ('A4', 1), ('G4', 2),
('F4', 1), ('F4', 1), ('E4', 1), ('E4', 1),
('D4', 1), ('D4', 1), ('C4', 2),
('G4', 1), ('G4', 1), ('F4', 1), ('F4', 1),
('E4', 1), ('E4', 1), ('D4', 2),
('G4', 1), ('G4', 1), ('F4', 1), ('F4', 1),
('E4', 1), ('E4', 1), ('D4', 2),
('C4', 1), ('C4', 1), ('G4', 1), ('G4', 1),
('A4', 1), ('A4', 1), ('G4', 2),
('F4', 1), ('F4', 1), ('E4', 1), ('E4', 1),
('D4', 1), ('D4', 1), ('C4', 2),
]
# 음 재생 함수
def play(note, beats):
pwm.ChangeFrequency(notes[note])
pwm.ChangeDutyCycle(50)
time.sleep(one_beat * beats)
pwm.ChangeDutyCycle(0)
time.sleep(0.05)
# 연주 실행
try:
print(f"{60/one_beat}bpm으로 연주합니다.")
for note, beats in melody:
play(note, beats)
finally:
if pwm is not None:
try:
pwm.stop()
except:
pass
del pwm
GPIO.cleanup()
[문제: 3Color LED와 부저를 이용한 동요 재생 실습]
- 3컬러 RGB LED는 아래와 같이 연결되어 있다.
- 빨강: GPIO 18
- 초록: GPIO 23
- 파랑: GPIO 24
- 작은별 멜로디를 부저로 연주한다.
- 각 음이 재생될 때, 해당 음에 지정된 색상으로 RGB LED가 점등된다.
- 음이 끝나면 LED는 꺼진다.
- 사용된 음표에 대한 색상 매핑은 아래와 같다.
| 음표 | 색상 | RGB 상태(GPIO) |
|---|---|---|
| C4 | 빨강 | (1, 0, 0) |
| D4 | 초록 | (0, 1, 0) |
| E4 | 파랑 | (0, 0, 1) |
| F4 | 노랑 | (1, 1, 0) |
| G4 | 하늘 | (0, 1, 1) |
| A4 | 보라 | (1, 0, 1) |
| B4 | 흰색 | (1, 1, 1) |
| C5 | 빨강 | (1, 0, 0) |
import RPi.GPIO as GPIO
import time
# GPIO 설정
GPIO.setmode(GPIO.BCM)
# 핀 번호
BUZZER_PIN = 17
RED_PIN = 18
GREEN_PIN = 23
BLUE_PIN = 24
# 핀 모드 설정
GPIO.setup(BUZZER_PIN, GPIO.OUT)
GPIO.setup(RED_PIN, GPIO.OUT)
GPIO.setup(GREEN_PIN, GPIO.OUT)
GPIO.setup(BLUE_PIN, GPIO.OUT)
# 부저 PWM 초기화
pwm = GPIO.PWM(BUZZER_PIN, 100)
pwm.start(0)
# 음표 주파수
notes = {
'C4': 261.63,
'D4': 293.66,
'E4': 329.63,
'F4': 349.23,
'G4': 392.00,
'A4': 440.00,
'B4': 493.88,
'C5': 523.25
}
# 색상 매핑 (C5도 빨강으로 수정)
colors = {
'C4': (1, 0, 0), # 빨강
'D4': (0, 1, 0), # 초록
'E4': (0, 0, 1), # 파랑
'F4': (1, 1, 0), # 노랑
'G4': (0, 1, 1), # 하늘
'A4': (1, 0, 1), # 보라
'B4': (1, 1, 1), # 흰색
'C5': (1, 0, 0) # 빨강으로 수정
}
# 작은별 멜로디
# melody = [('C4', 0.5), ('C4', 0.5), ('G4', 0.5), ('G4', 0.5)]
melody = [
('C4', 0.5), ('C4', 0.5), ('G4', 0.5), ('G4', 0.5),
('A4', 0.5), ('A4', 0.5), ('G4', 1.0),
('F4', 0.5), ('F4', 0.5), ('E4', 0.5), ('E4', 0.5),
('D4', 0.5), ('D4', 0.5), ('C4', 1.0),
('G4', 0.5), ('G4', 0.5), ('F4', 0.5), ('F4', 0.5),
('E4', 0.5), ('E4', 0.5), ('D4', 1.0),
('G4', 0.5), ('G4', 0.5), ('F4', 0.5), ('F4', 0.5),
('E4', 0.5), ('E4', 0.5), ('D4', 1.0),
('C4', 0.5), ('C4', 0.5), ('G4', 0.5), ('G4', 0.5),
('A4', 0.5), ('A4', 0.5), ('G4', 1.0),
('F4', 0.5), ('F4', 0.5), ('E4', 0.5), ('E4', 0.5),
('D4', 0.5), ('D4', 0.5), ('C4', 1.0)
]
# LED 색상 출력 함수
def set_color(r, g, b):
GPIO.output(RED_PIN, r)
GPIO.output(GREEN_PIN, g)
GPIO.output(BLUE_PIN, b)
# 음 재생 함수
# 음 재생 함수
def play_note(note, duration):
freq = notes.get(note, None) # 기본값을 None으로 설정하고 유효한 주파수인지 확인
rgb = colors.get(note, (0, 0, 0))
if freq: # freq가 None이 아니면 실행
pwm.ChangeFrequency(freq)
pwm.ChangeDutyCycle(50)
set_color(*rgb)
time.sleep(duration)
pwm.ChangeDutyCycle(0)
set_color(0, 0, 0)
time.sleep(0.05)
# 실행
try:
for note, dur in melody:
play_note(note, dur)
except Exception as e:
print(f"실행 중 예외 발생: {e}")
finally:
if pwm is not None:
try:
pwm.stop()
except:
pass
del pwm # __del__ 호출 시 오류 방지
GPIO.cleanup()
댓글목록0