본문으로 바로가기
반응형

부저센서 사용

부서센서를 사용하기위해 구성한 회로는 다음과같다.(회로까진 아니고 핀과 그라운드에만 연결하면된다)

부저센서를 작동하기위한 회로(?)구성

 

 

1. 도레미파솔라시도  를 부저센서로 출력해보자.

 # -*-coding: utf-8-*-
# 파일이름 : scale.py

import RPi.GPIO as GPIO
import time

pinPiezo = 21
Melody = [261, 294, 329, 349, 392, 440, 493, 523]
#Melody = [131, 147, 165, 174, 196, 220, 247, 262]

GPIO.setmode(GPIO.BCM)
GPIO.setup(pinPiezo, GPIO.OUT)

Buzz = GPIO.PWM(pinPiezo, 440)

try:
   while True:
      Buzz.start(50)
      for i in range(0, len(Melody)):
         Buzz.ChangeFrequency(Melody[i])
         time.sleep(0.3)
      Buzz.stop()
      time.sleep(1)

except KeyboardInterrupt:
   GPIO.cleanup()

해당 코드를 실행하면 주파수에따른 출력이 부저센서를 통해 소리로 들려준다. (대략 도레미파솔라시도 가 출력됨)

 

 

 

 

 

2. 키보드에서 1~8 중에 하나를 누르고 엔터 눌렀을때 해당되는 계이름이 부저에서 출력되는 코드

# -*-coding: utf-8-*-
# 파일이름 : scale_Key.py

import RPi.GPIO as GPIO
import time

# 숫자를 입력하는게 귀찮으니까 계이름들을 변수처리
O = 1
C = 261 # 도
D = 293 # 레
E = 329 # 미
F = 349 # 파
Ff = 370 # 파샵
G = 391 # 솔
A = 440 # 라
B = 493 # 시
Cc = 523 # 2옥도

pinPiezo = 21

GPIO.setmode(GPIO.BCM)
GPIO.setup(pinPiezo, GPIO.OUT)

Buzz = GPIO.PWM(pinPiezo, 440)

def buzz_Freq(Piano):
   print("주파수 : %d 입력" %Piano)
   Buzz.ChangeFrequency(Piano)
   time.sleep(0.3)
   Buzz.stop()
   #time.sleep(1)

try:
   while True:
      key = int(input())
      Buzz.start(90)
      if(key == 1):
         buzz_Freq(C)
      elif(key == 2):
         buzz_Freq(D)
      elif(key == 3):
         buzz_Freq(E)
      elif(key == 4):
         buzz_Freq(F)
      elif(key == 5):
         buzz_Freq(G)
      elif(key == 6):
         buzz_Freq(A)
      elif(key == 7):
         buzz_Freq(B)
      elif(key == 8):
         buzz_Freq(Cc)

except KeyboardInterrupt:
   GPIO.cleanup()

1을 눌렀을때 엔터를 누르면 input()을 통해 저장된 key에 따라 도 가 부저센서에서 출력된다.

같은 원리로 2~8로 입력하고 엔터를 누르면 도레미파솔라시도 가 부저센서에서 출력된다.

 

 

 

 

3. 1~8까지 눌렀을때 즉시(엔터없이) 피아노 계이름을 출력하는 코드작성

# -*-coding: utf-8-*-
# 파일이름 : scale_Key2.py

import sys, termios, tty, os, time  # getch를 위해 모드를 바꿀때 쓰는 import함수
import RPi.GPIO as GPIO
import time

# 계이름을 전부 변수처리
O = 1
C = 261  # 도
D = 293  # 레
E = 329  # 미
F = 349  # 파
Ff = 370 # 파샵
G = 391  # 솔
A = 440  # 라
B = 493  # 시
Cc = 523 # 2옥도

pinPiezo = 21

GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)       # 런타임워닝 무시해줌(scanf할때처럼)
                              # setmode와 setup사이에 써줘야함.
                              
GPIO.setup(pinPiezo, GPIO.OUT)

Buzz = GPIO.PWM(pinPiezo, 440)


def buzz_Freq(Piano):
   Buzz.ChangeFrequency(Piano)
   time.sleep(0.2)
   Buzz.stop()


# 모드를 바꿔주는 함수(다른 사이트에서 퍼온거)
def getch():
   fd = sys.stdin.fileno()
   old_settings = termios.tcgetattr(fd)
   try:
      tty.setraw(sys.stdin.fileno())
      ch = sys.stdin.read(1)
finally:
      termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
   return ch

try:
   while True:
      char = getch()        # 문자열로 받음
      Buzz.start(90)
      if(char == '1'):
         print("도")
         buzz_Freq(C)
      elif(char == '2'):
         print("레")
         buzz_Freq(D)
      elif(char == '3'):
         print("미")
         buzz_Freq(E)
      elif(char == '4'):
         print("파")
         buzz_Freq(F)
      elif(char == '5'):
         print("솔")
         buzz_Freq(G)
      elif(char == '6'):
         print("라")
         buzz_Freq(A)
      elif(char == '7'):
         print("시")
         buzz_Freq(B)
      elif(char == '8'):
         print("2옥도")
         buzz_Freq(Cc)
      else:
         exit(0)

except KeyboardInterrupt:
   GPIO.cleanup()

원래 피아노처럼 도를 누르면 바로 도 음이 나오는것처럼
키보드의 1을 누르면 도가 출력되는 것을 하고싶었는데,

이것을 위해서는 키보드를 입력받았을때 바로 감지하는 것이 필요하다.
근데 리눅스에서는 이것이 지원이 안되서(?) 모드를 바꿔서 입력받는 방법을 선택했다.

 

getch()를 통해 정수도 문자로 받는것을 기억하고 코드를 작성했다.

 

또, GPIO.setwarnings(False)  를 알아보도록 할껀데, 만약 이 코드를 작성해주지 않으면 런타임워닝이 출력된다.

이 오류는 C에서 scanf를 사용할때 보안이슈로인해서 초록줄을 그어주면서 오류가 있을것임을 암시하는(?) 코드와 비슷한 원리인데,

 

C에서 #define _CRT_SECURE_NO_WARNING이나 #pragma warning(disable : 4996) 를 사용해서 보안이슈를 잠시 무시하겠다는 코드처럼 GPIO.setwarnings(False)를 작성해주면된다.

이때, setmode와 setup 사이에 작성해야하는 것을 주의하여 작성하면 된다.

 

반응형