라즈베리파이 피코에서 PWM 으로 서보모터 제어하기

라즈베리파이 피코에서 PWM 으로 서보모터 제어하기

1. PWM 출력

앞선 글에서, 라즈베리 파이 피코 보드에서 아날로그 신호를 모사한 PWM 신호를 출력하는 방법을 소개한 바 있는데, 이를 이용하면 드론이나, 3D프린터, RC 장치 들의 동작 제어 등에 널리 사용되는 서보모터를 쉽게 동작할 수 있다.

https://blog.naver.com/mythee1/223186100305

2. 서보모터

서보모터는 반복적으로 회전하는 것을 목적으로 하기보다는, 지정한 특정 각도로 회전하는 것이 특징인 모터인데, 0도에서 180도 또는 0도에서 360도 회전하는 형태가 있다. 소비전력이 20mA 정도로 작은 경우에는 별도의 전원 연결 없이 피코 보드 등의 출력핀에서 나오는 전력으로도 동작이 가능하나 (피코보드는 50mA 이하 출력되는 것으로 알려져 있음), 규모가 커서 소비전력이 많은 경우에는 별도의 전원 연결이 필요하다. 물론 이러한 경우 GND는 피코보드의 GND에 연결해 주어야 한다.

라즈베리파이나 아두이노와 같은 마이크로 컨트롤러를 이용한 동작 제어에 사용되는 미니형 서보모터로는 다음과 같은 SG90이나 MG90S 같은 제품들이 많이 접할 수 있는 제품들이며, 이들은 대략 20 mA 정도의 전기를 사용하는 것으로 알려져 있다.

두 제품은 기본적으로 크기나 동작하는 방식은 거의 동일하나,

SG90의 경우는 내부의 기어와 베어링이 플라스틱 재질로 되어 있는 반면

MG90S는 금속 재질 기어와 베어링을 사용해서 좀 더 정교한 동작이 가능하고 수명이 상대적으로 긴 것으로 알려져 있다. 두 제품 모두 동작 방식은 동일하다.

3. 서보모터의 제어 원리

서보모터는 PWM 방식으로 제어하는데, 이들의 제조사 등에서 공지하는 Datasheet(다음 참조)에 보면 배선 방식과, 제어 방식이 공개되어 있으므로, 이를 참조하면 된다.

첨부파일

701916_87897_datasheet_en.pdf

파일 다운로드

이러한 Datasheet들을 참조하다 보면 다음과 같이, 배선하는 방법과

각도별로 제어하는 방법이 소개되어 있다.

예 1

예 2

또한 이러한 Datasheet에는 동작 주파수가 다음과 같은 형태로 표기된다.

주파수 표기 예 1

주파수 표기 예 2

즉, 이 서보모터는 datasheet 상으로는 50Hz의 주파수를 가지므로 하나의 사이클당 20 msec의 주기를 가지는데, 각 사이클당 1msec의 폭을 갖는 펄스를 주면 0도 위치로, 1.5msec의 폭을 가지는 펄스를 출력하면 90도로, 2.0msec의 폭을 가지는 펄스를 PWM으로 출력하면 180도 방향이 되도록 회전하게 되는 것을 알 수 있다.

실제 피코보드의 PWM 핀으로 보내는 펄스의 폭은 duty의 값을 변경하는 방법으로 출력하게 되는데, 한 사이클의 duty 값은 100% 라면 16비트 값의 최대치인 65535를 갖게 된다.

여기서는 한 사이클의 길이가 주파수 50Hz에 의해 20mSec로 결정되고, 각도별로 필요한 펄스 폭에 대한 시간 길이는 datasheet에서 확인되었으므로, 이를 이용하여 계산하면 다음과 같이 된다.

이론상 0도로 동작되도록 PWM 핀으로 실제 출력되어야 하는 duty 값은 : 65535 x 1.0 / 20 = 3276

이론상 90도로 동작되도록 PWM 핀으로 실제 출력되어야 하는 duty 값은 : 65535 x 1.5 / 20 = 4915

이론상 180도로 동작되도록 PWM 핀으로 실제 출력되어야 하는 duty 값은 : 65535 x 2.0 / 20 = 6553

<참고사항>

실제 test 해 보면 SG90의 경우 오차 및 제작사 설계치 변경 등으로 인해 위의 값을 그대로 사용하면 0도에서 180도까지 동작하지는 않는다. 실제로는 0.5msec~2.5 msec 범위로 값을 확장해 주어야 0도에서 180도까지 동작한다. 때문에 실제로 필요한 PWM duty 출력값은 다음과 같다.

실제 0도 동작에 출력되어야 하는 duty 값은 : 65535 x 0.5 / 20 = 1638 보다 작은 값

실제 180도 동작에 출력되어야 하는 duty 값은 : 65535 x 2.5 / 20 = 8192 보다 큰 값

4. 서보모터 PWM 출력 코딩 방법

서보모터의 PWM 출력을 위해서는 다음과 같은 요소들이 필요하다.

먼저 필수 Library를 선언해 준다.

import machine

import utime

그리고 사용할 핀 번호를 PWM으로 선언하면서, 변수를 할당해 준다. 다음은 GP15핀을 PWM으로 지정한다.

servo = machine.PWM(machine.Pin(15))

PWM으로 제어할 장치의 주파수를 PWM 핀이 지정된 변수의 freq( ) 속성을 이용해 지정해 준다.

여기에 사용한 50은 제어할 서보모터의 datasheet에서 찾아서 지정한다.

servo.freq(50)

실제 각도 제어를 위한 duty 값을 출력하려면 다음과 같이 duty_u16( )에 넣을 값을 게 산해야 하는데, 이때 이 값은 정수여야 하므로, int ( ) 함수를 이용하여 계산 값을 정수화 시켜주었다

output=int(2.0/20*65535) –> Data Sheet 상에서 2.0 msec에 해당되는 180도를 목적하는 경우

그리고 다음과 같이 PWM으로 지정된 핀에 duty_u16( ) 속성을 이용하여 PWM 출력을 하면 원하는 위치로 서보모터가 회전한다. 단 원하는 각도까지 기계적 요소가 구동할 시간을 주기 위해, PWM 출력 명령 뒤에 약간의 시간을 주기 위한 sleep 명령을 추가했다.

servo.duty_u16(output)

utime.sleep(2)

서보모터의 배선들은 다음과 같이 피코보드의 5V단자와, GND 단자, 그리고 PWM 출력핀으로 지정한 GP15에 연결했다. (이 서보모터의 동작전압은 5V이다.)

5. 서보모터 PWM 출력 사례, 그리고 Datasheet 과의 편차

위에서 계산한 대로, 서보모터 Datasheet에 제시된 펄스폭인 1msec, 1.5msec, 2.0 msec에 대해 duty output 값에 대해 서보모터를 동작하고 5초 간격으로 다음 각도로 이동하도록 다음 코드를 만들고 작동해 보았다.

import machine
import utime

servo = machine.PWM(machine.Pin(15))
servo.freq(50)

while True:
  
      print ("1, 0 degree")
      servo.duty_u16(3276)
      utime.sleep(5)

      print ("1.5, 90 degree")
      servo.duty_u16(4915)
      utime.sleep(5)

      print ("2.0, 180 degree")
      servo.duty_u16(6553)
      utime.sleep(5)

그 결과, 다음과 같이 서보모터가 잘 작동하기는 하나, 당초 기대했던 대로 0~180도보다는 훨씬 좁은 범위에서 작동했다.

포럼 등에, 서보모터가 오차 등으로 인해 Datasheet에 제시된 1.0~2.0mSec보다 더 넓은 범위의 값에서 동작하는 것을 알게 되어, 이를 확인하기 위해 Code를 약간 변경시켜 다음과 같이 다양한 값으로 duty 출력값이 변화되도록 해 보았다.

import machine
import utime

servo = machine.PWM(machine.Pin(15))
servo.freq(50)

while True:

   for i in range(30) :
      dutypercent=i*0.1/20
      output=int(round(dutypercent*65535, 0))
      
      print (i*0.1, "msec  ", dutypercent*100,"percent and calculated dutyoutput =", output)
      servo.duty_u16(output)
      utime.sleep(2)
      

그 결과,

SG90 서보모터는 실제로는 0.5mSec까지의 펄스 폭에서는 0도를 유지하다가 0.6mSec의 펄스폭을 가지는 경우부터 각도가 변하면서, 2.5mSec 수준이 되었을 때야 180도까지 회전하는 것을, 그 이후로는 값이 더 커져도 추가의 동작 없이 180도 각도를 유지하는 것을 다음 동영상과 같이 확인할 수 있었다.

즉, datasheet와 실제가 좀 달랐다.

또한 이러한 현상은 MG90S 서보모터에서도 동일했다.

이러한 차이가 발생하는 것에 대해서는 여러 사람들에 의해 확인된 것으로 알려져 있다.

다만, 이러한 차이가 발생하는 원인은 다소 분명하지는 않으나, 아마도 여러 제작사가 제품을 만들면서 원본과의 차별화 목적 또는 원본이 불과 1.0 ~2.0msec 구간만으로 180도 구간을 조절하는 것에 비해, 사용성 및 각도 오류를 완화시키기 위해 0.5~2.5mSec로 조절의 범위를 2배 넓어지도록 확장한 것이 아닐까 정도로 추정할 뿐이다.