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

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

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



지난 시간에 L293D를 이용하여 DC Motor의 회전 방향 제어와 속도 제어를 가단히 실험 하였습니다. 오늘은 좀 더 Motor 쉴드에 가깝게 74HC595 칩을 이용하여 L293D 칩을 두개를 제어하여 DC Motor 4개를 제어하는 실험을 하겠습니다.

1. 74HC595 복습




  • 데이터입력핀 DS핀 : 아두이노에서 데이터를 이칩에 보내게 됩니다.(총8개 출력값)
  • STCP 핀 : HIGH, LOW값으로 결쇠 역할을 하는 핀입니다. 칩에 입력할때 LOW 칩을 개방하고 입력을 끝내면 HIGH 칩닫음
  • SHCP 핀 : 클럭핀

세개의 핀 DS, STCP, SHCP를 통해서 74HC595핀을 제어하게 됩니다. 아두이노와 핀 연결은 위 사전학습에 가셔서 한번 읽어 주세요.

  • Q0~Q7 : 각 핀으로 입력된 8개의 값을 출력합니다.

Q0~Q7까지 8개의 값을 출력하는데 여기서 각 4개씩 L293D 칩에 입력신호로 나누면 2개의 L293D 칩을 제어할 수 있게 됩니다.

2. 74HC595+L293D


두 칩을 연결한 모습을 살펴 볼까요.


위 74HC595 칩의 핀넘버를 잘 보시고 L293D 칩의 In1~In4까지 연결된 모습입니다. 좀 햇갈릴 수 있으니 아래 이미지를 보시고 정확한 위치를 파악해 두세요.


그래도, 어렵다면 위에 공개 회로도에 가셔서 해당 칩이 어떻게 연결 되어 있는지 살펴보도록 하세요.

3. 74HC595+L293D+DC MOTOR 회로도


  • 준비물 : 74HC595 1개, L293D 2개, DC Motor 4개, Power Supply, 아두이노우노
  • 내용 : 74HC595핀은 9, 10, 11핀을 연결하고 74HC595 출력 Q0~Q7핀으로 L293D In1~In4핀에 입력 핀에 연결한다. 마지막으로 DC Motor는 L293D 출력핀에 연결한다.

외부 5V 전압일 경우의 실험입니다.


74HC595핀의 전류 아두이노가 아니 이부분도 외부에서 공급되도록 하였습니다. 참고로 74HC595의 허용 전압이 제한되어 있기 때문에 실제로 전압은 DC Motor에 따라 더 높은 전압을 연결할 수 있습니다. 그러면 74HC595의 허용 전압을 초과하게 됩니다 그러면 칩에 문제가 생기기 때문에 5V이상의 전압을 사용할 경우 5V 레귤러를 연결해야 합니다. 그리고 안정적 전류 공급을 위해서 충전기도 달아야 하는데 사실 의미만 전달하기 위한 회로도로 실험하기 때문에 가상시뮬레이터에서만 사용하시고 실제로는 만들지 말아주세요.

외부 5V 전압 이상일 경우 실험은 아래와 같이 5V 레귤러(LM7805)를 달아야 겠죠.



위 그림을 자세히 보시면 5V 레귤러(LM7805)은 I, G, O핀으로 구성되어 있는데 I은 입력 전압이고, G은 Gnd이고, O는 출력전압입니다. 5V 이상의 전압을 출력 5V로 만들어주는 부품입니다.

참고

5V 레귤러(LM7805)를 사용하요 5V 공급되면 강압이 일어나 가상시뮬레이터에서 약3V 전류가 흐르게 됩니다. 5V 레귤러(LM7805)로 5V의 전류가 공급이 될려면 7V이상이 공급되어야 겠죠.


아래 그림처럼 10V가 공급되었을 때 7V 이상이니깐 정상적으로 5V의 전류가 흐르게 됩니다.


오늘 실험 회로도는 간단히 원리만 이해하기 위한 회로도 입니다. 실제 모터쉴드를 구현한다면 추가로 몇가지 부품이 더 있어야 합니다. 여러개의 부품을 연결하면 사실 회로도가 너무 복잡해지기 때문에 간단히 의미만 전달할 수 있는 실험을 위해서 칩들만 연결하고 5V를 제한을 둔 회로도로 DC Motor를 제어하는 실험으로 구성했습니다.

3. 코딩


지난 시간의 코딩과 마찬가지로 L293D 칩의 동작을 기준으로 FORWARD, BACKWARD, RELEASE의 세가지 상태를 코딩으로 만들겠습니다. 참고로 속도 Enable은 Vcc에 연결하여 최대속도로 무조건 회전하도록 회도로를 구성했기 때문에 따로 이부분은 생략합니다.

74HC595 칩의 장점은 1byte 신호값을 8개의 출력 신호로 만들어 낼 수 있다는 점입니다. 그래서 4개의 출력신호로 1개의 DC Motor를 제어할 수 있게 됩니다. 2개의 DC Motor를 제어하니깐 1byte로 구성된 회전명을 미리 만들어 놓으면 쉽게 회전 제어가 가능하겠죠.

#define FORWARD  0B10011001
#define BACKWARD 0B01100110
#define RELEASE  0B00000000

위 표현은 각 비트 자리가 L293D의 입력 핀 값이 되기 때문에 정방향으로 갈려면 다음과 같습니다.
예)
1001 1001
1234 5678
=> FORWARD

나머지 BACKWARD, RELEASE는 해당 Motor 핀위치의 값을 1 or 0으로 맞춰서 값을 표현하면 되겠죠. 그래서 위와 같이 FORWARD, BACKWARD, RELEASE의 세가지 상태값을 정의해 놓습니다.

74HC595 핀을 사용하기 위해서

//Pin connected to ST_CP of 74HC595
const int ST_CP = 10;
//Pin connected to SH_CP of 74HC595
const int SH_CP = 11;
////Pin connected to DS of 74HC595
const int DS = 9;

3개의 핀을 선언합니다.

   pinMode(ST_CP, OUTPUT);
   pinMode(SH_CP, OUTPUT);
   pinMode(DS, OUTPUT);

3개의 핀은 출력모드이니깐 출력모드로 사용한다고 선언하게 됩니다.

74HC595 칩에 1byte의 신호를 전송하기 위해서는 다음과 같은 명령을 내리면 됩니다.

74HC595 사용함수

     digitalWrite(ST_CP, LOW);
     shiftOut(DS, SH_CP, LSBFIRST, FORWARD);
     digitalWrite(ST_CP, HIGH);

이렇게 1byte씩 데이터를 보낼 수 있습니다. 'OB' 기호가 있는 값은 byte값을 나타내는데 8bit이니깐 1byte 값이 되고 1byte을 shiftOut()함수를 통해서 74HC595 칩에 전송하게 됩니다. 전송된 값에 의해서 74HC595 칩의 Q0~Q7핀으로 FORWARD의 출력이 발생합니다.

그러면, FORWARD, BACKWARD, RELEASE 명령을 내려 볼까요.

digitalWrite(ST_CP, LOW);
shiftOut(DS, SH_CP, LSBFIRST, FORWARD);
digitalWrite(ST_CP, HIGH);
delay(2000);

digitalWrite(ST_CP, LOW);
shiftOut(DS, SH_CP, LSBFIRST, BACKWARD);
digitalWrite(ST_CP, HIGH);
delay(2000);

digitalWrite(ST_CP, LOW);
shiftOut(DS, SH_CP, LSBFIRST, RELEASE);
digitalWrite(ST_CP, HIGH);
delay(2000);

2초 단위로 FORWARD, BACKWARD, RELEASE 명령이 내려지게 됩니다. 2초단위로 전진, 후진, 정지 이렇게 DC Motor 4개가 동시에 회전하게 됩니다. 지난 시간에 비해 코딩이 더 간소화 되었습니다.

종합해보면, 2초 단위로 전진, 정지, 후진, 정지 반복수행

#define FORWARD  0B10011001
#define BACKWARD 0B01100110
#define RELEASE  0B00000000

//Pin connected to ST_CP of 74HC595
const int ST_CP = 10;
//Pin connected to SH_CP of 74HC595
const int SH_CP = 11;
////Pin connected to DS of 74HC595
const int DS = 9;

void setup(){
   pinMode(ST_CP, OUTPUT);
   pinMode(SH_CP, OUTPUT);
   pinMode(DS, OUTPUT);  
}

void loop(){
     digitalWrite(ST_CP, LOW);
     shiftOut(DS, SH_CP, LSBFIRST, FORWARD);
     digitalWrite(ST_CP, HIGH);
     delay(2000);

     digitalWrite(ST_CP, LOW);
     shiftOut(DS, SH_CP, LSBFIRST, RELEASE);
     digitalWrite(ST_CP, HIGH);
     delay(2000);
      
     digitalWrite(ST_CP, LOW);
     shiftOut(DS, SH_CP, LSBFIRST, BACKWARD);
     digitalWrite(ST_CP, HIGH);
     delay(2000);
  
     digitalWrite(ST_CP, LOW);
     shiftOut(DS, SH_CP, LSBFIRST, RELEASE);
     digitalWrite(ST_CP, HIGH);
     delay(2000);
}

4. 결과


결과는 2초 전진, 2초 정지, 2초 후진, 2초 정지 결과 입니다.


마무리


지난시간에 비해 회로도는 더 복잡해졌지만 코딩은 더 간소화 되었습니다. 칩에 데이터를 한번에 전송하고 그 데이터를 기준으로 74HC595에서 2개의 L293D 칩에 입력신호를 보내 DC Motor를 제어 했습니다. 74HC595칩을 사용할 줄 알면은 쉽게 L293D 칩을 제어를 할 수 있습니다. '0B10011001'라는 이 데이터 값을 통해 FORWARD(전진) 쉽게 표현할 수 있게 되었습니다.

     digitalWrite(ST_CP, LOW);
     shiftOut(DS, SH_CP, LSBFIRST, 모터신호값);
     digitalWrite(ST_CP, HIGH);

이 세줄로 DC Motor를 마음대로 제어할 수 있게 되었습니다. 하지만, 실제로 이것을 적용하려면 위 회로도를 그대로 적용하시면 안됩니다. 그 이유는 위에서 설명했듯이 불안전한 회로도입니다. 단지, DC Motor를 제어하는 원리를 이해하기 위해 표현한 회로도입니다. 4개의 입력값만 있으면 L293D 칩을 제어할 수 있으니깐 L293D 칩을 두개 제어하려면 8개의 입력값을 제어할 수 있으면 되니 떠오른 것이 바로 74HC595칩이였고 이 칩을 기반으로 간단히 표현한 것 뿐입니다.

초보분들은 대충 원리만 이해하고 넘어가시기 바랍니다. 사실 편하게 DC Motor 쉴드를 사용하는게 편하니깐요. 처음부터서 너무 완벽하게 전부 다 하실 필요는 없습니다. 모르는 것은 이미 구현된 것을 가져다가 사용하시면 됩니다. Motor를 안정적으로 제어하기 위해서는 DC Motor 쉴드를 구매하셔서 쉽게 제어하시기 바랍니다.

이렇게 해서 DC Motor 제어를 간단히 살펴보았습니다.


댓글()