[아두이노] L293D + DC MOTOR 제어

IOT/아두이노|2019. 5. 17. 09:00

[아두이노] L293D + DC MOTOR 제어



지난 시간에 DC Motor의 회전 방향 제어와 속도 제어를 가단히 실험 하였습니다. 오늘은 L293D 칩을 이용하여 방향과 속도 제어를 실험을 하겠습니다. DC MOTOR를 제어하는 모터쉴드 중 가장 싸고 가장 많이 사용되는 모터쉴드의 사용되는 칩입니다. 이제 L293D 칩으로 어떻게 DC MOTOR를 제어하는지 알아보도록 하죠.

1. L293D



L293D 칩은 16Pin으로 구성되어 있습니다. 아래 핀 정보를 잘 살펴 봐주세요.


[핀 정보]
Vcc - 8, 16 Pin
Gnd - 4, 5, 12, 13 Pin
Enable - 1, 9 Pin (속도)
Input - In1(2), In2(7), In3(10), In4(15)
Output - Out1(3), Out2(6), Out3(11), Out(14)

총 4개의 Input 값에 의해 4개의 Output 신호를 만들어 냅니다. L293D 칩을 이용하면 D2 Motor 2개를 제어할 수 있게 됩니다.

In1+In2 => Out1+Out2 = DC Motor1 (Enable1 - 1번핀)
In3+In4 => Out3+Out4 = DC Motor2 (Enable2 - 9번핀)

위 관계를 잘 기억해 두세요. 이 관계를 통해서 DC Motor의 회전과 속도가 결정됩니다.

예로)
In1(HIGH) + In2(LOW) 이면 Out1(DC Motor + 연결), Out2(DC Motor - 연결) 되어 있다면 정방향 회전입니다.
Enalbe1(255) 이면 정방향으로 255속도로 회전됩니다.

In1(LOW) + In2(HIGH) 이면 Out1(DC Motor + 연결), Out2(DC Motor - 연결) 되어 있다면 역방향 회전입니다.
Enalbe1(255) 이면 역방향으로 255속도로 회전됩니다.

In1(HIGH) + In2(HIGH) 이면 Out1(DC Motor + 연결), Out2(DC Motor - 연결) 되어 있다면 정지입니다.
In1(LOW) + In2(LOW) 이면 Out1(DC Motor + 연결), Out2(DC Motor - 연결) 되어 있다면 정지입니다.

기본 동작을 이해 했으니깐 이제 실험을 할까요.

2. L293D + DC Motor 회로도


  • 준비물 : L293D, 가변저항 1개, DC Motor 2개, Power Supply, 아두이노우노
  • 내용 : 핀정보를 통해서 DC Motor 제어할 4개의 Input핀과, 1개 Enable 핀을 아두이노에서 적당한 핀을 선택하여 연결한다.


L293D 핀을 연결할 때 In1(7번), In2(6번), In3(8), In4(9번)을 연결 했습니다. Enable(5번) 핀은 2개의 Enable핀을 하나의 핀으로 연결 했습니다.

Motor1 => In1(+핀), In2(-핀)
Motor2 => In4(+핀), In3(-핀)

3. 코딩


L293D 칩의 동작을 기준으로 FORWARD, BACKWARD, RELEASE의 세가지 상태를 코딩으로 만들어야 합니다.

가상시뮬레이터에서 실험을 해야 하기 때문에 const 형을 가상시뮬레이터에서 실험하니깐 사이트 문제인지 error가 발생했다 안했다 해서 그냥 아래와 같이 선언 했습니다. 한번 error가 발생하면 지금까지 실험한 정상적인 모든 회로로들이 전부 error가 발생해서 이 표현을 원래 싫어하는데 그냥 사용 했네요.

#define FORWARD  1
#define BACKWARD 2
#define RELEASE  3

byte enablePin = 5;
byte motorPin1 = 7;
byte motorPin2 = 6;
byte motorPin3 = 9;
byte motorPin4 = 8;

FORWARD 상태를 우선 하나를 기준으로 만들어 볼까요.

digitalWrite(motorPin1,HIGH);
digitalWrite(motorPin2,LOW);
digitalWrite(motorPin3,HIGH);
digitalWrite(motorPin4,LOW);

이렇게 L293D 칩에 입력을 주어졌을 때 이 상태를 FORWARD라고 기준을 정합니다. 그러면, BACKWARD은 반대로 전류가 공급되면 되겠죠.

digitalWrite(motorPin1,LOW);
digitalWrite(motorPin2,HIGH);
digitalWrite(motorPin3,LOW);
digitalWrite(motorPin4,HIGH);

어렵지 않죠. 그러면 RELEASE은 어떻게 전류 공급 상태를 만들어야 할까요. 정지는 두가지로 나뉘는데 어떤 것을 선택해도 상관 없습니다.

digitalWrite(motorPin1,HIGH);
digitalWrite(motorPin2,HIGH);
digitalWrite(motorPin3,HIGH);
digitalWrite(motorPin4,HIGH);

or

digitalWrite(motorPin1,LOW);
digitalWrite(motorPin2,LOW);
digitalWrite(motorPin3,LOW);
digitalWrite(motorPin4,LOW);

전부 HIGH or LOW가 되면 전류가 흐르지 않기 때문에 정지 상태가 됩니다.

이대로 코딩하기 보단 가독성을 위해 사용자 정의함수로 표현

void motorMove(int key){
  switch(key){
    case 1:
            digitalWrite(motorPin1,HIGH);
            digitalWrite(motorPin2,LOW);
            digitalWrite(motorPin3,HIGH);
            digitalWrite(motorPin4,LOW);
            break;
    case 2:
            digitalWrite(motorPin1,LOW);
            digitalWrite(motorPin2,HIGH);
            digitalWrite(motorPin3,LOW);
            digitalWrite(motorPin4,HIGH);
            break;
    case 3:
            digitalWrite(motorPin1,HIGH);
            digitalWrite(motorPin2,HIGH);
            digitalWrite(motorPin3,HIGH);
            digitalWrite(motorPin4,HIGH);
            break;
  }  
} 

3가지 상태를 선택제어문 switch() 함수를 통해서 3가지 상태중 하나를 선택하게 사용자정의 함수로 만들어 놓습니다.

이제 명령은 아래와 같이 가독성이 있는 코딩을 할 수 있습니다.

motorMove(FORWARD);
delay(1000); 
  
motorMove(BACKWARD);
delay(1000); 
  
motorMove(RELEASE);
delay(1000);  

코드만 봐도 FORWARD 상태로 1초동안 회전하고, BACKWARD 상태로 1초동안 회전하고 RELEASE상태로 1초동안 회전한다고 쉽게 위 코딩을 해석할 수 있고 쉽게 motorMove()함수로 Motor 동작을 제어할 수 있게 되었습니다.

DC Motor 속도 제어

지난 시간의 코딩과 동일합니다. 가변저항으로 속도를 결정하게 하였습니다.

  int speed = map(analogRead(A0), 0, 1023, 0, 255); //가변저항기의 입력값
  analogWrite(enablePin, speed);

속도핀 enablePin으로 가변저항으로 읽은 speed 값으로 DC Motor의 속도를 결정하게 됩니다.

종합해보면,

#define FORWARD  1
#define BACKWARD 2
#define RELEASE  3

byte enablePin = 5;
byte motorPin1 = 7;
byte motorPin2 = 6;
byte motorPin3 = 9;
byte motorPin4 = 8;

void setup() {
  pinMode(enablePin,OUTPUT); 
  pinMode(motorPin1,OUTPUT);
  pinMode(motorPin2,OUTPUT);
  pinMode(motorPin3,OUTPUT);
  pinMode(motorPin4,OUTPUT);  
  motorMove(RELEASE);
}
 
void loop() {
    
  int speed = map(analogRead(A0), 0, 1023, 0, 255); //가변저항기의 입력값
  analogWrite(enablePin, speed);

  motorMove(FORWARD);
  delay(1000); 
  
  motorMove(BACKWARD);
  delay(1000); 
  
  motorMove(RELEASE);
  delay(1000);  
} 

void motorMove(int key){
  switch(key){
    case 1:
            digitalWrite(motorPin1,HIGH);
            digitalWrite(motorPin2,LOW);
            digitalWrite(motorPin3,HIGH);
            digitalWrite(motorPin4,LOW);
            break;
    case 2:
            digitalWrite(motorPin1,LOW);
            digitalWrite(motorPin2,HIGH);
            digitalWrite(motorPin3,LOW);
            digitalWrite(motorPin4,HIGH);
            break;
    case 3:
            digitalWrite(motorPin1,HIGH);
            digitalWrite(motorPin2,HIGH);
            digitalWrite(motorPin3,HIGH);
            digitalWrite(motorPin4,HIGH);
            break;
  }  
}

4. 결과


위 회로도대로 연결해서 시뮬레이터를 하면 FORWARD가 +RPM이고 BACKWARD은 -RPM으로 돌아갑니다. 그리고, FORWARD, BACKWARD, RELEASE 상태를 각각 1초씩 실행하기 때문에 속도가 즉각적으로 반응하지 않습니다. 즉각적으로 반응하게 하려면 delay함수 없이 delay 효과를 부여하여 코딩해야 합니다. 하지만 오늘 실험은 회전 방향과 속도만 실험하기 때문에 생략 했습니다.


마무리


오늘 배운 L293D 칩을 통해서 DC Motor 2개를 제어를 해보았습니다. L293D 칩의 경우는 16개핀으로 좀 복잡해 보일 수 있지만 사실 Input 핀 4개와 Enable 핀 2개에 대해서만 알고 있으면 쉽게 제어가 가능하기 때문에 어렵게 생각 안하셔도 됩니다. 시중에서 판매하는 L293D 모터쉴드는 L293D 칩이 2개가 결합 된 형태로 DC Motor 4개를 제어할 수 있습니다.

나중에 L293D 모터쉴드를 통해 DC Motor를 제어할 때 사전 지식으로 L293D 칩에 대한 동작 제어를 알아 두시면 좋습니다.


댓글()