영역별 기술/SBC(싱글보드컴퓨터)

Jetson Nano에서 PWM 동작시켜서 서보모터 돌리기

Seokhwan Yang 2021. 10. 21. 22:56

서보모터(Servo Motor)는 계속 빙글빙글 돌아가는 DC모터와 달리 내장된 제어계측 회로에 의해서 입력된 만큼만 정확하게 움직이는 모터를 말하며, 일반적으로 그 회전 반경에 정해져 있는 경우(주로 0~180도)가 많습니다.

로봇의 관절 등에 많이 사용된다고 하네요.

전문가들이 보는 서보모터는 좀 더 상세한 특징과 정의 등이 있겠지만 저와 같은 비전문가라면 일단 저 정도로만 알고 있어도 좋을 것 같습니다.

 

그래서 지금 사용하고 있는 Jetson Nano에서 서보모터를 동작시켜 보기로 했습니다.

서보모터를 제어하려면 펄스 폭 변조(Pulse Width Modulation, PWM)라는 것을 사용해야 한다고 하더군요.

PWM은 펄스 폭을 변조하는 방법을 이용해서 디지털 출력으로 아날로그 회로를 제어하는 기술이라고 합니다.

일정한 간격으로 신호의 High 레벨과 Low 레벨의 폭을 전환해서 디지털 신호로 표현할 수 없는 중간값을 유사하게 표현함으로써 아날로그 회로를 제어한다고 하네요.

 

그런데 문제는... Jetson Nano는 PWM을 지원하지 않는다고 합니다. 

인터넷을 검색해보면 아두이노나 라즈베리파이를 이용해서 서보모터를 제어하는 정보는 넘쳐나는데 Jetson Nano를 이용한 서보모터 제어는 잘 없군요.

그나마 있는 정보들은 모두 PWM을 지원하기 위하여 PWM 제너레이터가 장착되어 있는 PCA9685와 같은 지원 모듈을 사용했다거나... 아니면 시리얼통신으로 제어되는 서보모터를 구매해서 사용했다거나.. 하는 힘빠지는 이야기들만 나오더군요. ㅠㅠ

PCA9685

이걸 또 사야 하나.. 하고 고민을 하면서 계속 검색을 하고 또 고민을 하고... 하던 중...드디어 해결책을 발견했습니다.

그리고 조금 전에... 아무런 추가 모듈 없이 서보모터를 제어하는 것을 성공했습니다.

알고보니...NVIDIA가 Jetson Nano에 내장된 PWM 제너레이터 기능을 감춰놓았더군요!!!

 

그래서 이번 글에서는 Jetson Nano(B01 버전입니다. 다른 버전은 갖고 있지 않아서 모릅니다)에서 PWM 제너레이터를 이용한 서보모터 제어방법을 정리하도록 하겠습니다.

 

먼저... Jetson Nano를 켜고 다음의 명령을 수행합니다.

$ sudo /opt/nvidia/jetson-io/jetson-io.py

그러면 다음과 같은 프로그램이 실행됩니다.

여기서 Configure Jetson 40pin Header를 선택합니다.

이번에는 Configure header pins manually를 선택합니다.

선택하고 나면 아래와 같은 메뉴가 나옵니다.

제가 아무 생각없이.. 그냥 암수로 된 와이어가 없어서 궁여지책으로 선택했던 33번 핀이... 바로 PWM 제너레이터로 사용되는 핀이었습니다.

이런 것을 숨겨두다니.. NVIDIA....

그럼 PWM0(32), PWM2(33)을 사용하겠다고 선택해봅시다.

둘 중에서 뭐가 뭔지 모르니까 일단 둘 다 선택했습니다.

이제 뒤로 돌아 나와서 저장을 합니다.

마지막으로 모든 작업을 저장하고 재부팅을 선택합니다.

이제 재부팅이 됩니다. 아무 키나 눌러주세요.

재부팅이 끝나면 이제 서보모터를 제어해 보도록 하겠습니다.

그림과 같이 서보모터를 Jetson Nano에 연결합니다.

서보모터의 빨간 선은 5V, 검은 선은 GND, 주황색선은 33번 핀(GPIO.BOARD)

다음은 아래의 코드를 입력해 주세요.

import Jetson.GPIO as GPIO
import time

SERVO_PIN = 33

GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(SERVO_PIN, GPIO.OUT)

pwm = GPIO.PWM(SERVO_PIN, 50)   # 서보모터를 제어하기 위한 주파수. 50Hz = 주기20ms
pwm.start(3.0)                  # PWM 구동 시작(주기 20ms, 주기의 3.0%(=0.6ms)동안 High 신호 출력

for t_high in range(30, 125):             # 30~125 범위동안 
    pwm.ChangeDutyCycle(t_high/10.0)      # 해당 t_high 값의 1/10 만큼 서보모터를 돌리도록 지시
    time.sleep(0.02)
    
pwm.ChangeDutyCycle(3.0)
time.sleep(1.0)
pwm.ChangeDutyCycle(0.0)

pwm.stop()
GPIO.cleanup()

이제 서보모터가 돌아가는 것을 확인하실 수 있습니다.

이제 한시름 놓았습니다.

다음에는 무엇을 해 볼까 생각해봐야 겠네요.

 

 

 

 

반응형