1. 참고할 이전 글들 – DC 모터 및 서보모터 제어
먼저 작성했던 다음 2개의 글을 통해 서보모터와, DC 모터를 라즈베리파이 피코 보드에서 사용하는 방법을 소개한 바 있었다.
라즈베리파이 피코 보드에서 서보모터를 제어하는 방법은 다음 글을 참고하기 바라며,
https://blog.naver.com/mythee1/223186947086
위의 2개의 글에 이어, 또 다른 중요한 모터 종류인 스텝 모터(Step Motor)를 아두이노나 라즈베리파이에서 자주 사용되는 스텝 모터인 28BYJ-48 모터를 중심으로 라즈베리파이 피코 보드에서 사용하는 방법을 소개한다.
참고로 이 스텝 모터는 5V 또는 12V 구동의 , 4개의 phase를 가진 unipolar 스텝 모터로, 가격이 개당 수천 원 정도로 저렴하고, 구하기 쉬우며, 기본적인 스텝모터의 동작에 필요한 토크도 있어 아두이노나 라즈베리 파이 등에서 널리 사용되는 스텝 모터이다. (관련 Datasheet : http://descargas.cetronic.es/28BYJ-48.pdf )
2. 스텝 모터에 대해서 알아야 할 기본적인 것 들
먼저 작성했던 다음 2개의 글을 통해 서보모터와, DC 모터를 라즈베리파이 피코 보드에서 사용하는 방법을 소개한 바 있었다.
1) 스텝 모터의 특징
먼저 스텝 모터는 브러시리스 DC 모터의 일종으로, 매우 느리기는 하지만, 서보모터와 달리 360도 연속으로도 회전이 가능하면서도, 아주 정교한 동작제어가 가능한 특징이 있다. 서보모터는 특정 각도로 정확하게 회전하는 동작은 가는하지만 연속 회전 등에는 부적합하고, DC 모터는 연속 회전은 가능하지만 정확한 회전수나 회전각도 제어가 어려운데, 스텝 모터는 이 두 가지를 하나로 합쳐놓은 것 같은 기능을 가지고 있다.
연속 신호의 수 (스텝 수)에 따라 회전하는 각도가 정해지기 때문에, 특정 각도까지만 정확하게 회전하는 것도 가능하고, 속도는 느리지만 원하는 횟수만큼 정확하게 연속 회전하는 것도 가능하다.
2) Uni-Polar vs. Bipola
스텝모터는 내부 coil들에 전원을 연결하는 방식에 따라 크게 unipolar와 Bipolar로 나뉜다.
unipolar는 다음과 같이 Coil의 중간부분에 전원선 단자들이 하나씩 있는 모터로, Coil 중간부 전원선으로 인해 외형상 6개선 (또는 전원선을 하나로 통합한 5개선)이 된다.
이들 Coil중간부 단자에 전원선을 연결하면 unipolar 모드로 동작하는데, Bipolar 방식에 비해 고속회전에 유리하나 에너지 효율면에서는 불리한 것으로 알려져 있다.
참고로, Unipolar방식이라 하더라도, Coil중앙부 전원선을 배선에 아예 사용하지 않으면, Unipolar로 설계된 모터도 Bipolar 방식으로 사용이 가능하다.
반면 Bipolar는 Coil중간부에 전원선이 없이 Coil 끝부분에 전원선을 연결하는 경우로, 4선식이 된다.
unipolar 모터에 비해 고속구동은 불리하지만, 에너지 효율이 높고 힘이 더 좋아지는 효과가 있다고 알려져 있다.
Unipolar 모터가 Coil 중간의 전원선을 활용하지 않는 방법으로 Bipolar 방식으로도 구동이 가능함에 반해, 이런 4선식 Bipolar 모터는 Coil중간에 전원연결이 원천적으로 불가능하므로, Unipolar 모드로 구동할수는 없다.
3) 제어 원리 – Full-Stepping vs. Half-Stepping
스텝 모터의 이러한 특징을 간단하게 설명하자면, 모터 내 설치된 인접 코일들에 전류를 서로 반대 방향 또는 약간의 시간 차이를 두면서 흘려주어서, 모터축이 미리 정해진 일정 각도까지 아주 짧은 시간에 움직이면 다음 코일에 가해진 역방향 전류로 인해 반대방향의 힘이 작동해 마치 브레이크가 걸리듯 멈추게 된다. 이렇게 하나의 신호(step)로 아주 작은 각도만큼 회전하게 되는 것이다. 이 상태에서 다시 다음 신호를 반복해 주면, 또 그만큼 회전하게 된다.
이 때문에, 일반적으로 DC 모터는 2선 또는 속도제어를 위한 PWM 신호선까지 3개 선으로 제어하는 반면, 스텝 모터는 여러 개의 내부 코일에 서로 다른 전류 방향을 구현하기 위해 여러 개의 신호선으로 구성된 시퀀스 신호를 주어야 하며, 이로 인해 스텝 모터의 제어선은 4~8개 정도로 상대적으로 많아지게 된다.
모터 코일에 주어지는 신호는 프로그램 코딩 시 시퀀스 구성을 미리 선언하는 방식으로 결정하게 되는데, 시퀀스 구성이 실제 스텝 모터를 동작시키는 중요한 결정 요소가 되며, 형태에 따라 크게 Full-Stepping 방법과, Half-Stepping, 그리고 Microstepping 방법이 알려져 있다.
Full-Stepping은 한 번에 특정 코일에만 신호를 주고 나머지 코일은 신호를 전혀 주지 않는 단순한 방식으로, 모터축이 전류가 흐르는 하나의 코일을 향해 회전하고 더 이상은 회전하지 않게 되는 방식이다. 이 방식은 전력 소모가 적지만, 한 칸 한 칸이 명확히 구분되므로, 토크에 의한 소음과 진동이 발생하기 쉬운 단점이 있다.
프로그램 코딩 시 사용하는 시퀀스 구성 신호는 다음과 같은 형태가 된다.(1상 방식)
|
A |
1 |
0 |
0 |
0 |
|
B |
0 |
1 |
0 |
0 |
|
A- |
0 |
0 |
1 |
0 |
|
B- |
0 |
0 |
0 |
1 |
반면 Half-Stepping은 8개 신호로 구성된 시퀀스 신호로 구성되고, 코일당 3개의 High와 5개의 Low 신호로 구성되며, 코일 단위로 2칸씩 차이가 나게 신호를 주게 된다. 이처럼 Half-Stepping 모드를 사용하게 되면, Step 당 각도를 절반으로 줄여, 좀 더 정밀한 제어가 가능해지고, 진동도 준다
|
A |
1 |
1 |
1 |
0 |
0 |
0 |
0 |
0 |
1 |
1 |
1 |
0 |
0 |
0 |
0 |
0 |
|
B |
0 |
0 |
1 |
1 |
1 |
0 |
0 |
0 |
0 |
0 |
1 |
1 |
1 |
0 |
0 |
0 |
|
A- |
0 |
0 |
0 |
0 |
1 |
1 |
1 |
0 |
0 |
0 |
0 |
0 |
1 |
1 |
1 |
0 |
|
B- |
1 |
0 |
0 |
0 |
0 |
0 |
1 |
1 |
1 |
0 |
0 |
0 |
0 |
0 |
1 |
1 |
이렇게 펄스를 실제 코드에 어떻게 구성해야 하는지에 대해서는 아래 부분의 Coding 예제 부분에서 자세히 설명하였으므로, 해당 부분을 참조하기 바란다.
이러한 Full-Stepping과 Half-Stepping으로 모터가 어떻게 구동하는지에 대해서 잘 소개된 동영상이 있어 소개한다.
https://www.youtube.com/watch?v=dmk6zIkj7WM
4) 모터드라이브
스텝모터 구동에 필요한 충분한 전력을 라즈베리피코 보드에서 직접 줄 수 없기 때문에, 충분한 전력을 제공하려면 모터드라이브를 사용해야 한다. 아두이노나 라즈베리파이에서 자주 사용되는 스텝 모터인 28BYJ-48 모터의 경우는 다음과 같이 생긴 ULN2003 모터드라이브를 사용한다. 이 모터 드라이브는 5V-12V에서 구동한다.
이 모터드라이브의 이름은 사용하는 구동 칩의 이름에서 유래한 것으로 알고 있다.
이 모터드라이브의 칩 부분을 살펴보면 다음과 같이 ULN2003이란 이름을 확인할 수 있다.
그런데, 여기서는 ULN2003을 사용하지만, 실상 사용 가능한 모터 드라이브는 그 종류가 매우 다양하고, 각각에 대해 알아야 할 것들이 많이 있다. 이에 대해서는 잘 정리된 자료가 있으므로 다음 글을 참조하기 바란다. 해당 페이지에서 각각의 이름을 선택하면 보다 자세한 내용들을 확인할 수 있다.
https://medium.com/jungletronics/quick-intro-to-motor-drivers-322e4929db44
5) 해상도 (Stride Angle)
해상도 (Stride Angle)는 한 step 진행시 모터 축이 회전하는 각도를 의미한다.
아두이노나 라즈베리파이에서 자주 사용되는 스텝 모터인 28BYJ-48 모터의 경우는
Half step mode로 제어 시 총 64개 신호로 모터축이 1회전하게 된다. 즉 해상도는 360/64=5.625도가 된다.
Full step mode로 사용 시는 총 32개 신호로 모터축이 1회전하게 되므로 해상도는 360/32=11.25도가 된다.
6) 기어 감속비 (speed variation ratio)
스텝 모터는 정교한 각도 또는 정확한 회전수만큼 회전하는 것을 목표로 하는데, 때로는 위에서 소개한 해상도(Stride angle) 조차 너무 튼 각도가 되는 경우들도 있다. 이러한 경우를 대비하여, 스텝 모터 내부에 감속기어를 추가하여 회전수를 더욱 낮추기도 하는데, 이때 모터 자체의 회전속도와, 감속기어 축의 회전 속도 이 값을 기어 감속비라고 한다.
아두이노나 라즈베리파이에서 자주 사용되는 스텝 모터인 28BYJ-48 모터의 경우는 64:1의 기어 감속비를 가지게 된다.
7) 회전당 스텝 수 (Steps per Revolution)
최종적으로 스텝모터가 1회전 하는데 필요한 신호의 수를 의미하며, 다음과 같이 계산한다.
회선당 스텝 수 = 360/해상도(Stride Angle) x 기어 감속비
28BYJ-48 모터의 경우 Half step mode시는 = 360 / 5.625 x 기어비 64 = 4096 이 되고,
Full step mode시는 = 360 / 11.25 x 기어비 64 = 2048 이 된다.
즉, 28BYJ-48 모터를 1회전 시키려면 Full step mode인 경우 2048개의 신호를 주어야 하고, half step mode인 경우는 4096개의 신호를 주어야 한다.
8) 스텝 각도 (Step Angle)
스텝 모터에 하나의 신호가 들어갈 때 감속기어를 거쳐서 구현되는 최종 동작 각도를 의미한다.
28BYJ-48 모터의 경우 Half step mode시 = 360 / 4096 = 0.088도가 되고,
Full step mode시 = 360 / 2048 = 0.175도가 된다.
3. 라즈베리파이 피코 보드 Coding 예제
아두이노나 라즈베리파이에서 자주 사용되는 스텝 모터인 28BYJ-48 모터와 ULN2003 모터드라이브를 이용하여 구동 회로를 구성했다.
스텝 모터 구동에 필요한 출력 핀 4개는 GP10~13의 4개 핀을 할당하였고, 모터 드라이브와의 연결에 필요한 GND는 간편한 배선을 위해 GP13과 GP14 사이의 GND를, Vcc는 5V 전원이 필요해서 물리 번호 40번 핀을 연결했다.
이들은 모터 드라이브에 다음과 같이 연결했다. (선의 색상 참조)
그리고 다음과 같이 코드를 만들었다.
-
GP10~14 각각의 핀에 대해 디지털 출력을 선언해 주었다. 모터 드라이브에 표기된 단자명을 변수 이름으로 썼다.
IN1 = machine.Pin(10,machine.Pin.OUT)
IN2 = machine.Pin(11,machine.Pin.OUT)
IN3 = machine.Pin(12,machine.Pin.OUT)
IN4 = machine.Pin(13,machine.Pin.OUT)
-
이들 핀에 동시에 신호가 출력되어야 스텝모터가 제어되므로 이들 핀 4개로 구성된 Class를 선언해 주었다.
pins = [IN1, IN2, IN3, IN4]
-
그리고 이들 핀에 줄 신호값을 다음과 같이, full stepping sequence로 구성하였다.
Full stepping이므로, 이를 이용하면, 28BYJ-48 모터는 하나의 Step 당 모터축 자체는 360/32=11.25도를 회전하는데, 모터 내부에 64:1의 감속기어가 내장되어 있으므로, 외부적으로는 11.25/64 = 0.175도가 된다. 결과적으로 이렇게 시퀀스를 구성함으로 인해, 이 스텝 모터는 2048 스텝에 1회전을 하게 되는 것이다.
그런데 이러한 시퀀스를 2번 선언한 것은 각기 정방향과 역방향 회전 각각에 사용하기 위한 것으로, 정방향 시퀀스를 거꾸로 지정해서 선언하면 스텝모터가 반대 방향으로 동작하게 되기 때문이다.
정회전 Sequence = [[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]]
역회전 sequence1 = [[0,0,0,1],[0,0,1,0],[0,1,0,0],[1,0,0,0]]
만일 Full stepping대신 Half stepping방식으로 구동하려면, 시퀀스를 다음과 같이 선언해 주어야 한다.
정회전 Sequence = [[1,0,0,1],[1,0,0,0],[1,1,0,0],[0,1,0,0],[0,1,1,0],[0,0,1,0],[0,0,1,1],[0,0,0,1]]
역회전 sequence1 = [[0,0,0,1],[0,0,1,1],[0,0,1,0],[0,1,1,0],[0,1,0,0],[1,1,0,0],[1,0,0,0],[1,0,0,1]]
만일 이 스텝 모터를 좀 더 세밀하게 움직이는 Half step mode로 제어하려면, 이 Sequence 구성을 위에서 소개한 대로 변경해 주어야 한다. 그러면 2048 스텝이 아닌 4096 스텝에 1회전을 하게 되며, 매 스텝당 (감속기어를 거쳐) 최종적으로 0.088도만큼 회전하게 되는 것이다.
이렇게 선언한 후, 아래와 같이 정방향 1회전하고, 그 후 다시 역방향으로 1회전하는 Code를 다음과 같이 작성했다. (Full Stepping 모드)
import machine
import utime
IN1 = machine.Pin(10,machine.Pin.OUT)
IN2 = machine.Pin(11,machine.Pin.OUT)
IN3 = machine.Pin(12,machine.Pin.OUT)
IN4 = machine.Pin(13,machine.Pin.OUT)
pins = [IN1, IN2, IN3, IN4]
sequence = [[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]]
sequence1 = [[0,0,0,1],[0,0,1,0],[0,1,0,0],[1,0,0,0]]
for k in range(512):
for step in sequence:
for i in range(4):
pins[i].value(step[i])
utime.sleep(0.001)
for k in range(512):
for step in sequence1:
for i in range(4):
pins[i].value(step[i])
utime.sleep(0.001)
Full step 모드로 동작하는 결과는 다음과 같다.
이 경우 1 왕복 회전에 대략 16-17초 정도 소요되는 것을 볼수 있다.
위의 예제를 Full ste으로 구동하는 대신, 신호 시퀜스만 다음과 같이 변경하여, Half-Stepping모드로 변경하면
정회전 Sequence = [[1,0,0,1],[1,0,0,0],[1,1,0,0],[0,1,0,0],[0,1,1,0],[0,0,1,0],[0,0,1,1],[0,0,0,1]]
역회전 sequence1 = [[0,0,0,1],[0,0,1,1],[0,0,1,0],[0,1,1,0],[0,1,0,0],[1,1,0,0],[1,0,0,0],[1,0,0,1]]
최종 Code는 다음과 같아지고
import machine
import utime
IN1 = machine.Pin(10,machine.Pin.OUT)
IN2 = machine.Pin(11,machine.Pin.OUT)
IN3 = machine.Pin(12,machine.Pin.OUT)
IN4 = machine.Pin(13,machine.Pin.OUT)
pins = [IN1, IN2, IN3, IN4]
sequence = [[1,0,0,1],[1,0,0,0],[1,1,0,0],[0,1,0,0],[0,1,1,0],[0,0,1,0],[0,0,1,1],[0,0,0,1]] #정회전
sequence1 = [[0,0,0,1],[0,0,1,1],[0,0,1,0],[0,1,1,0],[0,1,0,0],[1,1,0,0],[1,0,0,0],[1,0,0,1]] #역회전
for k in range(512):
for step in sequence:
for i in range(4):
pins[i].value(step[i])
utime.sleep(0.001)
for k in range(512):
for step in sequence1:
for i in range(4):
pins[i].value(step[i])
utime.sleep(0.001)
동일한 동작을 half stepping 모드로 구동시 동작하는 결과는 다음과 같다.
Full step구동시에 비해 천천히 동작하는 것을 볼수 있으며, 동작시간도 느려서 1왕복 회전에 약 30여초 소요되었다.

