본문 바로가기

Study/라즈베리파이 공부

라즈베리파이로 active buzzer 제어하는 방법

반응형

지난 시간에는 라즈베리파이를 이용해서 LED를 제어하는 방법에 대해서 기록했었습니다. 

오늘은 라즈베리파이를 이용해서 부저음을 낼 수 있는 방법에 대해서 기록하고자 합니다. 

 

[부저]

 

GPIO를 이용하여 부저음을 내기에 앞서 부저에 대해서 간단하게 설명드리겠습니다. 

부저(buzzer)는 소리를 낼 수 있는 부품으로 2가지 종류가 있습니다. 

동작 방식에 따라서 능동 부저(active buzzer)와 수동 부저(passive buzzer)로 나뉩니다. 

 

 

[능동 부저]

 

능동부저(active buzzer)

 

능동 부저란 내부에 부저 신호를 발생시킬 수 있는 기능이 있어서, 전원만 연결해주면 고정된 주파수의 소리가 발생하게 됩니다. 

동작 전압만 인가하면 소리가 나기 때문에 간단하게 소리를 낼 수 있지만, 고정된 주파수로만 소리가 나기 때문에 주파수를 바꿀 수 없는 단점이 있습니다. 

 

 

[수동 부저]

 

수동 부저(passive buzzer)

 

수동 부저는 이름에서도 알 수 있듯이, 자체적으로 신호를 발생시킬 수 없기 때문에 외부에서 신호를 발생시켜야만 소리가 납니다. 

PWM 제어를 통해서 신호를 발생시켜주면 해당하는 주파수로 소리가 나게 됩니다. 

 

 

[능동 부저와 수동 부저를 구분하는 방법]

 

외관으로 봤을 때 능동 부저인지 수동 부저인지를 구분하기는 쉽지 않습니다. 

3.3V 혹은 5V를 공급해 봤을 때 '삐~'라는 소리가 나면 능동 부저이고, '뚝' 하는 소리가 한 번 발생하고 그 이후로 아무 소리도 나지 않는다면 수동 부저일 가능성이 높습니다. 

 

 

라즈베리파이 IO Expansion에서 3.3V를 따와서 연결해보면 능동 부저의 경우 시끄러운 부저음이 들립니다. 

 

[극성 구분하는 방법]

(+)라고 표시된 쪽이 (+)극 입니다.

 

극성 구분은 손쉽게 할 수 있는데, (+)라고 표시된 쪽이 (+) 극입니다. 아무것도 쓰여있지 않은 쪽이 당연히 (-) 극이겠지요.

 

다리가 긴 쪽이 (+)극입니다.

 

다리의 길이에 차이가 난다면, 다리가 상대적으로 긴 쪽이 (+) 극이고, 다리가 짧은 쪽이 (-) 극입니다. 

 

 

[REMOVE SEAL AFTER WASHING의 의미]

REMOVE SEAL AFTER WASHING

 

REMOVE SEAL AFTER WASHING이라는 레이블이 붙어있는데, 이는 세척을 한 후에 레이블을 제거하라는 의미가 아닙니다. 

납땜 이후에 washing을 할 때 이물질이 부저 안으로 들어가는 것을 방지하기 위한 것입니다. 

납땜을 하지 않는다면 그냥 바로 레이블을 제거하면 됩니다. 

 

 

[회로 구성]

이제 회로 구성을 할 차례입니다. 

사실 회로 구성이라고 하기에도 부끄러울 정도로 단출합니다. 

 

Signal PINMAP Note
BUZ(+) 3 (GPIO2)  
BUZ(-) 25 (GND)  

 

부저의 (+) 극을 GPIO 2번 채널에 연결했고, 부저의 (-) 극을 GND에 연결하였습니다. 

 

 

[스크립트]

import RPi.GPIO as GPIO
import time

GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(2, GPIO.OUT)

while True:
    GPIO.output(2, True)
    time.sleep(1)
    GPIO.output(2, False)
    time.sleep(1)

위와 같이 작성하고 buzzer.py 파일로 저장합니다. 

복사해서 붙여 넣기보다 python 문법이 있을 때까지 손으로 한 글자씩 치는 것을 추천드립니다. 

 

[실행 명령]

$ sudo python buzzer.py

 

 

[실행 결과]

실행 결과는 1초마다 부저가 켜졌다 꺼졌다를 무한 반복합니다. 

Ctrl + C를 누르면 실행이 종료됩니다. 

스크립트가 종료되어도 마지막 GPO 값이 그대로 유지되기 때문에, 부저가 켜져 있을 때 Ctrl + C를 누르시면 시끄러운 부저음을 계속 들어야 합니다. 

이를 해결하기 위해서 스크립트가 종료되는 시점에 GPIO 설정값을 clear 시키는 방법이 있는데 아래쪽에서 추가로 설명드리겠습니다. 

 

 

[부저음을 좀 더 빠르게 울리기]

import RPi.GPIO as GPIO
import time

GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(2, GPIO.OUT)

while True:
    GPIO.output(2, True)
    time.sleep(0.05)
    GPIO.output(2, False)
    time.sleep(0.05)

1초에 한 번씩 부저음을 울리게 되면 뭔가 좀 loose 한 느낌이 듭니다. 

좀 더 리드미컬하게 부저음을 울릴 수 있도록 delay를 50ms 단위로 줄여보도록 하겠습니다.

기존 구문 변경 구문
time.sleep(1) time.sleep(0.05)

위와 같이 변경하고 실행해보면 훨씬 더 듣기 좋은 부저음이 울리게 됩니다. 

 

 

[종료 후에도 부저음이 계속 울리는 문제 수정]

이번에는 종료 후에도 부저음이 계속 울리는 문제를 수정해보겠습니다. 스크립트는 종료되더라도 마지막에 설정한 레지스터 값이 여전히 유효하기 때문에 스크립트 종료 시에 GPIO 설정을 초기화해주도록 하겠습니다. 

import RPi.GPIO as GPIO
import time

GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(2, GPIO.OUT)

try:
    while True:
        GPIO.output(2, True)
        time.sleep(0.05)
        GPIO.output(2, False)
        time.sleep(0.05)

finally:
    GPIO.cleanup()

 

위와 같이 기존의 while True: 이하 구문을 try 구문 안에 넣고, finally 구문으로 종료 시점에 GPIO.cleanup() 해주면 스크립트 종료 시에 GPIO 설정이 초기화되므로 언제든지 Ctrl + C로 종료하더라도 스크립트 종료 후에는 부저가 꺼지게 됩니다. 

 

 

[끝 맺음말]

이것으로 라즈베리파이의 GPIO를 이용하여 부저음을 제어하는 방법에 대해서 설명을 마칩니다. 

 

감사합니다. 

반응형