[아두이노 강좌] 04. 쉬프트 레지스터를 이용한 LED제어

본 게시글에서는 아두이노의 핀 8개를 사용하지 않고도 8개의 LED를 제어하는 방법에 대해서 설명하고자 합니다.

breadboard.jpg

8개의 LED를 아두이노로 제어하려면 8개의 LED를 아두이노의 핀 8개에 직접 연결(저항을 통하여)을 하여도 되겠지만 이는 쓸수 있는 아두이노 핀의 갯수를 많이 제한하게 됩니다. 아두이노에 LED만을 연결하려고 하면 문제가 없겠지만 버튼이나, 센서, 서보 등과 같은 다른 부품을 연결하고자 하면 이는 문제가 될수 있습니다. 그래서 74HC595 parallel to serial 컨버터 칩을 사용하여 이러한 문제를 해결합니다. 이 칩은 8개의 출력을 가지고 있으며 3개의 입력 핀을 가지고 있습니다.
74HC595.jpg
이 칩을 거치면 LED를 동작시키는 것이 약간은 느려지겠지만, 여전히 아주 매우 빠르게 LED를 동작시킬 수 있습니다.

브레드보드 레이아웃

아래의 그림은 8개의 LED와 저항, 74HC595칩과 아두이노를 결선한 모습입니다.
fritzing1.jpg

결선을 쉽게 하실려면 74HC595 칩을 먼저 꼽으시는 것이 좋습니다. U짜 형태로 홈이 파져 있는 곳을 브레드보드 위쪽 방향으로 연결하십시오. 칩의 1번 핀이 U홈의 왼쪽에 있습니다.

74HC595칩의 좌측에 거의 모든 출력 핀들이 위치하고 있으므로 LED를 쉽게 연결하기 위해서 74HC595칩 좌측에 LED를 설치하여야 할 것입니다. 저항들을 연결하고 LED를 연결합니다. 저항과 LED가 제대로 연결되었는지 다시 한번 확인합니다.

LED의 긴 다리 양극쪽이 반드시 칩쪽으로 연결되어야 합니다.

점퍼를 위의 그림과 같이 연결합니다. IC칩의 8번핀은 브레드보드의 GND로 연결해야 하는 것을 잊지 마십시오.

올바르게 연결하였다면 아래에 있는 예제 스케치를 아두이노에 올려 테스트를 하여봅니다. LED가 순서대로 점등 되고 모두 점등되면 다시 꺼지게 됩니다.

74HC595 쉬프트 레지스터

코드를 설명하기 전에 74HC595 칩에 대해 간단히 살펴보겠습니다. 이 칩은 쉬프트 레지스터라고 부르는 형태의 제품입니다.

shift_register.png

쉬프트 레지스터는 1 혹은 0을 저장할 수 있는 8개의 메모리 공간을 가지고 있습니다. 이 메모리 공간에 1 혹은 0을 넣을려면 칩의 Data와 Clock 핀을 이용하여야 합니다.

클럭핀은 한번에 8개의 펄스를 받습니다. 만약 데이터핀이 high라면 1이 쉬프트 레지스터에 들어가고 그렇지 않다면 0이 들어갑니다. 8개의 모든 펄스가 수신되었으면 Latch핀을 활성화시켜 8개의 값을 Latch register에 복사합니다.

칩에는 OE(output enble) 핀이 있는데 이 핀은 출력을 활성화 하거나 비활성화 할수 있습니다. 아두이노의 PWM 핀을 이 핀에 붙여서 LED의 밝기를 조절할 수 있습니다. 이 핀은 active low이므로 GND에 연결합니다.

아두이노 코드

아두이노는 shiftOut이라는 특별한 함수를 가지고 있습니다. 이 함수는 데이터를 쉬프트 레지스터에 보내기 위해 특별히 디자인되었습니다. 아래는 전체 스케치 코드입니다.

  1. int latchPin = 5;
  2. int clockPin = 6;
  3. int dataPin = 4;
  4. byte leds = 0;
  5. void setup()
  6. {
  7. pinMode(latchPin, OUTPUT);
  8. pinMode(dataPin, OUTPUT);
  9. pinMode(clockPin, OUTPUT);
  10. }
  11. void loop()
  12. {
  13. leds = 0;
  14. updateShiftRegister();
  15. delay(500);
  16. for (int i = 0; i < 8; i++)
  17. {
  18. bitSet(leds, i);
  19. updateShiftRegister();
  20. delay(500);
  21. }
  22. }
  23. void updateShiftRegister()
  24. {
  25. digitalWrite(latchPin, LOW);
  26. shiftOut(dataPin, clockPin, LSBFIRST, leds);
  27. digitalWrite(latchPin, HIGH);
  28. }

맨 처음 할 것은 우리가 사용할 세개의 핀을 정의하는 일입니다. 이 핀들은 아두이노 디지털 출력핀으로 쉬프트레지스터의 latch, clock, data핀에 연결됩니다.

  1. int latchPin = 5;
  2. int clockPin = 6;
  3. int dataPin = 4;

다음으로 leds라는 변수가 정의됩니다. 이 변수는 8개의 LED의 on/off 패턴을 저장하기 위해 사용됩니다. byte 타입의 변수이므로 8비트에 대한 정보를 저장할 수 있어 8개의 LED에 대한 On/Off 값을 저장이 능합니다.

  1. byte leds = 0;

setup함수는 세개의 이 디지털 출력으로 사용되는 것을 알려줍니다.

  1. void setup() <span style="COLOR: rgb(72,72,76)" class="pln">
    1. {
    2. pinMode(latchPin, OUTPUT);
    3. pinMode(dataPin, OUTPUT);
    4. pinMode(clockPin, OUTPUT);
    5. }
    </span>

loop 함수시작 부분에서 leds변수에 0을 할당함으로써 모든 LED를 off시키는 비트 패턴을 할당하고 updateShiftRegister라는 함수를 호출합니다. 이 함수는 leds변수의 값을 쉬프트 레지스터에 전송하여 모든 LED를 실질적으로 off시킵니다. 이 함수에 대한 용은 나중에 시시 습니다.

loop함수는 0.5초동안 딜레이 하다가 for 문안에서 bitset함수를 이용하여 leds변수의 비트를 셋팅합니다. 그 다음에 updateShiftRegister를 호출하여 leds변수의 비트패턴을 업데이트합니다. 다시 0.5초를 기다린 후 다음 루프를 실행합니다.

  1. void loop()
  2. {
  3. leds = 0;
  4. updateShiftRegister();
  5. delay(500);
  6. for (int i = 0; i < 8; i++)
  7. {
  8. bitSet(leds, i);
  9. updateShiftRegister();
  10. delay(500);
  11. }
  12. }

updateShiftRegister 함수 내부를 살펴보면 먼저 latch 핀을 low로 만들고 아두이노의 shiftOut함수를 부릅니다. shitOut은 네개의 파라메터를 가지고 있는데 처음 두개는 Data와 Clock으로 사용되는 핀이며,

세번째 파라메터는 데이터 어느쪽부터 시작을 것인지 즉 가장 오른쪽 비트부터 시작할 인지 가장 왼쪽 비트부터 시작할 인지를 정해줍니다. 기서는 가장오른쪽 비트 즉 LSB(Least Significant Bit)부터 시작합니다.

.마지막 네번째 파라메터는 실제 데이터로 쉬프트레지스터에 쓰여질 데이터입니다.

  1. void updateShiftRegister()
  2. {
  3. digitalWrite(latchPin, LOW);
  4. shiftOut(dataPin, clockPin, LSBFIRST, leds);
  5. digitalWrite(latchPin, HIGH);
  6. }

만약에 LED를 끄고 싶으면 bitSet 함수대신 bitClear함수를 사용하여 비트를 0으로 만들수 있습니다.

밝기 제어

74HC595에는 Output Enable핀이 있습니다. 이 핀은 13번핀이며 브레드 보드상에서 그라운드에 연결되어 있습니다. 이 핀은 스위치와 같이 동작하여 출력을 enable/disable시킬수 있습니다. 이 핀은 active low이기 때문에 enable로 들기 위해서는 그라운드에 연결시켜야 합니다. 만약 5V에 연결된다면 모든 출력은 off가 됩니다.

analogWrite 함수를 이 핀에 사용하면 PWM을 이용하여 LED의 밝기를 조절할수 있습니다.

74HC595의 13번핀을 브레드보드의 그라운드 대신 아두이노의 3번 핀에 연결하여 LED밝기를 조절하여 보십시오.

아래는 밝기를 조절하는 스케치 코드입니다.

  1. int latchPin = 5;
  2. int clockPin = 6;
  3. int dataPin = 4;
  4. int outputEnablePin = 3;
  5. byte leds = 0;
  6. void setup()
  7. {
    1. pinMode(latchPin, OUTPUT);
  8. pinMode(dataPin, OUTPUT);
  9. pinMode(clockPin, OUTPUT);
  10. pinMode(outputEnablePin, OUTPUT);
  11. }
  12. void loop()
  13. {
  14. setBrightness(255);
  15. leds = 0;
  16. updateShiftRegister();
  17. delay(500);
  18. for (int i = 0; i < 8; i++)
  19. {
  20. bitSet(leds, i);
  21. updateShiftRegister();
  22. delay(500);
  23. }
  24. for (byte b = 255; b > 0; b--)
  25. {
  26. setBrightness(b);
  27. delay(50);
  28. }
  29. }
  30. void updateShiftRegister()
  31. {
  32. digitalWrite(latchPin, LOW);
  33. shiftOut(dataPin, clockPin, LSBFIRST, leds);
  34. digitalWrite(latchPin, HIGH);
  35. }
  36. void setBrightness(byte brightness) // 0 to 255
  37. {
  38. analogWrite(outputEnablePin, 255-brightness);
  39. }

Comments