1.초음파 센서 + RPi.GPIO
- 초음파 센서로 거리 측정하여 LED 켜고 끄기
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
trig=13
echo=26
LED=21
GPIO.setup(trig, GPIO.OUT)
GPIO.setup(echo, GPIO.IN)
GPIO.setup(LED, GPIO.OUT, initial=GPIO.LOW)
print("start")
try:
while True:
GPIO.output(trig, GPIO.LOW)
time.sleep(1)
GPIO.output(trig, GPIO.HIGH)
time.sleep(0.001)
GPIO.output(trig, GPIO.LOW)
start=0
end=0
while GPIO.input(echo)==GPIO.LOW:
start=time.time()
while GPIO.input(echo)==GPIO.HIGH:
end=time.time()
duration=end-start
distance=(duration*340*100)/2
print("distance: %dcm" %distance)
if distance <= 10:
GPIO.output(LED, GPIO.HIGH)
else:
GPIO.output(LED, GPIO.LOW)
except KeyboardInterrupt:
GPIO.cleanup()
print("finish")
▷ 초음파 센서가 감지한 거리가 10cm 이하이면 LED를 켜고, 10cm보다 멀어지면 LED를 끈다.
https://m.blog.naver.com/PostView.nhn?blogId=chandong83&logNo=221155355360&proxyReferer=https%3A%2F%2Fwww.google.co.kr%2F
위 블로그를 참고하여 회로도를 구성하였다.
2.python의 pygame.midi 라이브러리
- 중간 도부터 높은 도까지의 음 연주하기(피아노, 바이올린)
import pygame, pygame.midi
import time
instrument = 0 # 0 = GRAND_PIANO
pygame.init()
pygame.midi.init()
def sound(sound, loud):
midi_out.note_on(sound, loud)
time.sleep(0.5)
midi_out.note_off(sound, loud)
time.sleep(0.1)
port = pygame.midi.get_default_output_id()
print("using output_id : %s" %port)
midi_out = pygame.midi.Output(port, 0)
midi_out.set_instrument(instrument)
sound(72, 127) # 72 = middle C # loud : 0 ~ 127
sound(74, 127)
sound(76, 127)
sound(77, 127) # 미-파 : 반음 차이
instrument = 42 # 42 = Violin
midi_out.set_instrument(instrument)
sound(79, 127)
sound(81, 127)
sound(83, 127)
sound(84, 127) # 시-도 : 반음 차이
del midi_out
pygame.midi.quit()
▷ 중간 도부터 파까지는 피아노로, 솔부터 높은 도까지는 바이올린으로 연주한다.
위 코드는 노트북에서는 실행되었으나, 라즈베리파이에서는 실행되지 않았다.
라즈베리파이에서 다른 음악이나 영상의 소리는 출력되었기 때문에,
소리 출력의 문제가 아닌 python의 pygame.midi 라이브러리의 문제인 것으로 예상했다.
3.python의 pygame.mixer 라이브러리
- 초음파 센서로 거리 측정하여 음악 재생하고 정지하기
import RPi.GPIO as GPIO
import pygame
import time
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
pygame.init()
pygame.mixer.init()
trig = 4
echo = 18
GPIO.setup(trig, GPIO.OUT)
GPIO.setup(echo, GPIO.IN)
music = "Ed Sheeran - Thinking Out Loud.mp3"
pygame.mixer.music.load(music)
DISTANCE = 5
before = [0]
now = [0]
def measure_distance(num):
GPIO.output(trig, GPIO.LOW)
time.sleep(1)
GPIO.output(trig, GPIO.HIGH)
time.sleep(0.001)
GPIO.output(trig, GPIO.LOW)
start = 0
end = 0
while GPIO.input(echo) == GPIO.LOW:
start = time.time()
while GPIO.input(echo) == GPIO.HIGH:
end = time.time()
duration = end - start
distance = (duration*340*100) / 2 # 단위 : cm
print("distance: %dcm" %distance)
return distance
def state(num, distance):
if distance <= DISTANCE:
now[num] = 1
else:
now[num] = 0
def change(num):
distance = measure_distance(num)
before[num] = now[num]
state(num, distance)
if before[num] != now[num]:
return 1
else:
return 0
def sense(num):
if change(num) == 0:
print("stay")
return 0 #stay
elif now[num] == 1: # now[num] == state(distance)
print("on")
return 1 #on
else:
print("off")
return -1 #off
def sound_on(num):
pygame.mixer.music.play()
def sound_off(num):
pygame.mixer.music.stop()
#---
try:
while True:
sns = sense(0)
if sns == 0:
pass
elif sns == 1:
print("on")
sound_on(0)
else:
print("off")
sound_off(0)
except KeyboardInterrupt:
GPIO.cleanup()
※ 소스 파일이 저장된 폴더에 “Ed Sheeran – Thinking Out Loud.mp3” 파일을 포함시킨 후 실행했다.
▷ 초음파 센서가 감지한 거리가 5cm 이하가 되면 음악 재생을 시작하고, 5cm보다 멀어지면 음악 재생을 정지한다.
위 코드가 파이에서 실행됨으로써, 앞서 소리가 출력되지 않은 것은 midi 라이브러리의 문제였던 것이 확인되었다.
- 라즈베리파이로 악기 연주하기

# setting
import RPi.GPIO as GPIO
import pygame
import time
SENSOR = 4
DISTANCE = 10 #cm
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
pygame.init()
pygame.mixer.init()
trig = [4, 17, 27, 6]
echo = [18, 23, 24, 12]
for i in trig:
GPIO.setup(i, GPIO.OUT)
for i in echo:
GPIO.setup(i, GPIO.IN)
sound_channel = [0, 0, 0]
for i in range(3):
sound_channel[i] = pygame.mixer.Channel(i + 1)
sound_list = [[], [], []]
sound_list[0] = ["piano-C4.wav", "piano-G4.wav", "piano-C5.wav"]
sound_list[1] = ["trumpet-C4.wav", "trumpet-G4.wav", "trumpet-C5.wav"]
sound_list[2] = ["violin-C4.wav", "violin-G4.wav", "violin-C5.wav"]
for i in range(3):
for j in range(3):
sound_list[i][j] = pygame.mixer.Sound(sound_list[i][j])
before = [0 for i in range(SENSOR)]
now = [0 for i in range(SENSOR)]
global count
count = 0
# ---
def measure_distance(num):
trg = trig[num]
ech = echo[num]
GPIO.output(trg, GPIO.LOW)
time.sleep(0.001)
GPIO.output(trg, GPIO.HIGH)
time.sleep(0.001)
GPIO.output(trg, GPIO.LOW)
start = 0
end = 0
while GPIO.input(ech) == GPIO.LOW:
start = time.time()
while GPIO.input(ech) == GPIO.HIGH:
end = time.time()
duration = end - start
distance = (duration*340*100) / 2 #cm
#print("sensor = %d distance: %dcm" %(num + 1, distance))
return distance
def state(num, distance):
if distance <= DISTANCE:
now[num] = 1
else:
now[num] = 0
def change(num):
distance = measure_distance(num)
before[num] = now[num]
state(num, distance)
if before[num] != now[num]:
return 1
else:
return 0
def sense(num):
if change(num) == 0:
return 'stay'
elif now[num] == 1: # now[num] == state(distance)
return 'on'
else:
return 'off'
def change_instrument():
if sense(SENSOR - 1) == 'on':
global count
count = (count + 1) % 3
for i in range(SENSOR - 1):
sound_channel[i].stop()
print("\n< Musical instrument is changed >\n")
def sound_on(num):
global count
sound_channel[num].play(sound_list[count][num])
def sound_off(num):
global count
sound_channel[num].stop()
# ---
try:
while True:
change_instrument()
for i in range(SENSOR - 1):
sns = sense(i)
if sns == 'stay':
pass
elif sns == 'on':
sound_on(i)
print("sensor %d on" %(i + 1))
else:
sound_off(i)
print("sensor %d off" %(i + 1))
except KeyboardInterrupt:
GPIO.cleanup()
※ 소스 파일이 저장된 폴더에 “piano-C4.wav”, “piano-G4.wav”, “piano-C5.wav”, “trumpet-C4.wav”, “trumpet-G4.wav”, “trumpet-C5.wav”, “violin-C4.wav”, “violin-G4.wav”, “violin-C5.wav” 파일을 포함시킨 후 실행했다.
▷ 3개의 초음파 센서는 각각 중간 도, 솔, 높은 도의 음을 담당한다.
▷ 초음파 센서에서 감지한 거리가 5cm 이하가 되면 악기 음 note가 재생된다.
거리가 5cm보다 멀어지면 음악 재생이 중단된다.
▷ 동시에 여러 음악이 재생될 수 있다.
▷ 왼쪽 끝의 초음파 센서는 악기를 바꾸는 역할을 담당한다. 한 번 감지할 때마다 피아노→트럼펫 → 바이올린 → 피아노 → … 의 순서대로 악기를 바꾼다.