라즈베리파이(Rasbperry pi)로 모터 제어하기 – L298N

라즈베리파이는 Model 3 B 기준으로 설명하겠다.

 

WiringPi

라즈베리파이에서 pin 제어를 위해서는 WiringPi 라는 라이브러리를 이용하면 편리하다.

다음은 wiringPi 설치법이다.

sudo apt-get update //optional
sudo apt-get upgrade //optional
git clone git://git.drogon.net/wiringPi
cd wiringPi
git pull origin
./build

 

라즈베리파이는 외부 통신을 위하여 다양한 인터페이스를 가지고 있다. 이러한 인터페이스들을 wiringPi에서는 다시 매칭하고 있다. 아래는 그 내용이다.

예를 들어 라즈베리파이에서 GPIO 21번 pin은 WiringPi의 29번으로 매칭이 된다.

 

모터 드라이버 – L298N

모터 드라이버란 모터의 제어를 위해 사용하는 부품이다.

모터의 종류로는 한방향으로만 회전하는 DC모터(일반적으로 우리가 아는 모터이다), 각도를 설정하여 제어할 수 있는 서보모터, 한 바퀴의 회전을 많은 수의 스텝들로 나눌 수 있는 스테퍼 모터 등이 있다.

이 중에 DC모터는 전원을 입력하면 한 방향으로만 회전하기 때문에, 이 모터의 회전 방향과 입력 전원의 전압 및 전류를 조절해주는 장치가 모터 드라이버이다.

모터드라이버는 다양한 종류가 있지만, L298N은 2개의 모터를 연결 할 수 있다.

스펙은 다음과 같다.

– 드라이브 부분의 공급전압 VMS : +5 V ~ 35 V-
– 드라이브 부분의 최대전류 : 2A / bridge
– 로직 부분의 공급전압 VSS : 4.5-5 0.5 V
– 로직 부분의 작동 전류 범위 :0 ~ 36mA
– 입력제어신호 전압 범위 : H: 4.5~ 5.5V / L: 0V
– 최대 소비 전력 : 20W
– 보관 온도 : -25 ℃까지 130 ℃

제어 핀은 총 6개로 ENA, EN1, EN2, EN3, EN4, ENB가 있다.

이 중 세 개(ENA, EN1, EN2)는 한쪽 모터 제어를 위해 사용되고, 나머지 세 개(ENB, EN3, EN4)는 다른쪽 모터 제어를 위해 사용된다.

예를 들어 한 쪽 모터를 움직이려면 “EN1 – High, EN2 – High, ENA – Pwm 제어”와 같이 하면 된다.

필자는 다음과 같이 연결하였다.

Setting PinPin Number
ENAWIringPi29(BCM21)
IN1WIringPi28(BCM20)
IN2WIringPi27(BCM16)
IN3WIringPi25(BCM26)
IN4WIringPi24(BCM19)
ENBWIringPi23(BCM13)

 

입출력 전원은 여기여 연결하면 되는데, 양쪽에 초록색 부분에는 각각 모터에 연결하면 된다.

가운데 파란색 부분에는 입력 전원을 연결해주면 되는데, VMS와 GND에 입력 전원을 넣어주면 되고, 만약 다른 곳으로 5V 출력을 해 주고 싶다면 5V에 연결하면 된다.

 

Source Code – C/C++

C/C++ 코드는 다음과 같다.

#include <stdio.h>
#include <wiringPi.h>
#include <softPwm.h>
#include <unistd.h>

#define ENA 29
#define IN1 28
#define IN2 27
#define IN3 25
#define IN4 24
#define ENB 23

void goFront()
{
    digitalWrite(IN1, 0);
    digitalWrite(IN2, 1);
    digitalWrite(IN3, 0);
    digitalWrite(IN4, 1);
    softPwmWrite(ENA, 128);
    softPwmWrite(ENB, 128);
}

void end()
{
    digitalWrite(IN1, 0);
    digitalWrite(IN2, 0);
    digitalWrite(IN3, 0);
    digitalWrite(IN4, 0);
    softPwmWrite(ENA, 0);
    softPwmWrite(ENB, 0);
}

int main()
{
    if( wiringPiSetup() == -1 )
    {
        printf("wiringPi Error!! \n");
        return 0;
    }

    //Initial Setting
    pinMode(ENA, OUTPUT);
    pinMode(IN1, OUTPUT);
    pinMode(IN2, OUTPUT);
    pinMode(IN3, OUTPUT);
    pinMode(IN4, OUTPUT);
    pinMode(ENB, OUTPUT);
    softPwmCreate(ENA, 0, 255);
    softPwmCreate(ENB, 0, 255);


    //call goFront function
    goFront();
    usleep(1000*1000*5);

    end();
    return 0;
}

Source Code – Aduino

import RPi.GPIO as GPIO
from time import sleep

STOP = 0
FORWARD = 1
BACKWORD = 2

CH1 = 0
CH2 = 1

OUTPUT = 1
INPUT = 0

HIGH = 1
LOW = 0

ENA = 21
IN1 = 20
IN2 = 16
IN3 = 26
IN4 = 19
ENB = 13


def goFront(pwmA, pwmB):
    GPIO.output(IN1, LOW)
    GPIO.output(IN2, HIGH)
    GPIO.output(IN3, LOW)
    GPIO.output(IN4, HIGH)
    pwmA.ChangeDutyCycle(128)
    pwmB.ChangeDutyCycle(128)

def end:
    GPIO.output(IN1, LOW)
    GPIO.output(IN2, LOW)
    GPIO.output(IN3, LOW)
    GPIO.output(IN4, LOW)
    pwmA.ChangeDutyCycle(0)
    pwmB.ChangeDutyCycle(0)
    GPIO.cleanup()


//Initial Setting
GPIO.setmode(GPIO.BCM)
GPIO.setup(ENA, GPIO.OUT)
GPIO.setup(IN1, GPIO.OUT)
GPIO.setup(IN2, GPIO.OUT)
GPIO.setup(IN3, GPIO.OUT)
GPIO.setup(IN4, GPIO.OUT)
GPIO.setup(ENB, GPIO.OUT)
pwmA = GPIO.PWM(ENA, 128)
pwmB = GPIO.PWM(ENB, 128)

//call goFront function
goFront()
sleep(5)

end()