【라즈베리Pi#20】 피에조 부저 사용하기! with (파이썬 코드)
【라즈베리Pi#20】 피에조 부저 사용하기! with (파이썬 코드)
RaspberryPi Buzzer control with Python !
안녕하세요 라즈이노 IoT 입니다.
이번 시간에는 라즈베리 Pi에서 부저를 사용해 보는 실습을 진행합니다.
GPIO 출력을 제어하여 부저를 울리는 방법을 설명드리며,
주파수를 이용하여 음의 높낮이를 조절할 수 있기에, 실습5 에서는 간단한 동요를 출력해 보겠습니다.
1. 음계(Scale)와 옥타브(Octave)
음계란, 음악에 쓰이는 음을 높이의 차례대로 배열한 음의 층계를 말합니다.
음 높이는 Pitch.
"도, 레, 미, 파, 솔, 라, 시, 도" 의 8가지 음계를 옥타브라고 합니다. 즉, 옥타브는 어떤 음에서 완전 8도의 거리에 있는 음까지를 말하며, 물리학적으로는 주파수(진동수)가 두 배 차이나는 두 음 사이의 음정을 말하는데, 예를 들어, 음높이가 400Hz인 음과 800Hz인 음 사이의 음정은 옥타브라고 말하며, 인간의 귀는 이 두 음을 높이는 다르지만 서로 같은 음으로 인식합니다. (예, 낮은 '도'와 높은'도', 낮은 '솔'과 높은 '솔')
2. 소리와 주파수 (음계 별 표준 주파수)
스피커나 부저를 통해서 듣게 되는 음도, 진동판의 떨림(주파수)에 의해 들을 수 있게 되는데요, 1초(Second)에 1회의 떨림을 1Hz라 부르며, 1초에 100회면 100Hz라 말합니다. 떨림(주파수)이 낮을수록 낮은음을 내게 되며, 높을수록 늪은 음을 내게 됩니다.
음악에 사용되는 악기들의 종류는 매우 다양하고 많지만, 합주를 했을 때 음의 일치가 되는 이유는, 각각의 음 높이가 특정 주파수로 정리되었기에 가능합니다.
아래가 각 음계 별 표준 주파수입니다.
그럼, 이 번 실습에서 각 음계 별 주파수를 참고하여, 적당히 반올림한 수를 코드에 적용하면, 해당음의 소리를 출력할 수 있게 됩니다.
3. 부저의 종류와 특징 :
- Passive type : 전원만 가해서는 소리가 나지 않고, PWM 형태의 일정한 주파수일 때 소리가 나는 타입.
- Active type : 전원만 연결해 주면 소리가 나는 타입.
위 이미지에서 녹색의 기판이 보이는 부저가 (좌) 패시브 타입이며, PWM처리 회로를 내장하여 검은색으로 마감 처리한 부저가 (우) 액티브 타입 부저입니다.
라즈베리 Pi의 포트에서 High 신호를 내보내어 직접 부저를 울릴 수도 있지만, 출력이 약할 수 있고, 포트를 통한 직접적인 출력을 제한하기 위해, 아래와 같은 Low level trigger 방식을 사용할 수 있습니다.
이 방식은, GPIO 포트를 통한 직접적인 출력을 사용하지 않고, VCC 전원을 사용하게 함으로, 포트를 보호하게 되며, 부저에 충분한 전류를 공급할 수 있게 합니다.
회로 연결을 보면, 입출력(I/O) 부분이 Low 신호가 되면, TR이 작동(스위치 On) 되어, VCC(+), Buzzer로 이어지는 전류가 E(에미터) - C(컬렉터)로 빠져나가면서, Buzzer를 울리게 됩니다. 그래서 이런 작동 형태를 '로우-레벨-트리거'(Low level trigger)라 말합니다.
TR은 위 회로 기준으로, 가지고 있는 PNP타입의 TR 어떤 것이든 사용 가능합니다.
TR의 경우는 NPN 타입과 PNP타입으로 나뉘는데요, PNP 타입도 제품 품번마다 E(에미터), B(베이스), C(컬렉터) 핀의 위치가 다르기 때문에 자신이 사용하는 TR의 스펙을 확인(검색 가능)해서 연결하면 됩니다.
즉, 같은 PNP 타입의 TR이라 하더라도, 위 이미지처럼, A1015품번의 경우 핀이 E C B의 순으로 되어 있지만,
또 다른 PNP타입의 A9012 TR의 경우 핀 순서는 E B C로 되어 있습니다. (핀 배열 구분 주의!)
또한 아래처럼, 액티브 타입 부저를 '로우-레벨-트리거' 방식으로 모듈화 한 제품도 있으니 참고하세요.
그림에 보면 TR과 저항이 내장되어 있습니다.(Low level trigger 방식)
4. 라즈베리파이+부저 연결도 (실습을 위한 연결 도면)
기본적으로 아래처럼 라즈베리 Pi 포트 출력으로 직접 부저를 작동시키는 연결을 하면 됩니다.
또는 아래와 같이 TR과 저항을 이용한 Low level trigger 방식의 연결을 하여도 됩니다.
이때, 사용한 TR은 PNP 타입의 A1015 품번을 사용했습니다. PNP타입의 다른 품번을 사용해도 되며, 이때는 ECB의 핀 배열이 다를 수도 있으니, 해당 TR의 스펙을 확인해 보세요.
또한 아래처럼, TR과 저항이 내장되어 모듈화 된 부저 모듈을 사용하여 간편하게 연결할 수도 있습니다.
【 부저를 이용한 실습 】
(실습 1) 부저 1회 울리기
: 아래 코드를 작성하여 동작시켜 보세요.
부저가 1.5 동안 1회 울리고 종료됩니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
import RPi.GPIO as GPIO
import time
buzzer = 18
GPIO.setmode(GPIO.BCM)
GPIO.setup(buzzer, GPIO.OUT)
GPIO.setwarnings(False)
pwm = GPIO.PWM(buzzer, 262) # '262'는 음의 높이에 해당하는 특정 주파수
pwm.start(50.0)
time.sleep(1.5) # 1.5초간 음이 울리도록 시간지연
pwm.stop()
GPIO.cleanup()
|
cs |
(실습 2) 부저로 '도, 레, 미' 음 3회 반복 울리기
: 아래 코드를 작성하여 동작시켜 보세요.
부저가 1.0초 간격으로 도, 레, 미 음을 3번 반복한 후 종료됩니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
import RPi.GPIO as GPIO
import time
buzzer = 18
GPIO.setmode(GPIO.BCM)
GPIO.setup(buzzer, GPIO.OUT)
GPIO.setwarnings(False)
pwm = GPIO.PWM(buzzer, 1.0) # 초기 주파수 설정을 1Hz로 함.
pwm.start(50.0)
for cnt in range(0,3):
pwm.ChangeFrequency(262) # 262는 4옥타브의 '도'에 해당되는 주파수
time.sleep(1.0)
pwm.ChangeFrequency(294) # 294는 4옥타브의 '레'에 해당되는 주파수
time.sleep(1.0)
pwm.ChangeFrequency(330) # 330은 4옥타브의 '미'에 해당되는 주파수
time.sleep(1.0)
pwm.ChangeDutyCycle(0.0)
pwm.stop()
GPIO.cleanup()
|
cs |
(실습 3) 부저로 '도레미파솔라시도' 음계 출력하기
: 아래 코드를 작성하여 동작시켜 보세요.
부저가 4옥타브 영역의 주파수인 '도, 레, 미, 파, 솔, 라, 시, 도' 음을 출력한 후 종료됩니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
import RPi.GPIO as GPIO
import time
buzzer = 18
GPIO.setmode(GPIO.BCM)
GPIO.setup(buzzer, GPIO.OUT)
pwm = GPIO.PWM(buzzer, 1.0) # 초기 주파수를 1Hz로 설정
pwm.start(50.0) # 듀티비를 50%로 설정
scale = [262, 294, 330, 349, 392, 440, 494, 523]
for i in range(0,8):
pwm.ChangeFrequency(scale[i])
time.sleep(1.0)
pwm.stop()
GPIO.cleanup()
|
cs |
(실습 4) 부저로 '도-레-미-파-솔-라-시- 도 -시-라-솔-파-미-레-도' 음계 출력하기
: 아래 코드를 작성하여 동작시켜 보세요.
부저가 '도, 레, 미, 파, 솔, 라, 시, 도' 음을 올리고 다시 내리는 형태로 출력합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
import RPi.GPIO as GPIO
import time
buzzer = 18
GPIO.setmode(GPIO.BCM)
GPIO.setup(buzzer, GPIO.OUT)
pwm = GPIO.PWM(buzzer, 1.0) # 초기 주파수를 1Hz로 설정
pwm.start(50.0) # 듀티비를 50%로 설정
# 4옥타브 주파수 : 도(262)/레(294)/미(330)/파(349)/솔(392)/라(440)/시(494)/도(523)
scale = [262, 294, 330, 349, 392, 440, 494, 523]
for i in range(0,8):
pwm.ChangeFrequency(scale[i])
time.sleep(1.0)
for i in range(7,-1,-1):
pwm.ChangeFrequency(scale[i])
time.sleep(1.0)
pwm.stop()
GPIO.cleanup()
|
cs |
(실습 5) 부저로 '반짝반짝 작은 별' 동요를 출력해 봅니다.
: 아래 코드를 작성하여 멜로디를 출력해 보세요.
부저가 '반짝 반짝 작은별' 계이름을 울리고 종료하도록 합니다.
아래, '작은 별' 악보를 참고하세요. 실습을 이해한 후, 다른 곡도 코딩하여 연습해 보세요.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
import RPi.GPIO as GPIO
import time
buzzer = 18
GPIO.setmode(GPIO.BCM)
GPIO.setup(buzzer, GPIO.OUT)
pwm = GPIO.PWM(buzzer, 1.0) # 초기 주파수를 1Hz로 설정
pwm.start(90.0) # 듀티비를 90%로 높여 설정함(음 구분이 더 잘되고 조금 더 부드럽게 들림)
# == 동요 : 반짝 반짝 작은별 계이름 ==
#도도솔솔라라솔파파미미레레도 솔솔파파미미레 솔솔파파미미레 도도솔솔라라솔파파미미레레도
# 4옥타브:도(1)/ 레(2)/ 미(3)/ 파(4)/ 솔(5)/ 라(6) / 시(7)
scale = [ 262 , 294 , 330 , 349 , 392 , 440 , 494 ]
twinkle = [ 1, 1, 5, 5, 6, 6, 5, 4, 4, 3, 3, 2, 2, 1, \
5, 5, 4, 4, 3, 3, 2, 5, 5, 4, 4, 3, 3, 2, \
1, 1, 5, 5, 6, 6, 5, 4, 4, 3, 3, 2, 2, 1 ]
try :
for i in range(0,42):
pwm.ChangeFrequency(scale[twinkle[i]])
if i==6 or i==13 or i==20 or i==27 or i==34 or i==41:
time.sleep(1.0) # 2분음표 부분을 모두 1초로 출력
else :
time.sleep(0.5) # 기타 4분음표는 모두 0.5초로 출력함
pwm.stop()
finally :
GPIO.cleanup()
|
cs |
자, 어떠신가요? 비록 단순 부저여서 음질이 좋지는 못하지만, 음 고유의 주파수를 이용하여 동요나 가요의 멜로디를 얼마든지 연주할 수 있습니다.
그럼, 아래 전체 과정을 담은 동영상을 함께 보면서 실습해 보세요.