본문 바로가기
Real Cart 프로젝트

[EP.4] 라즈베리파이에서 Servo 모터 제어

by code_killer 2023. 2. 15.
728x90
반응형

1. Servo Motor

  • PWM (Pulse Width Modulation) 유형 신호에 따라 정의 된 특정 각도로 회전하는 모터
  • 종종 소형 모터는 제한적이며 한 번 이상 회전 불가능
  • 따라서 매우 정밀한 짧은 움직임에 사용

1-2. PWM

  • Servo Motor는 Pulse를 조절하여 회전한다.
  • PWM을 20ms(50hz) 주기로 동작시키고 펄스 폭(duty)만 조절해 위치(각도)를 조절하는 것이다.
  • 여기서 duty는 1주기 동안 High(전류가 흐르는 순간)를 유지하는 기간으로 보면 된다.

 

2. 라즈베리파이 연결 및 테스트 코드

  • 라즈베리파이 연결도

 

  • 라즈베리파이 파이썬 코드
import RPi.GPIO as GPIO #RPi.GPIO 라이브러리를 GPIO로 사용
from time import sleep  #time 라이브러리의 sleep함수 사용

servoPin          = 12   # 서보 핀
SERVO_MAX_DUTY    = 12   # 서보의 최대(180도) 위치의 주기
SERVO_MIN_DUTY    = 3    # 서보의 최소(0도) 위치의 주기

GPIO.setmode(GPIO.BOARD)        # GPIO 설정
GPIO.setup(servoPin, GPIO.OUT)  # 서보핀 출력으로 설정

servo = GPIO.PWM(servoPin, 50)  # 서보핀을 PWM 모드 50Hz로 사용하기 (50Hz > 20ms)
servo.start(0)  # 서보 PWM 시작 duty = 0, duty가 0이면 서보는 동작하지 않는다.


'''
서보 위치 제어 함수
degree에 각도를 입력하면 duty로 변환후 서보 제어(ChangeDutyCycle)
'''
def setServoPos(degree):
  # 각도는 180도를 넘을 수 없다.
  if degree > 180:
    degree = 180

  # 각도(degree)를 duty로 변경한다.
  duty = SERVO_MIN_DUTY+(degree*(SERVO_MAX_DUTY-SERVO_MIN_DUTY)/180.0)
  # duty 값 출력
  print("Degree: {} to {}(Duty)".format(degree, duty))

  # 변경된 duty값을 서보 pwm에 적용
  servo.ChangeDutyCycle(duty)


if __name__ == "__main__":  
  # 서보 0도에 위치
  setServoPos(0)
  sleep(1) # 1초 대기
  # 90도에 위치
  setServoPos(90)
  sleep(1)
  # 50도..
  setServoPos(50)
  sleep(1)

  # 120도..
  setServoPos(120)
  sleep(1)

  # 180도에 위치
  setServoPos(180)
  sleep(1)

  # 서보 PWM 정지
  servo.stop()
  # GPIO 모드 초기화
  GPIO.cleanup()
728x90