소리와 불빛이 나는 계단 프로토타입

  1. 프로토타입의 사진/영상 및 코드

– LED는 14번 핀이 HIGH 일 때 3.3V를 공급받는다.
– Sharp IR 센서가 출력하는 데이터(전압)는 ADC를 통해 디지털화 되어 파이에 전달된다. 이 과정에서 spidev 라이브러리에 있는 spi 객체가 사용된다.

import time

# 적외선 센서를 사용하기 위한 사전 작업
import spidev 
spi = spidev.SpiDev()
spi.open(0, 0)
spi.max_speed_hz = 100

# 음악을 재생하기 위한 부분
import pygame 
pygame.init()
pygame.mixer.init()

sound_channel = pygame.mixer.Channel(0)
sound = "piano-C4.wav" # 음에 따라 다른 파일 필요(C4, D4)
sound = pygame.mixer.Sound(sound); 

# LED 재생을 위한 부분
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM) # GPIO 핀 세팅 방식 설정
GPIO.setwarnings(False)
GPIO.setup(14, GPIO.OUT, initial = GPIO.LOW) # 14번 핀이 HIGH로 설정될 때, LED가 켜진다

def readChannel(channel) :
  val = spi.xfer2([1, (8 + channel) << 4, 0])
  data = ((val[1] & 3) << 8) + val[2]
  return data

# 거리 측정 함수
def measure_distance() :
  v = (readChannel(0) / 1023.0) * 3.3
  dist = 16.2537*v**4 - 129.893*v**3 + 382.268*v**2 - 512.611*v + 301.439
  return dist

# 측정하고자 하는 위치에 발이 존재하는지를 알려줌
def should_play() :
    distance = measure_distance()
    if distance < 60 :
        return True
    return False
    
# sound channel을 통해 소리 재생
def sound_on() :
    sound_channel.play(sound)

# 소리 재생 중지
def sound_off() :
    sound_channel.stop()
    
try:
    music_on = False
    was_on = False
    
    while True:
        time.sleep(0.1) # 0.1초에 한 번 씩 재생
        music_on = should_play() # 음악이 켜져야 하는가?

        if music_on == was_on : # 이전 상태와 지금 상태가 같다면, 변화가 필요없다.
            pass
        elif music_on : # 음악이 재생되어야 한다면,
            sound_on() # 소리 재생
            GPIO.output(14, GPIO.HIGH) # LED on
        else : # 음악이 꺼져야 한다면,
            sound_off() # 소리 재생 중지
            GPIO.output(14, GPIO.LOW) # LED off
            
        was_on = music_on # 현 상태 정보 저장
                    
except KeyboardInterrupt :
    pass

2. 적외선 센서의 원리

  • 적외선 센서가 적외선을 방출하면 적외선이 물체에 반사되어 다시 센서로 돌아온다. 이때 적외선이 반사된 위치에 따라 센서에 입력되는 적외선의 위치가 다르고, 이에 따라 센서가 발신하는 데이터, 즉 전압의 크기가 달라진다. 거리에 따른 전압의 그래프는 위와 같이 나타난다.
  • 이 때, 0~15cm에서 출력하는 값과, 15cm 이후로 출력하는 전압이 일부 겹친다. (실제로 둘 중 더 큰 거리를 측정값으로 보여준다.) 따라서 0~15cm에서 유의미한 값을 출력한다고 보기 어렵다.

3. 시행착오들

  • 센서 측정하는 과정에서 소리가 씹히는 현상이 발생함.

현재 코드에 따르면, 센서의 측정 위치에 사물이 있느냐 없느냐에 따라 소리가 재생되거나 종료한다. SPI 버스의 데이터 전송 주기를 1000,000 hz로 설정하고, main 함수의 while문을 반복적으로 재생하였을 경우, 한 번에 연속적으로 소리가 재생되는 것이 아닌, 불연속적으로 여러번 소리가 났다. 정확한 발생 원인은 모르지만, 같은 값을 너무 자주 SPI bus를 통해 전송함으로써 오류가 생기지 않았나 추측한다.

SPI 버스의 데이터 전송 주기를 낮추고, while문 재생에 간격을 둠으로써 음이 한번에 연속적으로 재생될 수 있게 하였다.

  • 휴대폰으로 오디오를 출력하려는 노력

오디오를 이어폰으로 출력하면 영상을 촬영할 수 없고, HDMI로 출력하면 모니터 간의 간격이 너무 넓어서 라즈베리 파이 두 개를 나란히 두기 어려웠다. 그래서 휴대폰 또는 모니터와 bluetooth pairing을 하여 휴대폰 또는 모니터로 오디오를 출력하고자 하였다.

라즈베리파이와 휴대폰을 bluetooth pairing하는 것까지 성공했으나, 오디오 출력을 휴대폰으로 바꾸는 방법을 찾지 못했다. 블루투스 스피커를 연결할 경우, 라즈베리파이의 상태표시줄 중 볼륨 아이콘을 오른쪽 마우스로 클릭하면 블루투스 스피커가 표시된다고 하는데, 휴대폰은 표시되지 않는 것으로 보아 파이의 오디로를 휴대폰에서 출력하는 기능이 존재하지 않는 것 같다.

결국 HDMI 모니터 두 개를 사용하기로 했고, 그래서 전선의 길이를 길게 할 필요가 있었다.

  • 전선의 길이가 짧음

LED strip에 전선을 연결할 때에는 납땜을 했고, 전선의 반대쪽 끝은 절연테이프를 활용해 이었다. 적외선 센서에 연결된 전선을 길게 하기 위해서 양끝의 모양이 다른 점프선들을 여러 개 연결하였다.

  • 적외선 센서 측정에 오류가 생김

적외선 센서를 바닥에 그대로 부착했을 때 거리 측정값이 엉망으로 출력되었다. 원인은 적외선 센서의 각도가 약간 아래를 향하고 있던 것이었다. 각도를 바닥과 나란하게 조정하자 올바른 출력값을 얻을 수 있었다.


Written by. 하은&혜정

답글 남기기

아래 항목을 채우거나 오른쪽 아이콘 중 하나를 클릭하여 로그 인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Google photo

Google의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Twitter 사진

Twitter의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

%s에 연결하는 중