DC 모터 제어하기 – On/OFF 제어 및 PWM으로 속도 제어

DC 모터 제어하기 – On/OFF 제어 및 PWM으로 속도 제어

1. 서보모터와 DC 모터

앞선 글에서 서보모터를 라즈베리파이 피코에서 제어하는 방법을 소개했었다.

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

그런데, 서보모터는 360도 회전을 반복하기보다는 특정한 각도나 위치로 조정하는 데 사용되나, 반복적인 회전을 필요로 하는 경우에는 사용하기에 부적합하다.

이러한 이유로 일반적인 회전력을 필요로 하는 곳에는 서보모터가 아닌 DC 모터가 많이 사용된다. DC 모터는 우리 주변에서 간단한 장치들에서 가장 보편적으로 볼 수 있는 모터로, 2개의 선으로 단자가 구성된 게 특징이다.

DC 모터는 속도나 각도를 정교하게 제어하기는 어려우나 힘이 좋고, 가격도 상대적으로 저렴한 장점이 있다.

일반적으로 DC 모터는 소비전력이 아주 적은 소형 모터를 제외하고는 라즈베리파이 피코 보드에서 나오는 전력만으로는 동작이 불가능하기 때문에, 별도의 전력 공급이 필요하며 통상 다음과 같은 모터 드라이브라는 장치와 결합하여 사용한다.

2. 모터 드라이브 L298N

모터 드라이브는 외부전원을 모터에 공급해 주고, 마이크로컨트롤러에서 입력된 신호로 직접적으로 모터를 제어하는 역할을 하는데, 다양한 제품이 있다.

라즈베리 파이나 아두이노 등의 마이크로 컨트롤러에서 자주 사용되는 소형 모터 드라이브로는 L298N 이란 제품이 많이 사용되는, L298N은 5~35V에 해당되는 DC 모터 2개를 동시에 제어할 수 있고, 각 모터당 2A의 연속 전류를 허용할 수 있다. 또한 단순히 모터를 On/Off 동작으로만 제어하는 것이 아니라, PWM 신호를 주면 모터의 속도도 제어가 가능하다.

이처럼 L298N은 성능은 소형 장치에 사용할 만큼 꽤 쓸만함에도, 가격은 매우 저렴해서 수천원 정도로 구입이 가능하기에, 많이 사용되곤 한다.

L298N 모터 드라이브의 모습 및 배선 연결은 다음과 같다.

모터 1개를 제어할 경우 Input 단자 4개 중 1번과 2번을 이용하여 연결하면 된다.

모터의 용량이 커서 외부에서 별도 전원을 모터 드라이브에 연결하는 경우, 모터 드라이브의 GND 단자는 라즈베리파이 피코 보드의 GND에 연결해야 한다.

연결하는 모터들을 단순 On/OFF 동작으로 모터를 제어할 경우 Input 단자 옆이 Enable 핀 스위치들은 연결한 상태로 둔다. 이것을 제거하면 해당 모터가 동작하지 않는다(또는 PWM 연결을 해서 속도 제어 방식으로 사용해야 한다.)

3. DC 모터 On/Off 및 방향제어

DC 모터의 제어 원리는 간단하다.

프로그램 앞부분에 필수 library를 선언하고,

import machine

import utime

다음과 같이 헤더 핀 2개를 디지털 출력으로 선언하고,

m1 = machine.Pin(14, machine.Pin.OUT)

m2 = machine.Pin(15, machine.Pin.OUT)

모터 드라이브의 출력핀 2개를 각기 디지털 High와 Low로 놓아 방향을 제어한다

m1(1)

m2(0) 이렇게 2개의 핀에 출력하면 한쪽 방향으로 회전한다.

두 핀에 동시에 low, low를 출력하면 모터는 정지하게 된다.

m1(0)

m2(0)

그리고 다시 두 핀에 동시에 high, low를 처음과 반대로 출력하면, 반대 방향으로 회전하게 된다.

m1(0)

m2(1) 반대 방향으로 회전한다.

이러한 원리를 토대로 다음의 예제 Code를 만들고

import machine
import utime
 
m1 = machine.Pin(14, machine.Pin.OUT)
m2 = machine.Pin(15, machine.Pin.OUT)
while True:
    #정방향 회전
    m1(1)
m2(0)
    utime.sleep(2)
    #정지
    m1(0)
m2(0)
    utime.sleep(5)
    #반대방향 회전
    m1(0)
m2(1)
    utime.sleep(2)
    #정지
    m1(0)
m2(0)
    utime.sleep(5)

실행시키면 다음과 같이 동작하게 된다.

4. DC 모터 PWM을 이용한 속도 제어

DC 모터의 속도를 제어하는 원리는 위의 On/OFF 제어를 그대로 적용하되, 모터 드라이브의 Enable 핀에 PWM 신호(PWM 값은 0~65535)를 주어서, 마치 모터 자체의 전원 스위치를 연속적으로 켰다가 끄는 형식으로 제어하는 것이다. 다만, 이 간격이 지극히 짧기 때문에 시각적으로는 속도가 변화하는 것으로 나타나게 되는 것이다.

프로그램 하는 방법은 위에 소개한 On/Off 제어와 동일하나, 추가로 속도제어에 사용할 핀 하나를 PWM 출력으로 선언해야 하고, 초당 몇 개의 펄스 사이클로 제어할지를 주파수로 선언해 준다.

speed = machine.PWM(machine.Pin(16))

speed.freq(1000)

그리고 배선 시 이 PWM 출력 핀데 연결된 신호선을 다음과 같이 모터 드라이브의 Enable 핀에 연결해 주어야 한다. (원래 핀스 위치가 꼽혀져 있는 경우 이를 제거하고 연결하여야 하며, Input 핀 바로 옆의 핀에 연결한다.)

이를 뒷면에서 보면 다음과 같다.

그리고, 모터 출력 시 위의 On/Off 제어와 동일하게 하되 추가로 PWM 출력값을 함께 출력해 주면 된다.

speed.duty_u16(20000)

pin1.high()

pin2.low()

utime.sleep(3)

이러한 원리를 토대로 다음의 예제 Code를 만들고

import machine
import utime
 
pin1 = machine.Pin(14, machine.Pin.OUT)
pin2 = machine.Pin(15, machine.Pin.OUT)
speed = machine.PWM(machine.Pin(16))
speed.freq(1000)
while True:
    
    speed.duty_u16(20000)
    pin1.high()
    pin2.low()
    utime.sleep(3)
    
    pin1.low()
    pin2.high()
    utime.sleep(3)
    
    speed.duty_u16(40000)
    pin1.high()
    pin2.low()
    utime.sleep(3)
    
    pin1.low()
    pin2.high()
    utime.sleep(3)
    
    speed.duty_u16(65535)
    pin1.high()
    pin2.low()
    utime.sleep(3)
    
    pin1.low()
    pin2.high()
    utime.sleep(3)

실행시키면 다음과 같이 동작하게 된다.

참고 : 본 예의 경우, 사용하는 모터가 소형인 점을 고려하여 외부 전력원을 연결하는 대신 라즈베리파이 피코의 5V 출력을 모터 드라이브에 연결하여 사용하였다. PWM 출력값이 너무 낮은 경우(30000 이하)에는 기동에 필요한 토크를 제공하지 못해 동작이 원활하지 않은 경우도 있었다. 즉, DC 모터의 원활한 속도 제어를 하려면 각 모터별로 어느 정도 최소 임계치 이상의 PWM 값을 주어야 동작이 원활함을 알 수 있다.