L293D + DC MOTOR 제어 (아두이노)

in #kr-arduino7 years ago (edited)

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 칩에 대한 동작 제어를 알아 두시면 좋습니다.

Sort:  

스달 날라가는 코딩 짜주세요 ~ 흑흑

원하시는 스팀달러 날라가는 코딩입니다

ㅋㅋㅋㅋㅋㅋㅋㅋㅋ

예전 봐둔 자바스트립트 코딩이였는데 거기에 단어만 넣어서 바로 표현을 해 봤네요.

흐미 복잡한것들이 많네여... 코딩맨이 짱이신듯 @^^@

오늘 핵심은 이것만 이해하시면 됨.

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

Motor핀에 전류 공급하는 방식만 이해하시면 어렵지 않고요. L293D핀 구조를 먼저 이해해야하는게 처음 접하는분들이 어려워하는 부분이지만 알고나면 그렇게 어렵지 않는 칩이고요. 처음만 접해보지 않아서 어렵게 보일꺼에요.
선 연결이 많아서 회로도가 복잡해 보일 뿐 나눠서 살펴보면 선 연결도 그렇게 어렵지 않을 꺼에요.

ㅎㅎㅎ 감사합니다 !꾸준히 계속 보면서 눈에 익혀야겠습니~~

dc motor 제어, 코딩이 간단하네요.

그쵸. 간단한데 접해보지 못해서 약간 처음에 어려워하는 것 같아요.

대부분 어려워 하는 코딩 내용을 쉽게 잘 설명해 주시네요. 감사합니다. ^^

그렇게 생각해 주셔서 감사합니다.

짱짱맨 호출에 출동했습니다!!
고팍스에서 MOC상장 에어드롭 이벤트를 진행합니다.
혜자스러운 고팍스!
https://steemit.com/kr/@gopaxkr/moc

그러면 고팍스에 코인 가지고 있는분 다른 거래소나 지갑으로 이전했다가 다시 옮겨오면 이벤트 참여 되는지 모르겠군요. ^^

그냥 아두이노로 모터를 제어해도 될 것 같은데, L293D를 쓰면 어떤 점이 좋길래 그걸 쓰신 건가요?

절대 안됩니다. 아두이노로 직접 Motor로 전원 공급이나 제어를 하시면 안돼요.
역전류 문제도 있고요. 아두이노에서 DC Motor로 전원을 공급하면요 DC Motor는 다른 모터와 다르게 전력 소모가 많습니다. 그러면 아두이노 보드를 안정상태를 유지할 전류량이 순간 부족할 수 있어요. 그렇게 되면 불안전한 전류상태가 되면 아두이노는 숏다운 됩니다.
Servo Motor도 사실 아두이노에서 그냥 실험하잖아요. 그런데 Servo Motor로 여러개 연결하면 아두이노에서 직접 관리하는게 아니라 중간에 Servo Motor를 관리해주는 모듈이 있는데 그걸 사용합니다.
아무튼 Motor의 겨우는 전력소모가 심하기 때문에 아두이노에 안좋다고 보시면 돼요.
L293D를 쓰면요 외부로 전력을 공급할 수 있고 칩으로 아두이노에서 회전시킬 값만 전송한다고 생각하시면 돼요.
참고로 직접 아두이노에서 제어한다면 DC Motor의 경우 5V이상 Motor는 제어할 수 없습니다.

아, 그래서 저번에 서보모터 돌려보니깐 그렇게 힘 없이 돌아갔던 거군요. 아직도 생생한 기억인데요. LED돌리고, 피에조부조 돌리고, 서버모터 돌리고, 7 세그먼트 하니깐. 서보모터가 정말 힘 없이 돌아가면서 LED도 되게 희미하게 켜졌어요. DC 모터 제어는 수업만 듣고, 직접 해본 적은 없어서 문제가 안 생긴 건지도 모르겠네요. ㅎㅎㅎ. 아하. 이거 아두이노 할 때 전류 전원계산이랑, 소자를 뭘 꽂을지에 따른 계산도 잘 해야겠어요. 방식이 조금씩 다르군요.

Servo Motor에 따라서 필요한 전압이 좀 다를 수 있어요. 약간 전압이면 사실 회전에 좀 그렇겠죠. 많은 전력 소모가 있는 부품들은 될 수 있으면 외부 전류를 공급하는게 좋아요