Processor

【라즈베리파이】 wiringPi Python : 서보 모터 SG90 동작

작성자 임베디드코리아 작성일26-02-20 00:25 조회75회 댓글0건
◆ 서보모터는 20ms 주기의  펄스파에서 1ms~2ms 범위의 High 신호 파형으로 회전 각도가 정해지며,
    180˚ 서보의 경우, 1ms 신호일 때, 0˚의 위치로 이동하며, 1.5ms 이면 90˚ ,  2ms 일 때 180˚의 위치로 이동한다.
◆ 1ms~2ms의 신호 범위로 0˚~180˚의 각도를 조절한다.
◆ 180˚서보의 경우 실제적으로 움직일 수 있는 각도 범위는 2˚~177˚ 이하로 보는 것이 좋으며,
    일부 서보모터의 경우 1~2ms 작동 범위의 오차가 다소 있다.
◆ 서보모터가 심하게 떨리는 증상이 있다면, 이 범위를 벗어난 신호 때문일 수 있다.

● RaspberryPI에서 서보모터의 각도 변경은 ChangeDutyCycle( ) 함수를 사용한다.
    • 함수의 인자값으로 사용되는 듀티비는 화면과 같은 수식으로 구할 수 있다.
    • 서보모터를 0˚ 위치로 보내기 위해서는 1ms의 PWM 신호를 넣어준다,
      - 1ms는 20ms 신호 주기의 5%에 해당.
        ( ‘5’%라는 인자값을 듀티비 함수에 넣어 주면, 서보모터는 0˚로 이동.)
  • 서보모터를 180˚ 위치로 보내기 위해서는 2ms의 PWM 신호를 넣어준다.
      - 2ms는 20ms 신호 주기의 10%에 해당. 
        ( ‘10’%라는  인자값을 듀티비 함수에 넣어 주면, 서보모터는 180˚로 이동.)
  •  90˚는 인자값 7.5%를 함수에 넣으면 되고, 나머지 각도 계산도 동일한 방식이다.

● 서보모터 제품별로 1ms~2ms(5%~10%) 작동 범위에 오차가 있을 수 있다.
  • 5%~10%의 기본값을 적용하여 오차가 있을 경우,
    듀티비 값을 조금씩 조절해서 각도를 최대로 안정적으로 움직이는 값을 찾으면 된다.
  • SG90 제품의 경우 : 신호 주기를 0.6ms~2.4ms(3%~12%)의 범위로 하였을 때,
      0˚~180˚의 각도 대부분을 제어할 수 있었다. 
 
<<< 서보모터 각도 조절해 보기 (0도 위치로 돌리기) >>>
# 서보는 PWM을 20ms(50hz) 주기로 동작시키고 펄스 폭(duty)만 조절해 위치(각도)를 조절함.
# 여기서 duty는 1주기 동안 High를 유지하는 기간이며,
# 20ms 주기에 100% 면 20ms가 되는 것이고 10% 면 2ms 5% 면 1ms가 됨.
# 펄스 폭은 1ms 일때 0도 2ms 일때 180도, 중간값 1.5ms 일때 90도로 이동함.
# 단, 저렴한 서보는 3%~12%(0도~180도)의 동작 특성을 가짐.
# 만약 모터가 떨린다면, 이 범위를 벗어났기 때문이며, 0도에서 떨린다면
# 3%값에서 조금 올려주고, 180도에서 떨린다면 12%에서 값을 조금 내려주면 됨.

--->>> 예제 : servo01.py  <<<-------------------------------
import RPi.GPIO as GPIO
import time

servo_pin = 18

GPIO.setmode(GPIO.BCM)
GPIO.setup(servo_pin, GPIO.OUT)

pwm = GPIO.PWM(servo_pin, 50)  # 50Hz (서보모터 PWM 동작을 위한 주파수)
pwm.start(3.0)  # 0.6ms

time.sleep(2.0)
pwm.ChangeDutyCycle(0.0)

pwm.stop()
GPIO.cleanup()


--->>> 예제 : servo02.py 0˚→90˚→180˚ 단계로 회전을 하되 3회 반복 <<<---------
import RPi.GPIO as GPIO
import time
servo_pin = 18
GPIO.setmode(GPIO.BCM)
GPIO.setup(servo_pin, GPIO.OUT)
pwm = GPIO.PWM(servo_pin, 50)  # 50Hz (서보모터 PWM 동작을 위한 주파수)
pwm.start(3.0) #서보의 0도 위치(0.6ms)이동:값 3.0은 pwm주기인 20ms의 3%를 의미하므로,0.6ms됨.

for cnt in range(0, 3) :      # 0부터 3미만까지(3번) for문의 내용을 반복
    pwm.ChangeDutyCycle(3.0)  # 서보모터를 0도로 회전(이동)
    time.sleep(1.0)            # 서보 모터가 이동할 시간을 줌
    pwm.ChangeDutyCycle(7.5)  # 서보 모터를 90도로 회전(이동)
    time.sleep(1.0)            # 서보 모터가 이동할 시간을 줌
    pwm.ChangeDutyCycle(12.5)  # 서보 모터를 180도로 회전(이동)
    time.sleep(1.0)            # 서보 모터가 이동할 시간을 줌
   
pwm.ChangeDutyCycle(0.0)

pwm.stop()
GPIO.cleanup()