소스 뷰어
# servo_kbd.py
# 키보드 입력을 통해 서보 모터의 각도를 제어하는 프로그램
# GPIO 핀 17을 사용하여 PWM 신호를 생성하고 서보 모터를 제어합니다.
import curses # 키보드 입력을 처리하는 curses 라이브러리 임포트
import RPi.GPIO as GPIO # Raspberry Pi GPIO 제어를 위한 표준 라이브러리 임포트
from time import sleep # 프로그램에 대기(일시 정지) 기능을 추가하기 위한 sleep 함수 임포트
def main(stdscr):
GPIO.setwarnings(False) # GPIO 관련 경고를 비활성화
GPIO.setmode(GPIO.BCM) # BCM 핀 번호 체계를 사용하도록 설정
GPIO.setup(17, GPIO.OUT) # GPIO 핀 17을 출력 모드로 설정
duration = 0.5 # 모터 움직임 간의 대기 시간 (초)
frequency = 50 # 서보 모터의 PWM 주파수 (50Hz)
dc = 0 # 초기 듀티 사이클을 0으로 설정
dc_increment = 2.5/4 # 듀티 사이클을 변경할 때 사용할 증분 값
count = 0 # 실행 횟수
p = GPIO.PWM(17, frequency) # GPIO 핀 17에서 50Hz로 PWM 시작
p.start(0) # PWM을 시작하고 듀티 사이클을 0으로 설정
sleep(duration) # 초기화 후 잠시 대기
p.ChangeDutyCycle(dc) # 초기 듀티 사이클 설정
sleep(duration) # 잠시 대기
# 화면에 안내 메시지 출력
stdscr.addstr(0, 0, "Enter q to quit!") # 프로그램 종료 안내
stdscr.addstr(1, 0, "Use ← ↑ → ↓ key to control servo!") # 방향키로 서보 모터 제어 안내
stdscr.addstr(2, 0, "") # 빈 줄 추가
stdscr.addstr(5, 0, f"[{count:3d}] Duty cycle = {dc:5.2f}") # 현재 듀티 사이클 출력
next_key = None # 다음 입력을 저장할 변수
# 무한 루프: 키 입력을 통해 서보 모터 제어
while 1:
curses.halfdelay(1) # 0.1초 대기 후 입력 대기
# 현재 입력을 확인
if next_key is None:
key = stdscr.getch() # 키 입력 대기
else:
key = next_key # 이전에 저장된 키 입력 사용
next_key = None # 다음 키 입력을 None으로 초기화
pass
if key != -1: # 유효한 키가 입력된 경우
count += 1 # 실행 횟수 증가
curses.halfdelay(3) # 키가 입력되면 0.3초 대기
# 방향키 ↑ 또는 ←가 입력된 경우 듀티 사이클 증가
if key in [curses.KEY_UP, curses.KEY_LEFT]:
dc += dc_increment
stdscr.addstr(3, 0, f"[{count:3d}] ↑ : angle increased.")
# 방향키 ↓ 또는 →가 입력된 경우 듀티 사이클 감소
elif key in [curses.KEY_DOWN, curses.KEY_RIGHT]:
dc -= dc_increment
stdscr.addstr(3, 0, f"[{count:3d}] ↓ : angle decreased.")
# 'q' 또는 'Q'가 입력되면 루프를 종료 (프로그램 종료)
elif key in [ord('q'), ord('Q'), curses.KEY_ENTER]:
stdscr.addstr(3, 0, f"[{count:3d}] q pressed.")
break
pass
# 듀티 사이클이 0에서 12.5 사이에 있도록 제한
dc = max(0, min(12.5, dc))
# 화면에 현재 듀티 사이클을 출력
stdscr.addstr(5, 0, f"[{count:3d}] Duty cycle = {dc:5.2f}")
# 새로운 듀티 사이클을 PWM에 적용하여 서보 모터 제어
p.ChangeDutyCycle(dc)
sleep(duration) # 듀티 사이클 변경 후 잠시 대기
next_key = key # 현재 키 입력을 저장하여 연속적으로 같은 키가 입력되었는지 확인
# 같은 키가 계속 눌렸는지 확인
while next_key == key:
next_key = stdscr.getch() # 다음 키 입력 대기
pass
pass
pass
p.stop() # PWM 신호 중지
GPIO.cleanup() # 사용한 GPIO 핀을 기본 상태로 되돌림
pass
if __name__ == "__main__":
curses.wrapper(main) # curses 환경에서 프로그램 실행
pass