[권문송의 라즈베리 파이 먹기] (7)로봇 관절을 꿈꿨지만… 현실은

- Advertisement -

[프로젝트 7] 서보 모터를 돌려보자. 진짜 그냥 돌려만 보자.

안녕하세요. [권문송의 라즈베리 파이 먹기] 시간이 돌아왔습니다. 제가 라즈베리 파이 <3>편에서 이런 말을 한 적이 있네요.

그랑죠 하면 로봇, 로봇 하면 관절이죠. 이 로봇의 관절은 모터로 움직입니다. 실제 라즈베리 파이 로봇 팔 키트도 판매하고 있네요. 이런 것도 있습니다.

그랑죠 수준은 아니더라도 로봇 팔 정도를 움직여 보려면 모터에 대해 알아봐야겠죠. 그래서 라즈베리 파이 테스트용 모터로 잘 알려진 서보 모터를 돌려보겠습니다.

이게 라즈베리 파이로 돌릴 수 있는 서보 모터 중 가장 저렴한 제품인 거 같습니다. 인터넷에서 천 원대로 구매할 수 있습니다. 서보 모터 종류는 매우 다양하지만, 입문자인 만큼 가장 싼 제품으로 어떻게 구동하는지부터 먼저 알아보도록 하겠습니다.

같은 제품의 데이터시트입니다. 이게 무슨 말인가 싶어서 저도 인터넷을 통해 열심히 자료를 찾아봤습니다. 우선 모터 사이즈는 크게 상관없겠죠. 이 서보 모터는 180도까지 돌아갑니다. 실제로 로봇 관절처럼 사용하기에는 힘이 부족하다고 하네요. 라즈베리 파이 연습용으로 많이 추천하고 있습니다.

아래쪽 하단에 보면 듀티사이클(DutyCycle)이라는 게 있습니다. 1-2ms라고 표시되어 있는데요. 이게 매우 중요했습니다. 이 부분은 뒤에서 다시 말씀드리도록 하죠.

서보 모터는 3개 선이 붙어 있습니다. 오렌지(주황)색은 PWM이라고 해서 서보 모터를 제어하는 역할을 합니다. 빨간 선은 +로 라즈베리 파이 GPIO의 5V 핀에 꽂아줄 겁니다. 갈색은 -로 GPIO 그라운드(GND)와 연결합니다.

서보 모터 케이블은 하나로 붙어 있습니다. 그래서 암수 점퍼 와이어 3개가 더 필요합니다. 라즈베리 파이 GPIO에 따로 연결해야 하기 때문이죠.

전에는 왼쪽 사진으로 GPIO를 이해했습니다. 그런데 좀 더 구체적인 이미지가 있었습니다. 바로 오른쪽에 있는 사진입니다. 여기는 단순 GPIO와 5V, GND 등 3가지 핀 외에 PWM 표시도 있습니다.

PWM은 ‘펄스 폭 변조(Pulse Width Modulation)’라는 뜻입니다. GPIO핀은 디지털 신호기 때문에 PWM을 통해 아날로그 신호(모터)를 제어해야 합니다. 가령 LED나 부저, 버튼 등을 연결할 때는 아무 GPIO에 선을 연결했겠죠. 그러나 서보 모터를 사용하려면 오렌지색 선을 PWM이 가능한 GPIO 핀에 꽂아야 합니다.

제가 내용을 참고한 블로거분은 ‘이거 믿으세요’라며 오렌지는 GPIO 18, 빨간 선은 전원 선(5V), 갈색은 GND에 연결하라고 조언했습니다. 믿었습니다. 그리고 구원받았습니다. GPIO 18 외 GPOP12, GPIO13. GPIO 19 등에 연결해도 괜찮을 거 같습니다. 실제 해보진 않았습니다.

우선 서보 모터 선을 나누기 위해 암수 점퍼 와이어 3개를 준비했습니다. 색 혼돈을 피하기 위해서 서보 모터에 연결된 선 색상과 같은 색의 점퍼 와이어로 진행했습니다.

이렇게 됩니다. 그 후 분리된 선을 라즈베리 파이 GPIO에 꽂아줍니다. 저는 아래 사진처럼 노란색 동그라미를 친 GPIO에 연결했습니다.

이렇게만 연결하면 사실 기본 세팅은 끝납니다. 참 쉽죠?라고 말하고 싶지만 이제 즐거운 코딩 시간입니다. 사실 코딩의 코자도 모르는 상황에서 서보 모터를 돌리는 구문을 짜는 게 막막했습니다. 그러나 역시 인터넷은 정보의 보고입니다. 딱 제가 원하는 수준의 서보 모터 스크립트를 짜주신 분들이 몇몇 계시더라고요.

그전에 해야 할 일이 있었습니다. 이번 코딩은 파이썬으로 할건데요. 파이썬에서 GPIO를 제어할 수 있도록 설치해야 할 것이 있습니다. 바로 GPIO.RPi 라이브러리입니다. 간단하게 라즈비안 터미널에서 sudo apt-get install python-rpi.gpio라고 치면 됩니다.

icon-alert

ic_multitracktest

네이버 동영상 플레이어

재생시간, 이 동영상의 길이는 18초 입니다.

화질 선택 옵션

화질 선택 옵션

GPIO.RPi 라이브러리 설치

그다음 파이썬 툴인 토니를 열어 구문을 넣어줍니다.

import RPi.GPIO as GPIO

import time

pin = 18 # PWM pin num 18

GPIO.setmode(GPIO.BCM)

GPIO.setup(pin, GPIO.OUT)

p = GPIO.PWM(pin, 50)

p.start(0)

cnt = 0

try:

while True:

p.ChangeDutyCycle(1)

print “angle : 1”

time.sleep(1)

p.ChangeDutyCycle(5)

print “angle : 5”

time.sleep(1)

p.ChangeDutyCycle(8)

print “angle : 8”

time.sleep(1)

except KeyboardInterrupt:

p.stop()

GPIO.cleanup()

출처: https://ljs93kr.tistory.com/40 [건프의 소소한 개발이야기]

저는 ‘건프의 소소한 개발이야기’님 블로그에 있는 구문을 참고했습니다. 중간에 print “angle : 1” 구문은 실행해보니 괄호()가 없다고 메시지가 떴습니다. 그래서 괄호를 넣어주고 실행했습니다. 아래 영상입니다.

icon-alert

ic_multitracktest

네이버 동영상 플레이어

재생시간, 이 동영상의 길이는 1분 56초 입니다.

화질 선택 옵션

화질 선택 옵션

서보 모터 파이썬 코딩

엄청난 속도로 코딩하는 거 같지만, 사실 영상을 3배속 한 것입니다. 실제 실행에는 문제가 없었습니다. 그렇다면 그냥 서보 모터를 돌리고 끝내면 될까요? 그럼 ‘왜 이렇게 될까’에 대한 의문을 해소할 수 없겠죠. 그래서 인터넷을 돌아다니며 구문 하나하나가 어떤 의미가 있는지 찾아봤습니다. 블로거 웹나우테스님(https://webnautes.tistory.com/1346)께서 엄청 친절하게 잘 설명해주셨더라고요. 그것도 동영상으로 말이죠. 이걸 제가 입력했던 구문에 적용해서 이야기해보겠습니다.

1번 import RPi.GPIO as GPIO는 서보 모터를 제어할 RPi.GPIO를 불러오는 거라고 합니다. 아까 라이브러리를 설치했던 것을 의미하는 것 같습니다.

2번은 모터 동작 후 대기할 때 사용할 time 모듈을 불러옵니다. 그 뒤로는 설명에 좀 차이가 있었습니다. 4번 라인은 아까 GPIO 18번에 꽂았던 주황색 선을 제어 핀으로 설정하는 것이겠 죠. 이후 GPIO를 설정하는데, 6번은 GPIO.setmode(GPIO.BCM)는 BCM 모드로 GPIO를 제어한다는 뜻입니다.

BCM은 무엇인가. 또 열심히 찾아봤죠. GPIO를 제어하는 방식으로는 2가지가 있습니다. 하나는 BCM이고, 다른 하나는 Board 모드입니다. 각각 핀 번호가 다릅니다. 아래 사진을 보면 쉽게 이해할 수 있습니다.

가운데 있는 동그란 숫자가 Board 모드 핀 번호입니다. 하지만 BCM이 GPIO 명령과 함께 사용할 때는 좀 더 쉬운 것 같습니다. 양쪽 밖에 있는 게 BCM으로 Board 12번이 GPIO 18번이 되는 겁니다.

7번 구문은 GPIO 입출력을 설정하는 것입니다. GPIO.setup(pin, GPIO.OUT)로 핀(pin)을 출력(GPIO.OUT)으로 설정합니다. pin은 앞서 4번 구문에서 GPIO 18번으로 정해두었습니다.

8번 구문부터 머리가 아파지기 시작했습니다. 일단 p = GPIO.PWM(pin, 50)은 GPIO 18번 핀을 PWM으로 사용하고, 주파수를 50Hz로 한다는 의미입니다. PWM과 GPIO 18은 알겠는데, 주파수는 또 무엇일까요.

서보 모터 종류마다 차이가 있지만, PWM은 정해진 주파 수 신호를 받아야 작동이 됩니다. 이 서보 모터는 주파수 50Hz이고, 50Hz의 주파수 신호가 입력돼야 서보 모터가 돌아간다는 뜻입니다. 9번 구문인 p.start(0)은 듀티 사이클 0%로 PWM을 시작하는 겁니다.

앞에서도 언급했던 듀티 사이클이란 무엇일까요. 아래 사진을 먼저 보시죠.

제가 가지고 있는 서보 모터(왼쪽)의 듀티 사이클은 오른쪽과 같습니다. 듀티 사이클은 한 주기 내에 신호가 들어오는(HIGH) 비율입니다. 한 주기는 20ms인데 여기서 1ms 비율의 듀티 사이클의 경우 5%로, 모터는 -90도로 회전합니다. 1.5ms 경우 7.5% 0도로, 2ms일 경우 10%, 다시 90도로 이동합니다.

파이썬에서는 한 주기에서 신호가 HIGH 구간의 비율인 듀티 사이클로 서보 모터를 제어합니다. 그러니 듀티 사이클 입력하는 값이 다음과 같아지겠죠.

주기

듀티 사이클

회전 각도

파이썬 입력값

1ms

5%

-90

p.ChangeDutyCircle(5)

1.5ms

7.5%

0

p.ChangeDutyCircle(7.5)

2ms

10%

90

p.ChangeDutyCircle(10)

문제는 데이터시트에 표시된 주기에 따라 회전 각도가 정확히 맞지 않다는 겁니다. 실제로 위의 (5), (7.5), (10) 의 튜티 사이클을 입력했을 때 모터 회전입니다.

icon-alert

ic_multitracktest

네이버 동영상 플레이어

재생시간, 이 동영상의 길이는 15초 입니다.

화질 선택 옵션

화질 선택 옵션

듀티 사이클 (5) (7.5) (10)

이동 각도가 90도 차이보다는 약 45도 차이로 움직입니다. 앞서 파이썬 구문으로 짰던 (1), (5), (8) 듀티 사이클도 조금씩 각도 차이가 있습니다. 이건 건프의 소소한 개발이야기 블로거님 버전이었습니다.

icon-alert

ic_multitracktest

네이버 동영상 플레이어

재생시간, 이 동영상의 길이는 18초 입니다.

화질 선택 옵션

화질 선택 옵션

듀티 사이클 (1) (5) (8)

그나마 웹나우테스 블로거님이 제시한 듀티 사이클 값이 가장 유사하게 90도 단위(마지막은 180도)와 유사했습니다. 듀티 사이클 값은 (3), (7.5), (12) 입니다.

icon-alert

ic_multitracktest

네이버 동영상 플레이어

재생시간, 이 동영상의 길이는 15초 입니다.

화질 선택 옵션

화질 선택 옵션

듀티 사이클 (3) (7.5) (12)

어설프게나마 이해한 대로 서보 모터를 돌려보았습니다. 여기서 얻은 결론은 데이터시트 값대로 해도 정확하지 않을 수 있다는 겁니다. 실제 듀티 사이클 값을 변경하면서 진짜 90도 회전 각도를 찾아야 하는 걸까요. 아니면 제가 입력했던 듀티 사이클 값들의 제품이 실제로 다른 제품이었던 걸까요. 같이 구매한 다른 모터로 같은 값을 주면서 테스트해봐야겠습니다.

듀티 사이클 입력 밑에 print 구문이 있는데 이건 파이썬 툴 토니에서 어떤 듀티 사이클로 돌고 있는지 값을 출력해주는 겁니다. 화면으로 쉽게 파악할 수 있습니다. 마지막 밑에 있는 구문은 전체를 정리해 주는 문장이라고 합니다. 제가 내용을 스킵 한다고 해서 중요하지 않은 것이 아닙니다. 잘 몰라서 그렇습니다. 아시는 분은 좀 도와주세요 ㅜㅜ

이게 만약 좀 더 강한 모터고, 다른 부품을 덧붙이면 로봇팔같이 움직일 수 있을까요? 실력이 미천하여 아직 로봇 팔의 모양새도 못 만들고 있네요. 계속 노력하겠습니다. 그래도 이걸로 뭘 할 수 있을까 싶어 좀 더 만지작거려봤습니다.

icon-alert

ic_multitracktest

네이버 동영상 플레이어

재생시간, 이 동영상의 길이는 25초 입니다.

화질 선택 옵션

화질 선택 옵션

따귀

지금은 여기에서 만족하겠습니다 ㅜㅜ. 혹시 제가 잘못 이해했거나 오류 부분이 있으면 댓글 부탁드립니다. 다음 시간에 또 만나요~

사실 이 모터는 두 번째 모터였습니다

전에 구매한 라즈베리 파이 입문용 키트에는 서보 모터가 하나만 있었습니다. 그런데 듀티 사이클 값을 잘못 입력했는지, 이상한 움직임을 보였습니다.