라즈베리 파이 센서 및 액추에이터 제어 마스터하기: 가속도계, 서보 모터, 데이터 스트리밍
대부분의 개발자는 정적 파일이나 단순한 그래픽을 다루지만, 피지컬 컴퓨팅은 현실 세계와의 상호작용으로 문을 열어줍니다. 센서에서 데이터를 읽고 액추에이터를 구동함으로써, 물리 세계를 감지하고 판단하여 행동하는 시스템을 만들 수 있습니다.
목표
라즈베리 파이를 사용해 가속도계 값을 읽고 서보 모터를 제어하며, 피지컬 컴퓨팅의 핵심 개념을 시연합니다.
핵심 개념
- 라즈베리 파이 – HDMI, 이더넷, USB 포트 2개, 그리고 무엇보다 신호를 송수신할 수 있는 GPIO 핀을 갖춘 35달러 리눅스 컴퓨터입니다.
- GPIO 핀 – 범용 입출력 핀으로 바이너리 스위치 역할을 합니다. 핀을 HIGH(3.3V) 또는 LOW(0V)로 설정해 액추에이터를 구동하거나, 상태를 읽어 센서 데이터를 수집할 수 있습니다.
이 글에서는 라즈베리 파이의 하드웨어 역량을 보여주는 4가지 실용적인 파이썬 프로젝트를 다룹니다:
- LED 깜빡이기
- 포텐쇼미터 읽기
- 네트워크로 데이터 스트리밍
- 서보 모터 제어
LED 깜빡이기
LED(발광 다이오드)는 전류가 한 방향으로 흐를 때 빛을 냅니다. 라즈베리 파이와 LED를 보호하기 위해 500Ω~1.5kΩ 사이의 저항을 사용합니다. 저항 값은 R = (V_s - V_d) / I 공식으로 계산할 수 있지만, 위 범위면 대부분의 취미용 키트에 적합합니다.
import time
from itertools import cycle
import RPi.GPIO as io
io.setmode(io.BCM)
io.setup(12, io.OUT)
for state in cycle([1, 0]):
io.output(12, state)
time.sleep(0.5)
이 코드는 핀 12를 출력으로 설정하고 0.5초마다 토글해 LED를 깜빡이게 합니다.
포텐쇼미터 읽기
포텐쇼미터(가변 저항)는 노브 위치를 전압으로 변환합니다. GPIO 핀은 디지털이므로 ADC(아날로그-디지털 변환기)가 필요합니다. MCP3008은 8개의 10비트 채널을 제공하며, 0~3.3V를 0~1023 정수 값으로 매핑합니다.
spidev를 설치해 MCP3008과 SPI로 통신합니다:
pip install spidev
채널 0에서 값을 읽는 스크립트:
import spidev
import time
spi = spidev.SpiDev()
spi.open(0, 0)
def readadc(adcnum):
if not 0 <= adcnum <= 7:
return -1
r = spi.xfer2([1, (8 + adcnum) << 4, 0])
adcout = ((r[1] & 3) << 8) + r[2]
return adcout
while True:
val = readadc(0)
print(val)
time.sleep(0.5)
ØMQ로 데이터 스트리밍
ØMQ(ZeroMQ)는 고성능 메시징 라이브러리로 네트워킹을 단순화합니다. REQUEST/REPLY 패턴을 사용해 파이썬으로 경량 서버와 클라이언트를 구축할 수 있습니다.
서버
import zmq
context = zmq.Context()
socket = context.socket(zmq.REP)
socket.bind('tcp://*:1980')
while True:
message = socket.recv()
print(message)
socket.send(b"I'm here")
클라이언트
import zmq
context = zmq.Context()
socket = context.socket(zmq.REQ)
socket.connect('tcp://192.168.1.6:1980')
for _ in range(10):
socket.send(b'You home?')
message = socket.recv()
print(message)
traits와 enaml을 사용하면 스트리밍 데이터를 시각화하는 반응형 UI를 만들 수 있습니다. 전체 예제는 acc_plot 데모를 참고하세요.
서보 모터 제어
서보 모터는 PWM(펄스 폭 변조)을 사용해 정밀한 위치로 이동합니다. 일반적인 하비 서보는 0.5ms 펄스를 최소 각도, 2.5ms 펄스를 최대 각도로 해석하며, 20ms마다 반복합니다.
범용 OS에서 정밀한 타이밍을 구현하기는 어렵습니다. ServoBlaster는 PWM 생성을 DMA 컨트롤러에 오프로드하는 커널 모듈로, 간단한 /dev/servoblaster 인터페이스를 제공합니다.
이 기능을 작은 객체 지향 라이브러리로 래핑했습니다: RobotBrain. 아래 예제는 서보를 0%에서 100% 듀티 사이클로 이동시킵니다.
import time
import numpy as np
from robot_brain.servo import Servo
# 핀 4에 서보 초기화, 최소/최대 펄스 폭 커스텀(마이크로초 단위)
servo = Servo(0, min=60, max=200)
for val in np.arange(0, 1, 0.05):
servo.set(val)
time.sleep(0.1)
깃허브의 servo_slider 데모를 통해 네트워크로 서보를 제어하는 방법을 확인할 수 있습니다.
라즈베리 파이로 센서와 액추에이터를 제어하는 더 깊은 내용은 원본 문서나 커뮤니티 튜토리얼을 참조하세요.