아두이노로 LED matrix 제어하기 #6 : 스크롤링(Shift) effect 1

2018. 2. 5. 16:35

Arduino/Display

Arduino LedControl Library : 애니메이션 함수 만들기

이전 글에서 LedControl Library 기본 함수를 이용해서 숫자와 문자(영문자)를 출력하는 함수를 작성하였습니다. 이제 이 함수들을 이용해서 shift, rotation 애니메이션 함수를 만들어 보겠습니다.

우선, 문자열에 흐름 효과를 줄 시프트(shift) 함수를 먼저 구성하겠습니다. 왼쪽이나 오른쪽 방향으로, 한 모듈의 내용이 다음 모듈로 옮겨지도록 모듈내에서 가로, 세로 방향으로 한 줄씩 이동하는 기능도 나중에 추가하도록 하겠습니다.

출력 화면을 구성하기 위한 작업대, 버퍼(Buffer) 만들기

이전에 작성한 예제의 문제점

우선, 이전 글에서 작성한 마지막 프로그램을 기본 소스로 사용하여 수정해 가겠습니다.

#include "LedControl.h"
LedControl lc = LedControl(12,11,10,3);
byte chars[][8] = {
{
  B00000000,
  B00000000,
  B00000000,
  B00000000,
  B00000000,
  B00000000,
  B00000000,
  B00000000
},{
  B00111000,
  B01000100,
  B01000100,
  B01000100,
  B01000100,
  B01000100,
  B01000100,
  B00111000
},{
  B00010000,
  B00110000,
  B00010000,
  B00010000,
  B00010000,
  B00010000,
  B00010000,
  B00111000
},{
  B00111000,
  B01000100,
  B00000100,
  B00000100,
  B00001000,
  B00010000,
  B00100000,
  B01111100
},{
  B00111000,
  B01000100,
  B00000100,
  B00011000,
  B00000100,
  B00000100,
  B01000100,
  B00111000
},{
  B00000100,
  B00001100,
  B00010100,
  B00100100,
  B01000100,
  B01111100,
  B00000100,
  B00000100
},{
  B01111100,
  B01000000,
  B01000000,
  B01111000,
  B00000100,
  B00000100,
  B01000100,
  B00111000
},{
  B00111000,
  B01000100,
  B01000000,
  B01111000,
  B01000100,
  B01000100,
  B01000100,
  B00111000
},{
  B01111100,
  B00000100,
  B00000100,
  B00001000,
  B00010000,
  B00100000,
  B00100000,
  B00100000
},{
  B00111000,
  B01000100,
  B01000100,
  B00111000,
  B01000100,
  B01000100,
  B01000100,
  B00111000
},{
  B00111000,
  B01000100,
  B01000100,
  B01000100,
  B00111100,
  B00000100,
  B01000100,
  B00111000
},{
  B00000000,
  B00111100,
  B01100110,
  B01100110,
  B01111110,
  B01100110,
  B01100110,
  B01100110
},{
  B00000000,
  B01111100,
  B01100110,
  B01100110,
  B01111100,
  B01100110,
  B01100110,
  B01111100
},{
  B00000000,
  B00111100,
  B01100110,
  B01100000,
  B01100000,
  B01100000,
  B01100110,
  B00111100
},{
  B00000000,
  B01111100,
  B01100110,
  B01100110,
  B01100110,
  B01100110,
  B01100110,
  B01111100
},{
  B00000000,
  B01111110,
  B01100000,
  B01100000,
  B01111100,
  B01100000,
  B01100000,
  B01111110
},{
  B00000000,
  B01111110,
  B01100000,
  B01100000,
  B01111100,
  B01100000,
  B01100000,
  B01100000
},{
  B00000000,
  B00111100,
  B01100110,
  B01100000,
  B01100000,
  B01101110,
  B01100110,
  B00111100
},{
  B00000000,
  B01100110,
  B01100110,
  B01100110,
  B01111110,
  B01100110,
  B01100110,
  B01100110
},{
  B00000000,
  B00111100,
  B00011000,
  B00011000,
  B00011000,
  B00011000,
  B00011000,
  B00111100
},{
  B00000000,
  B00011110,
  B00001100,
  B00001100,
  B00001100,
  B01101100,
  B01101100,
  B00111000
},{
  B00000000,
  B01100110,
  B01101100,
  B01111000,
  B01110000,
  B01111000,
  B01101100,
  B01100110
},{
  B00000000,
  B01100000,
  B01100000,
  B01100000,
  B01100000,
  B01100000,
  B01100000,
  B01111110
},{
  B00000000,
  B01100011,
  B01110111,
  B01111111,
  B01101011,
  B01100011,
  B01100011,
  B01100011
},{
  B00000000,
  B01100011,
  B01110011,
  B01111011,
  B01101111,
  B01100111,
  B01100011,
  B01100011
},{
  B00000000,
  B00111100,
  B01100110,
  B01100110,
  B01100110,
  B01100110,
  B01100110,
  B00111100
},{
  B00000000,
  B01111100,
  B01100110,
  B01100110,
  B01100110,
  B01111100,
  B01100000,
  B01100000
},{
  B00000000,
  B00111100,
  B01100110,
  B01100110,
  B01100110,
  B01101110,
  B00111100,
  B00000110
},{
  B00000000,
  B01111100,
  B01100110,
  B01100110,
  B01111100,
  B01111000,
  B01101100,
  B01100110
},{
  B00000000,
  B00111100,
  B01100110,
  B01100000,
  B00111100,
  B00000110,
  B01100110,
  B00111100
},{
  B00000000,
  B01111110,
  B01011010,
  B00011000,
  B00011000,
  B00011000,
  B00011000,
  B00011000
},{
  B00000000,
  B01100110,
  B01100110,
  B01100110,
  B01100110,
  B01100110,
  B01100110,
  B00111110
},{
  B00000000,
  B01100110,
  B01100110,
  B01100110,
  B01100110,
  B01100110,
  B00111100,
  B00011000
},{
  B00000000,
  B01100011,
  B01100011,
  B01100011,
  B01101011,
  B01111111,
  B01110111,
  B01100011
},{
  B00000000,
  B01100011,
  B01100011,
  B00110110,
  B00011100,
  B00110110,
  B01100011,
  B01100011
},{
  B00000000,
  B01100110,
  B01100110,
  B01100110,
  B00111100,
  B00011000,
  B00011000,
  B00011000
},{
  B00000000,
  B01111110,
  B00000110,
  B00001100,
  B00011000,
  B00110000,
  B01100000,
  B01111110
},{
  B00000000,
  B00000000,
  B00000000,
  B00111100,
  B00000110,
  B00111110,
  B01100110,
  B00111110
},{
  B00000000,
  B01100000,
  B01100000,
  B01100000,
  B01111100,
  B01100110,
  B01100110,
  B01111100
},{
  B00000000,
  B00000000,
  B00000000,
  B00111100,
  B01100110,
  B01100000,
  B01100110,
  B00111100
},{
  B00000000,
  B00000110,
  B00000110,
  B00000110,
  B00111110,
  B01100110,
  B01100110,
  B00111110
},{
  B00000000,
  B00000000,
  B00000000,
  B00111100,
  B01100110,
  B01111110,
  B01100000,
  B00111100
},{
  B00000000,
  B00011100,
  B00110110,
  B00110000,
  B00110000,
  B01111100,
  B00110000,
  B00110000
},{
  B00000000,
  B00000000,
  B00111110,
  B01100110,
  B01100110,
  B00111110,
  B00000110,
  B00111100
},{
  B00000000,
  B01100000,
  B01100000,
  B01100000,
  B01111100,
  B01100110,
  B01100110,
  B01100110
},{
  B00000000,
  B00000000,
  B00011000,
  B00000000,
  B00011000,
  B00011000,
  B00011000,
  B00111100
},{
  B00000000,
  B00001100,
  B00000000,
  B00001100,
  B00001100,
  B01101100,
  B01101100,
  B00111000
},{
  B00000000,
  B01100000,
  B01100000,
  B01100110,
  B01101100,
  B01111000,
  B01101100,
  B01100110
},{
  B00000000,
  B00011000,
  B00011000,
  B00011000,
  B00011000,
  B00011000,
  B00011000,
  B00011000
},{
  B00000000,
  B00000000,
  B00000000,
  B01100011,
  B01110111,
  B01111111,
  B01101011,
  B01101011
},{
  B00000000,
  B00000000,
  B00000000,
  B01111100,
  B01111110,
  B01100110,
  B01100110,
  B01100110
},{
  B00000000,
  B00000000,
  B00000000,
  B00111100,
  B01100110,
  B01100110,
  B01100110,
  B00111100
},{
  B00000000,
  B00000000,
  B01111100,
  B01100110,
  B01100110,
  B01111100,
  B01100000,
  B01100000
},{
  B00000000,
  B00000000,
  B00111100,
  B01101100,
  B01101100,
  B00111100,
  B00001101,
  B00001111
},{
  B00000000,
  B00000000,
  B00000000,
  B01111100,
  B01100110,
  B01100110,
  B01100000,
  B01100000
},{
  B00000000,
  B00000000,
  B00000000,
  B00111110,
  B01000000,
  B00111100,
  B00000010,
  B01111100
},{
  B00000000,
  B00000000,
  B00011000,
  B00011000,
  B01111110,
  B00011000,
  B00011000,
  B00011000
},{
  B00000000,
  B00000000,
  B00000000,
  B01100110,
  B01100110,
  B01100110,
  B01100110,
  B00111110
},{
  B00000000,
  B00000000,
  B00000000,
  B00000000,
  B01100110,
  B01100110,
  B00111100,
  B00011000
},{
  B00000000,
  B00000000,
  B00000000,
  B01100011,
  B01101011,
  B01101011,
  B01101011,
  B00111110
},{
  B00000000,
  B00000000,
  B00000000,
  B01100110,
  B00111100,
  B00011000,
  B00111100,
  B01100110
},{
  B00000000,
  B00000000,
  B00000000,
  B01100110,
  B01100110,
  B00111110,
  B00000110,
  B00111100
},{
  B00000000,
  B00000000,
  B00000000,
  B00111100,
  B00001100,
  B00011000,
  B00110000,
  B00111100
}
};
void setup() { 
  lc.shutdown(0, false);
  lc.shutdown(1, false);
  lc.shutdown(2, false); 
  lc.setIntensity(0,2);
  lc.setIntensity(1,2);
  lc.setIntensity(2,2);
  lc.clearDisplay(0);
  lc.clearDisplay(1);
  lc.clearDisplay(2);
}
void loop() { 
  setChars(lc, 0, 'a');
  setChars(lc, 1, 'A');
  setChars(lc, 2, '3');
}
void setChars(LedControl ledctrl, int addr, char value) {
  int maxDevice = ledctrl.getDeviceCount();
  if (addr < 0 || addr >= maxDevice) {
    return;
  }
  int i;
  int c = -1;
  if (value >= 'A' && value <= 'Z') {
    c = value - 'A' + 11;
  } else if (value >= 'a' && value <= 'z') {
    c = value - 'a' + 37;
  } else if (value >= '0' && value <= '9') {
    c = value - '0' + 1;
  }
  if (c != -1) {
    for (i = 0; i < 8; i++) {
      ledctrl.setRow(addr, i, chars[c][i]);
    }
  }
}

위 소스 코드의 585 ~ 587 라인은 실제로 LED 모듈에 문자를 출력하는 함수로 loop() 함수내에 위치하고 있으며, 총 3개의 LED 모듈에 각각 a, A, 3을 출력하는 간단한 코드입니다.

이제, 위 출력 결과가 왼쪽으로 시프트(Shift)되도록 코드를 추가해야 한다면, 첫 번째 모듈의 a는 사라지고 두 번째 모듈의 A가 첫 번째 모듈로 와야 하며 세 번째 모듈의 3도 두 번째 모듈로 옮겨져야 합니다. LED 모듈 자체에 이런 기능이 있으면 좋겠지만, 자신이 어떤 모양을 출력하고 있는 지(64개 LED의 on/off bit 값)를 알지 못하기에 모듈내에서 처리할 수 있는 방법은 없을 듯 합니다.

따라서, 프로그램 코드내에서 출력할 데이터를 가공하여 제공하도록 처리해야 합니다.

void loop() { 
  setChars(lc, 2, 'a');
  //
  delay(1000);
  setChars(lc, 1, 'a');
  setChars(lc, 2, 'A');
  //
  delay(1000);
  setChars(lc, 0, 'a');
  setChars(lc, 1, 'A');
  setChars(lc, 2, '3');
  //
  delay(1000);
  setChars(lc, 0, 'A');
  setChars(lc, 1, '3');
  lc.clearDisplay(2);
  //
  delay(1000);
  setChars(lc, 0, '3');
  lc.clearDisplay(1);
  delay(1000);
  lc.clearDisplay(0);
  //
  delay(1000);
}

설명을 위해서, 먼저 단순하게 구현해 보았습니다. 왼쪽 시프트가 이루어지는 상황을 프로그래머가 헤아려서 순차적으로 코딩한 것이고, 출력할 글자 수가 늘어날수록 비효율적인 방법입니다. 위 예제는 우선 두 가지 문제점을 가지고 있습니다.

첫 번째 문제는 clearDisplay() 함수를 사용해야 하는 부분입니다. 위 예제의 출력 함수 setChars()는 빈 화면, 즉 모든 LED를 off하는 기능이 없습니다. 이 문제는, 문자 패턴을 가지고 있는 chars[][] 배열의 첫 번째 항목이 모든 bit가 0으로 채워져 있는 빈 화면 값이기 때문에, 이 항목만 출력할 수 있도록 수정하면 해결할 수 있습니다.

두 번째 문제는 setChars() 함수가 원하는 데이터를 셋팅하고 모듈에 출력하는 기능을 동시에 처리하는 부분에 있습니다. 위 예제는 출력할 데이터가 세 글자이지만, 출력할 글자 수가 더 늘어나면 복잡해지게 됩니다. 이는 출력할 데이터를 따로 저장하지 않고, 데이터 가공과 출력을 한 함수에서 모두 처리되도록 했기 때문입니다.

먼저 이전 예제를 조금 수정하겠습니다.

프로그램 소스를 다루기 편하도록 몇 가지를 수정하겠습니다.

void setup() {
  ledSetup(); // LED모듈 초기화
}
void loop() {
  // loop() 함수
}
// LED모듈 초기화 함수
void ledSetup() {
  lc.shutdown(0, false);
  lc.shutdown(1, false);
  lc.shutdown(2, false);
  //
  lc.setIntensity(0,2);
  lc.setIntensity(1,2);
  lc.setIntensity(2,2);
  //
  lc.clearDisplay(0);
  lc.clearDisplay(1);
  lc.clearDisplay(2);
}

우선 setup() 함수를 조금 수정했습니다. 처음 시작할 때, LED 모듈을 초기화하는 몇 가지 설정 코드들을 ledSetup() 함수내에 하나로 묶어서 넣었습니다. 당연히, 기능상으론 동일하고 단순히 setup() 함수를 간단하고 보기 좋게 하기 위함입니다.

#include "LedControl.h"
//
LedControl lc = LedControl(12,11,10,3);
// 숫자 패턴
byte digits[10][8] = {};
// 영문자
byte chars[52][8] = {};
// 기호
byte symbols[][8] = {};

그 다음, 출력 패턴을 담고 있는 배열을 그 종류에 따라 좀더 세분화시켰습니다. 숫자 패턴을 위한 digits[10][8] 배열은 첫 번째 첨자가 10 이고 0부터 9까지의 패턴을 차례대로 저장합니다. chars[52][8] 배열은 알파벳 소문자, 대문자 총 52개의 패턴을 저장하고, 기호를 담게 될 symbol[][8] 배열은, 몇 개를 사용할 지 정해진 것은 아니라서 첫 번째 첨자를 생략했습니다. 단, 기호 패턴의 첫 번째인 symbol[0][8] 항목은 빈 화면을 쉽게 출력할 수 있도록 모든 비트를 0으로 채우겠습니다.

byte digits[10][8] = {
  {
  B00111000,
  B01000100,
  B01000100,
  B01000100,
  B01000100,
  B01000100,
  B01000100,
  B00111000
},{
  B00010000,
  B00110000,
  B00010000,
  B00010000,
  B00010000,
  B00010000,
  B00010000,
  B00111000
},{
  B00111000,
  B01000100,
  B00000100,
  B00000100,
  B00001000,
  B00010000,
  B00100000,
  B01111100
},{
  B00111000,
  B01000100,
  B00000100,
  B00011000,
  B00000100,
  B00000100,
  B01000100,
  B00111000
},{
  B00000100,
  B00001100,
  B00010100,
  B00100100,
  B01000100,
  B01111100,
  B00000100,
  B00000100
},{
  B01111100,
  B01000000,
  B01000000,
  B01111000,
  B00000100,
  B00000100,
  B01000100,
  B00111000
},{
  B00111000,
  B01000100,
  B01000000,
  B01111000,
  B01000100,
  B01000100,
  B01000100,
  B00111000
},{
  B01111100,
  B00000100,
  B00000100,
  B00001000,
  B00010000,
  B00100000,
  B00100000,
  B00100000
},{
  B00111000,
  B01000100,
  B01000100,
  B00111000,
  B01000100,
  B01000100,
  B01000100,
  B00111000
},{
  B00111000,
  B01000100,
  B01000100,
  B01000100,
  B00111100,
  B00000100,
  B01000100,
  B00111000
}};
// 영문자
byte chars[52][8] = {
{
  B00000000,
  B00111100,
  B01100110,
  B01100110,
  B01111110,
  B01100110,
  B01100110,
  B01100110
},{
  B00000000,
  B01111100,
  B01100110,
  B01100110,
  B01111100,
  B01100110,
  B01100110,
  B01111100
},{
  B00000000,
  B00111100,
  B01100110,
  B01100000,
  B01100000,
  B01100000,
  B01100110,
  B00111100
},{
  B00000000,
  B01111100,
  B01100110,
  B01100110,
  B01100110,
  B01100110,
  B01100110,
  B01111100
},{
  B00000000,
  B01111110,
  B01100000,
  B01100000,
  B01111100,
  B01100000,
  B01100000,
  B01111110
},{
  B00000000,
  B01111110,
  B01100000,
  B01100000,
  B01111100,
  B01100000,
  B01100000,
  B01100000
},{
  B00000000,
  B00111100,
  B01100110,
  B01100000,
  B01100000,
  B01101110,
  B01100110,
  B00111100
},{
  B00000000,
  B01100110,
  B01100110,
  B01100110,
  B01111110,
  B01100110,
  B01100110,
  B01100110
},{
  B00000000,
  B00111100,
  B00011000,
  B00011000,
  B00011000,
  B00011000,
  B00011000,
  B00111100
},{
  B00000000,
  B00011110,
  B00001100,
  B00001100,
  B00001100,
  B01101100,
  B01101100,
  B00111000
},{
  B00000000,
  B01100110,
  B01101100,
  B01111000,
  B01110000,
  B01111000,
  B01101100,
  B01100110
},{
  B00000000,
  B01100000,
  B01100000,
  B01100000,
  B01100000,
  B01100000,
  B01100000,
  B01111110
},{
  B00000000,
  B01100011,
  B01110111,
  B01111111,
  B01101011,
  B01100011,
  B01100011,
  B01100011
},{
  B00000000,
  B01100011,
  B01110011,
  B01111011,
  B01101111,
  B01100111,
  B01100011,
  B01100011
},{
  B00000000,
  B00111100,
  B01100110,
  B01100110,
  B01100110,
  B01100110,
  B01100110,
  B00111100
},{
  B00000000,
  B01111100,
  B01100110,
  B01100110,
  B01100110,
  B01111100,
  B01100000,
  B01100000
},{
  B00000000,
  B00111100,
  B01100110,
  B01100110,
  B01100110,
  B01101110,
  B00111100,
  B00000110
},{
  B00000000,
  B01111100,
  B01100110,
  B01100110,
  B01111100,
  B01111000,
  B01101100,
  B01100110
},{
  B00000000,
  B00111100,
  B01100110,
  B01100000,
  B00111100,
  B00000110,
  B01100110,
  B00111100
},{
  B00000000,
  B01111110,
  B01011010,
  B00011000,
  B00011000,
  B00011000,
  B00011000,
  B00011000
},{
  B00000000,
  B01100110,
  B01100110,
  B01100110,
  B01100110,
  B01100110,
  B01100110,
  B00111110
},{
  B00000000,
  B01100110,
  B01100110,
  B01100110,
  B01100110,
  B01100110,
  B00111100,
  B00011000
},{
  B00000000,
  B01100011,
  B01100011,
  B01100011,
  B01101011,
  B01111111,
  B01110111,
  B01100011
},{
  B00000000,
  B01100011,
  B01100011,
  B00110110,
  B00011100,
  B00110110,
  B01100011,
  B01100011
},{
  B00000000,
  B01100110,
  B01100110,
  B01100110,
  B00111100,
  B00011000,
  B00011000,
  B00011000
},{
  B00000000,
  B01111110,
  B00000110,
  B00001100,
  B00011000,
  B00110000,
  B01100000,
  B01111110
},{
  B00000000,
  B00000000,
  B00000000,
  B00111100,
  B00000110,
  B00111110,
  B01100110,
  B00111110
},{
  B00000000,
  B01100000,
  B01100000,
  B01100000,
  B01111100,
  B01100110,
  B01100110,
  B01111100
},{
  B00000000,
  B00000000,
  B00000000,
  B00111100,
  B01100110,
  B01100000,
  B01100110,
  B00111100
},{
  B00000000,
  B00000110,
  B00000110,
  B00000110,
  B00111110,
  B01100110,
  B01100110,
  B00111110
},{
  B00000000,
  B00000000,
  B00000000,
  B00111100,
  B01100110,
  B01111110,
  B01100000,
  B00111100
},{
  B00000000,
  B00011100,
  B00110110,
  B00110000,
  B00110000,
  B01111100,
  B00110000,
  B00110000
},{
  B00000000,
  B00000000,
  B00111110,
  B01100110,
  B01100110,
  B00111110,
  B00000110,
  B00111100
},{
  B00000000,
  B01100000,
  B01100000,
  B01100000,
  B01111100,
  B01100110,
  B01100110,
  B01100110
},{
  B00000000,
  B00000000,
  B00011000,
  B00000000,
  B00011000,
  B00011000,
  B00011000,
  B00111100
},{
  B00000000,
  B00001100,
  B00000000,
  B00001100,
  B00001100,
  B01101100,
  B01101100,
  B00111000
},{
  B00000000,
  B01100000,
  B01100000,
  B01100110,
  B01101100,
  B01111000,
  B01101100,
  B01100110
},{
  B00000000,
  B00011000,
  B00011000,
  B00011000,
  B00011000,
  B00011000,
  B00011000,
  B00011000
},{
  B00000000,
  B00000000,
  B00000000,
  B01100011,
  B01110111,
  B01111111,
  B01101011,
  B01101011
},{
  B00000000,
  B00000000,
  B00000000,
  B01111100,
  B01111110,
  B01100110,
  B01100110,
  B01100110
},{
  B00000000,
  B00000000,
  B00000000,
  B00111100,
  B01100110,
  B01100110,
  B01100110,
  B00111100
},{
  B00000000,
  B00000000,
  B01111100,
  B01100110,
  B01100110,
  B01111100,
  B01100000,
  B01100000
},{
  B00000000,
  B00000000,
  B00111100,
  B01101100,
  B01101100,
  B00111100,
  B00001101,
  B00001111
},{
  B00000000,
  B00000000,
  B00000000,
  B01111100,
  B01100110,
  B01100110,
  B01100000,
  B01100000
},{
  B00000000,
  B00000000,
  B00000000,
  B00111110,
  B01000000,
  B00111100,
  B00000010,
  B01111100
},{
  B00000000,
  B00000000,
  B00011000,
  B00011000,
  B01111110,
  B00011000,
  B00011000,
  B00011000
},{
  B00000000,
  B00000000,
  B00000000,
  B01100110,
  B01100110,
  B01100110,
  B01100110,
  B00111110
},{
  B00000000,
  B00000000,
  B00000000,
  B00000000,
  B01100110,
  B01100110,
  B00111100,
  B00011000
},{
  B00000000,
  B00000000,
  B00000000,
  B01100011,
  B01101011,
  B01101011,
  B01101011,
  B00111110
},{
  B00000000,
  B00000000,
  B00000000,
  B01100110,
  B00111100,
  B00011000,
  B00111100,
  B01100110
},{
  B00000000,
  B00000000,
  B00000000,
  B01100110,
  B01100110,
  B00111110,
  B00000110,
  B00111100
},{
  B00000000,
  B00000000,
  B00000000,
  B00111100,
  B00001100,
  B00011000,
  B00110000,
  B00111100
}};
// 기호
byte symbols[][8] = {
{
  B00000000,
  B00000000,
  B00000000,
  B00000000,
  B00000000,
  B00000000,
  B00000000,
  B00000000
},
{
  B00000000,
  B00011000,
  B00111100,
  B00111100,
  B00011000,
  B00011000,
  B00000000,
  B00011000
},{
  B00000000,
  B00111100,
  B01100110,
  B00000110,
  B00011100,
  B00011000,
  B00000000,
  B00011000
}};

위와 같이 초기화도 해주었습니다. 심볼은 빈 화면과 느낌표, 물음표만 포함시켰습니다.

버퍼로 사용할 배열 선언

#include "LedControl.h"
//
LedControl lc = LedControl(12,11,10,3);
//
byte buffers[3][8];
//
byte chars[][8] = {

위 코드의 5번 라인처럼 버퍼 변수를 선언하였습니다. 패턴을 저장하는 chars[][] 변수 등과 마찬가지로 byte type 2차원 배열로 선언하였고, LED 모듈의 개수가 3개이므로 배열 첫 번째 첨자는 3으로 지정했습니다. 앞으로 출력 데이터는 buffers 배열을 작업 공간으로 삼고 처리합니다.

void setup() {
  ledSetup(); // LED모듈 초기화
  // buffers 초기화
  for (int i = 0; i < 3; i++) {
    for (int j = 0; j < 8; j++) {
      buffers[i][j] = B00000000;
    }
  }
}

buffers[][] 배열을 초기화하는 코드입니다. 바깥쪽 for문이 첫 번째 모듈부터 세 번째 모듈까지 반복해주고, 안쪽 for문은 각 모듈의 첫 번째 행부터 마지막 여덟 번째 행까지 반복해 주면서 모든 비트를 0으로 셋팅합니다.

memcpy() 함수를 이용한 배열 데이터의 할당

위 초기화 코드 memcpy() 함수를 이용하여 좀 더 간단하게 수정할 수 있습니다. 우선, 아래 코드를 먼저 보시면,

  // buffers 초기화
  for (int i = 0; i < 3; i++) {
    for (int j = 0; j < 8; j++) {
      buffers[i][j] = symbols[0][j];
    }
  }

buffers[][] 배열을 초기화하기 위해 할당하는 값을 변경하였습니다. 원래는 byte값 B00000000 였죠! symbols[][] 배열은 기호 패턴을 담기 위해 선언한 배열이고, 배열 첫 번째 항목 symbols[0][]은 모든 bit가 0으로 채워진 빈 화면 출력을 위한 패턴입니다. 이 패턴의 0번 행부터 7번행까지의 값을 차례대로 같은 행의 buffers[i][]에 할당함으로써 초기화를 수행하는 방식입니다.

그런데, 구조가 같은 배열 사이의 데이터 할당은 memcpy() 함수를 이용하면 편합니다.

  // buffers 초기화
  for (int i = 0; i < 3; i++) {
    memcpy(&buffers[i], &symbols[0], sizeof(symbols[0]));
  }

위 코드도 초기화 기능은 동일하지만, memcpy() 함수를 이용해서 좀더 간단해졌습니다. 배열 항목을 한 번에 복사하기 때문에 두 번째 for문이 필요 없게 됩니다.

memcpy() 함수는 이름처럼 메모리의 특정 영역의 데이터를 다른 영역으로 그대로 복사해 줍니다. 첫 번째 인수(dest)와 두 번째 인수(src)는 목적지 주소와 원본 주소이며 포인터 타입이기 때문에 변수명에 &(ampersand)를 붙여주었습니다. 마지막 인수(size)는 복사할 크기입니다. 자동으로 계산해 주지 않기 때문에 정확한 크기를 제공해야 하는데, sizeof() 함수를 이용해 원본 데이터의 크기를 구해서 인수로 주었습니다.

앞으로의 코딩이 배열간 데이터 교환이 많기 때문에, memcpy() 함수를 이용하는 편이 훨씬 좋습니다.

버퍼의 내용을 LED에 출력하는 함수

이제, LED 모듈에 실제로 출력하는 함수를 작성하겠습니다. 출력할 데이터를 처리하는 부분과 실제로 LED로 출력하는 부분을 나눠서 코딩하기 때문에 간단하게 작성할 수 있습니다.

void loop() { 
  buffersOut(); // LED 출력
}
// buffers를 LED 모듈에 출력하는 함수
void buffersOut() {
  for (int i = 0; i < 3; i++) {
    for (int j = 0; j < 8; j++) {
      lc.setRow(i, j, buffers[i][j]);
    }
  }
  delay(1000);
}

2번 라인이 loop() 함수내에서 출력 함수를 호출하는 부분이고, 5번 라인부터 출력 함수 buffersOut()의 정의입니다.

바깥 쪽 for문은 첫 번째 모듈부터 세 번째 모듈까지 반복하고, 안쪽 for문은 각 모듈의 첫 번째 행부터 마지막 행까지 setRow() 함수를 이용해서 출력을 반복합니다. 함수 마지막에 delay(1000) 함수를 이용해 1초간 대기한 수 실행을 끝냅니다.

우선, 여기까지의 코드를 아두이노에 업로드하여 실행해 보겠습니다.

void loop() {
  // 출력 테스트
  for (int i = 0; i < 3; i++) {
    memcpy(&buffers[i], &chars[i], sizeof(chars[0]));
  }
  buffersOut(); // LED 출력
}

결과 확인을 위해서 위와 같이 문자 "ABC"를 버퍼에 저장했습니다. for문에 의해 변수 i 의 값이 0,1, 2로 차례로 변하게 되고, 이에 따라 buffers[0], buffers[1], buffers[2]에 같은 순서로 chars[0], chars[1], chars[2]의 값이 저장됩니다. 그에 해당 문자가 "ABC"입니다.

#include "LedControl.h"
// 버퍼
LedControl lc = LedControl(12,11,10,3);
//
byte buffers[3][8];
// 숫자 패턴
byte digits[10][8] = {
  {
  B00111000,
  B01000100,
  B01000100,
  B01000100,
  B01000100,
  B01000100,
  B01000100,
  B00111000
},{
  B00010000,
  B00110000,
  B00010000,
  B00010000,
  B00010000,
  B00010000,
  B00010000,
  B00111000
},{
  B00111000,
  B01000100,
  B00000100,
  B00000100,
  B00001000,
  B00010000,
  B00100000,
  B01111100
},{
  B00111000,
  B01000100,
  B00000100,
  B00011000,
  B00000100,
  B00000100,
  B01000100,
  B00111000
},{
  B00000100,
  B00001100,
  B00010100,
  B00100100,
  B01000100,
  B01111100,
  B00000100,
  B00000100
},{
  B01111100,
  B01000000,
  B01000000,
  B01111000,
  B00000100,
  B00000100,
  B01000100,
  B00111000
},{
  B00111000,
  B01000100,
  B01000000,
  B01111000,
  B01000100,
  B01000100,
  B01000100,
  B00111000
},{
  B01111100,
  B00000100,
  B00000100,
  B00001000,
  B00010000,
  B00100000,
  B00100000,
  B00100000
},{
  B00111000,
  B01000100,
  B01000100,
  B00111000,
  B01000100,
  B01000100,
  B01000100,
  B00111000
},{
  B00111000,
  B01000100,
  B01000100,
  B01000100,
  B00111100,
  B00000100,
  B01000100,
  B00111000
}};
// 영문자
byte chars[52][8] = {
{
  B00000000,
  B00111100,
  B01100110,
  B01100110,
  B01111110,
  B01100110,
  B01100110,
  B01100110
},{
  B00000000,
  B01111100,
  B01100110,
  B01100110,
  B01111100,
  B01100110,
  B01100110,
  B01111100
},{
  B00000000,
  B00111100,
  B01100110,
  B01100000,
  B01100000,
  B01100000,
  B01100110,
  B00111100
},{
  B00000000,
  B01111100,
  B01100110,
  B01100110,
  B01100110,
  B01100110,
  B01100110,
  B01111100
},{
  B00000000,
  B01111110,
  B01100000,
  B01100000,
  B01111100,
  B01100000,
  B01100000,
  B01111110
},{
  B00000000,
  B01111110,
  B01100000,
  B01100000,
  B01111100,
  B01100000,
  B01100000,
  B01100000
},{
  B00000000,
  B00111100,
  B01100110,
  B01100000,
  B01100000,
  B01101110,
  B01100110,
  B00111100
},{
  B00000000,
  B01100110,
  B01100110,
  B01100110,
  B01111110,
  B01100110,
  B01100110,
  B01100110
},{
  B00000000,
  B00111100,
  B00011000,
  B00011000,
  B00011000,
  B00011000,
  B00011000,
  B00111100
},{
  B00000000,
  B00011110,
  B00001100,
  B00001100,
  B00001100,
  B01101100,
  B01101100,
  B00111000
},{
  B00000000,
  B01100110,
  B01101100,
  B01111000,
  B01110000,
  B01111000,
  B01101100,
  B01100110
},{
  B00000000,
  B01100000,
  B01100000,
  B01100000,
  B01100000,
  B01100000,
  B01100000,
  B01111110
},{
  B00000000,
  B01100011,
  B01110111,
  B01111111,
  B01101011,
  B01100011,
  B01100011,
  B01100011
},{
  B00000000,
  B01100011,
  B01110011,
  B01111011,
  B01101111,
  B01100111,
  B01100011,
  B01100011
},{
  B00000000,
  B00111100,
  B01100110,
  B01100110,
  B01100110,
  B01100110,
  B01100110,
  B00111100
},{
  B00000000,
  B01111100,
  B01100110,
  B01100110,
  B01100110,
  B01111100,
  B01100000,
  B01100000
},{
  B00000000,
  B00111100,
  B01100110,
  B01100110,
  B01100110,
  B01101110,
  B00111100,
  B00000110
},{
  B00000000,
  B01111100,
  B01100110,
  B01100110,
  B01111100,
  B01111000,
  B01101100,
  B01100110
},{
  B00000000,
  B00111100,
  B01100110,
  B01100000,
  B00111100,
  B00000110,
  B01100110,
  B00111100
},{
  B00000000,
  B01111110,
  B01011010,
  B00011000,
  B00011000,
  B00011000,
  B00011000,
  B00011000
},{
  B00000000,
  B01100110,
  B01100110,
  B01100110,
  B01100110,
  B01100110,
  B01100110,
  B00111110
},{
  B00000000,
  B01100110,
  B01100110,
  B01100110,
  B01100110,
  B01100110,
  B00111100,
  B00011000
},{
  B00000000,
  B01100011,
  B01100011,
  B01100011,
  B01101011,
  B01111111,
  B01110111,
  B01100011
},{
  B00000000,
  B01100011,
  B01100011,
  B00110110,
  B00011100,
  B00110110,
  B01100011,
  B01100011
},{
  B00000000,
  B01100110,
  B01100110,
  B01100110,
  B00111100,
  B00011000,
  B00011000,
  B00011000
},{
  B00000000,
  B01111110,
  B00000110,
  B00001100,
  B00011000,
  B00110000,
  B01100000,
  B01111110
},{
  B00000000,
  B00000000,
  B00000000,
  B00111100,
  B00000110,
  B00111110,
  B01100110,
  B00111110
},{
  B00000000,
  B01100000,
  B01100000,
  B01100000,
  B01111100,
  B01100110,
  B01100110,
  B01111100
},{
  B00000000,
  B00000000,
  B00000000,
  B00111100,
  B01100110,
  B01100000,
  B01100110,
  B00111100
},{
  B00000000,
  B00000110,
  B00000110,
  B00000110,
  B00111110,
  B01100110,
  B01100110,
  B00111110
},{
  B00000000,
  B00000000,
  B00000000,
  B00111100,
  B01100110,
  B01111110,
  B01100000,
  B00111100
},{
  B00000000,
  B00011100,
  B00110110,
  B00110000,
  B00110000,
  B01111100,
  B00110000,
  B00110000
},{
  B00000000,
  B00000000,
  B00111110,
  B01100110,
  B01100110,
  B00111110,
  B00000110,
  B00111100
},{
  B00000000,
  B01100000,
  B01100000,
  B01100000,
  B01111100,
  B01100110,
  B01100110,
  B01100110
},{
  B00000000,
  B00000000,
  B00011000,
  B00000000,
  B00011000,
  B00011000,
  B00011000,
  B00111100
},{
  B00000000,
  B00001100,
  B00000000,
  B00001100,
  B00001100,
  B01101100,
  B01101100,
  B00111000
},{
  B00000000,
  B01100000,
  B01100000,
  B01100110,
  B01101100,
  B01111000,
  B01101100,
  B01100110
},{
  B00000000,
  B00011000,
  B00011000,
  B00011000,
  B00011000,
  B00011000,
  B00011000,
  B00011000
},{
  B00000000,
  B00000000,
  B00000000,
  B01100011,
  B01110111,
  B01111111,
  B01101011,
  B01101011
},{
  B00000000,
  B00000000,
  B00000000,
  B01111100,
  B01111110,
  B01100110,
  B01100110,
  B01100110
},{
  B00000000,
  B00000000,
  B00000000,
  B00111100,
  B01100110,
  B01100110,
  B01100110,
  B00111100
},{
  B00000000,
  B00000000,
  B01111100,
  B01100110,
  B01100110,
  B01111100,
  B01100000,
  B01100000
},{
  B00000000,
  B00000000,
  B00111100,
  B01101100,
  B01101100,
  B00111100,
  B00001101,
  B00001111
},{
  B00000000,
  B00000000,
  B00000000,
  B01111100,
  B01100110,
  B01100110,
  B01100000,
  B01100000
},{
  B00000000,
  B00000000,
  B00000000,
  B00111110,
  B01000000,
  B00111100,
  B00000010,
  B01111100
},{
  B00000000,
  B00000000,
  B00011000,
  B00011000,
  B01111110,
  B00011000,
  B00011000,
  B00011000
},{
  B00000000,
  B00000000,
  B00000000,
  B01100110,
  B01100110,
  B01100110,
  B01100110,
  B00111110
},{
  B00000000,
  B00000000,
  B00000000,
  B00000000,
  B01100110,
  B01100110,
  B00111100,
  B00011000
},{
  B00000000,
  B00000000,
  B00000000,
  B01100011,
  B01101011,
  B01101011,
  B01101011,
  B00111110
},{
  B00000000,
  B00000000,
  B00000000,
  B01100110,
  B00111100,
  B00011000,
  B00111100,
  B01100110
},{
  B00000000,
  B00000000,
  B00000000,
  B01100110,
  B01100110,
  B00111110,
  B00000110,
  B00111100
},{
  B00000000,
  B00000000,
  B00000000,
  B00111100,
  B00001100,
  B00011000,
  B00110000,
  B00111100
}};
// 기호
byte symbols[][8] = {
{
  B00000000,
  B00000000,
  B00000000,
  B00000000,
  B00000000,
  B00000000,
  B00000000,
  B00000000
},
{
  B00000000,
  B00011000,
  B00111100,
  B00111100,
  B00011000,
  B00011000,
  B00000000,
  B00011000
},{
  B00000000,
  B00111100,
  B01100110,
  B00000110,
  B00011100,
  B00011000,
  B00000000,
  B00011000
}};
//
void setup() {
  ledSetup(); // LED모듈 초기화
  // buffers 초기화
  for (int i = 0; i < 3; i++) {
    memcpy(&buffers[i], &symbols[0], sizeof(symbols[0]));
  }
}
void loop() {
  // 출력 테스트
  for (int i = 0; i < 3; i++) {
    memcpy(&buffers[i], &chars[i], sizeof(chars[0]));
  }
  buffersOut(); // LED 출력
}
// buffers를 LED 모듈에 출력하는 함수
void buffersOut() {
  for (int i = 0; i < 3; i++) {
    for (int j = 0; j < 8; j++) {
      lc.setRow(i, j, buffers[i][j]);
    }
  }
  delay(1000);
}
// LED모듈 초기화 함수
void ledSetup() {
  lc.shutdown(0, false);
  lc.shutdown(1, false);
  lc.shutdown(2, false);
  //
  lc.setIntensity(0,2);
  lc.setIntensity(1,2);
  lc.setIntensity(2,2);
  //
  lc.clearDisplay(0);
  lc.clearDisplay(1);
  lc.clearDisplay(2);
}

전체 소스와 결과 화면입니다. 당연히 아직은 아무런  움직임이 없고, 버퍼에 패턴을 저장하고 출력 함수로 LED에 출력하는 부분이 제대로 되고 있음은 확인할 수 있습니다.

출력 Refresh, 출력 갱신 주기

이제 까지의 소스는 출력 데이터 처리와 상관없이 항상 LED에 출력하도록 코딩되어 있습니다. 별다른 제어가 없다면 loop() 함수가 한 번 순회하는 동안 출력 함수도 매 번 실행하게 됩니다. 위와 같이 출력 데이터의 변화가 없는 소스에서는 출력을 너무 빠르게 반복하는 건 비효율적이므로 일정시간 마다 한 번씩만 출력하도록 좋을 듯 합니다.

위 코드의 출력 함수 buffersOut() 내에는 delay(1000) 함수를 이용해 1초간 정지하도록 했습니다. 이는 그냥 1초를 쉬는 것이지 "1초 마다"의 개념과는 좀 다릅니다. 1초 delay() 하는 동안 실행이 중지되기 때문에 다른 코드들도 실행되지 않습니다. delay() 후에 다시 Loop를 돌면서 다른 명령들이 실행되면, 다시 출력하기까지 1초 보다는 긴 시간 간격을 가지게 됩니다. 이 문제를 해결하도록 하겠습니다.

#include "LedControl.h"
//
LedControl lc = LedControl(12,11,10,3);
//
unsigned long refreshed = 0; // 출력 주기를 위한 변수

우선, 1초마다 LED를 갱신하는 것으로 하고 필요한 변수를 하나 선언하였습니다. 1초 마다 실행하기 위해선, 기준 시점에서 1000 밀리 초(1 초)가 지났는 지 계산하면 되는 데, 이 기준 시점을 저장할 변수를 refreshed 라는 이름으로 선언하였고, millis() 함수에서 값을 받기 위해 unsigned long type으로 지정하였습니다. millis() 함수의 리턴 타입이 unsigned long 입니다. 선언과 동시에 0으로 초기화하였습니다.

// buffers를 LED 모듈에 출력하는 함수
void buffersOut() {
  if (millis() - refreshed >= 1000 ) {  
    for (int i = 0; i < 3; i++) {
      for (int j = 0; j > 8; j++) {
        lc.setRow(i, j, buffers[i][j]);
      }
    }
    refreshed = millis();
  }
}

buffersOut() 함수에 표시된 라인을 추가하였습니다. 3번 행 if문을 보면, 현재 시간(millis())과 refreshed의 값 차이가 1000 이상이면 1초가 지났음을 의미하므로 LED에 출력하고, 아니라면 Loop를 도는 동안 아무 일도 하지 않습니다. 출력을 한 후에는 9번 행처럼 다시 현재 시간으로 초기화해줍니다. refreshed 변수는 선언하면서 0으로 초기화했기 때문에, 처음 실행시에는 거의 대부분 현재 시간이 1000 이상 클 것이므로 한 번 실행하고 시작하게 됩니다.

아직은 출력 데이터의 변화가 없으므로, 결과는 동일하게 "ABC"를 항상 출력합니다.

//
unsigned long refreshed = 0; // 출력 주기를 위한 변수
unsigned long testInterval = 0; // 테스트 출력을 위한 변수
boolean blinkMode = false; // 깜박임 모드 체크

지금까지의 코드가 제대로 작동하는 지 체크하기 위해 테스트 데이터를 준비하겠습니다. LED 출력 함수 buffersOut()와 마찬가지로 버퍼에 패턴을 저장하는 함수들도 같은 방식의 시간 체크를 통해 처리하게 되며, 이 부분은 테스트 예제에서 확인할 수 있습니다.

테스트 데이터의 처리시에도 시간 체크를 해야 하므로 위와 같이 testInterval 변수를 하나 선언하였습니다. 그리고, 0.5초마다 깜빡이도록 하기 위해 blinkMode 라는 변수도 하나 선언하였습니다.

void loop() {
  // 출력 테스트
  if (millis() - testInterval >= 500) {
    "ABC" 또는 빈 화면 출력;
  } 
  buffersOut(); // LED 출력
}

출력 데이터를 버퍼에 셋팅하는 부분은 위와 같이 구성합니다. 0.5초(500밀리초) 마다 체크하기 위해 현재 시간과의 차이를 구해서 비교합니다. buffersOut() 함수에서 refreshed 변수 사용과 동일한 방식이죠! if문 내부에서는 "ABC"와 빈 화면을 번갈아 출력하도록 코딩해야 합니다.

if (millis() - testInterval >= 500) {
    if (blinkMode) {
      for (int i = 0; i < 3; i++) {
        memcpy(&buffers[i], &symbols[0], sizeof(symbols[0]));
        blinkMode = false;
      }
    } else {
      for (int i = 0; i < 3; i++) {
        memcpy(&buffers[i], &chars[i], sizeof(chars[0]));
        blinkMode = true;
      }
    }
    testInterval = millis();
  }

blinkMode 변수를 이용하여 "ABC"와 빈 화면을 토글하여 출력합니다. blinkMode가 true이면 빈 화면을 출력한 후, 다음 번엔 "ABC"를 출력하도록 blinkMode를 false로 셋팅합니다. 반대로, blinkMode가 false면 "ABC"를 출력합니다.

그런데, 이 예제를 실행해 보면, 원하는 대로 보여지진 않습니다. "ABC"와 빈 화면이 0.5초씩 합쳐서 1초 간격으로 실행될 것 같지만, 다른 코드들의 실행 시간도 있기 때문에 1초마다 출력하는 buffersOut() 함수와 맞아 떨어지지 않습니다. 그래서, "ABC"나 빈 화면 한 쪽만 지속적으로 나오다가 가끔 바뀌는 정도만 보여 줍니다. 따라서, buffersOut() 출력 주기를 훨씬 빠르게 할 필요가 있습니다.

#include "LedControl.h"
//
LedControl lc = LedControl(12,11,10,3);
//
unsigned long refreshed = 0; // 출력 주기를 위한 변수
unsigned int refreshInterval = 50; // 출력 refresh 간격
unsigned long testInterval = 0; // 테스트 출력을 위한 변수
boolean blinkMode = false; // 깜박임 모드 체크
// 버퍼
byte buffers[3][8];
// 숫자 패턴
byte digits[10][8] = {
  {
  B00111000,
  B01000100,
  B01000100,
  B01000100,
  B01000100,
  B01000100,
  B01000100,
  B00111000
},{
  B00010000,
  B00110000,
  B00010000,
  B00010000,
  B00010000,
  B00010000,
  B00010000,
  B00111000
},{
  B00111000,
  B01000100,
  B00000100,
  B00000100,
  B00001000,
  B00010000,
  B00100000,
  B01111100
},{
  B00111000,
  B01000100,
  B00000100,
  B00011000,
  B00000100,
  B00000100,
  B01000100,
  B00111000
},{
  B00000100,
  B00001100,
  B00010100,
  B00100100,
  B01000100,
  B01111100,
  B00000100,
  B00000100
},{
  B01111100,
  B01000000,
  B01000000,
  B01111000,
  B00000100,
  B00000100,
  B01000100,
  B00111000
},{
  B00111000,
  B01000100,
  B01000000,
  B01111000,
  B01000100,
  B01000100,
  B01000100,
  B00111000
},{
  B01111100,
  B00000100,
  B00000100,
  B00001000,
  B00010000,
  B00100000,
  B00100000,
  B00100000
},{
  B00111000,
  B01000100,
  B01000100,
  B00111000,
  B01000100,
  B01000100,
  B01000100,
  B00111000
},{
  B00111000,
  B01000100,
  B01000100,
  B01000100,
  B00111100,
  B00000100,
  B01000100,
  B00111000
}};
// 영문자
byte chars[52][8] = {
{
  B00000000,
  B00111100,
  B01100110,
  B01100110,
  B01111110,
  B01100110,
  B01100110,
  B01100110
},{
  B00000000,
  B01111100,
  B01100110,
  B01100110,
  B01111100,
  B01100110,
  B01100110,
  B01111100
},{
  B00000000,
  B00111100,
  B01100110,
  B01100000,
  B01100000,
  B01100000,
  B01100110,
  B00111100
},{
  B00000000,
  B01111100,
  B01100110,
  B01100110,
  B01100110,
  B01100110,
  B01100110,
  B01111100
},{
  B00000000,
  B01111110,
  B01100000,
  B01100000,
  B01111100,
  B01100000,
  B01100000,
  B01111110
},{
  B00000000,
  B01111110,
  B01100000,
  B01100000,
  B01111100,
  B01100000,
  B01100000,
  B01100000
},{
  B00000000,
  B00111100,
  B01100110,
  B01100000,
  B01100000,
  B01101110,
  B01100110,
  B00111100
},{
  B00000000,
  B01100110,
  B01100110,
  B01100110,
  B01111110,
  B01100110,
  B01100110,
  B01100110
},{
  B00000000,
  B00111100,
  B00011000,
  B00011000,
  B00011000,
  B00011000,
  B00011000,
  B00111100
},{
  B00000000,
  B00011110,
  B00001100,
  B00001100,
  B00001100,
  B01101100,
  B01101100,
  B00111000
},{
  B00000000,
  B01100110,
  B01101100,
  B01111000,
  B01110000,
  B01111000,
  B01101100,
  B01100110
},{
  B00000000,
  B01100000,
  B01100000,
  B01100000,
  B01100000,
  B01100000,
  B01100000,
  B01111110
},{
  B00000000,
  B01100011,
  B01110111,
  B01111111,
  B01101011,
  B01100011,
  B01100011,
  B01100011
},{
  B00000000,
  B01100011,
  B01110011,
  B01111011,
  B01101111,
  B01100111,
  B01100011,
  B01100011
},{
  B00000000,
  B00111100,
  B01100110,
  B01100110,
  B01100110,
  B01100110,
  B01100110,
  B00111100
},{
  B00000000,
  B01111100,
  B01100110,
  B01100110,
  B01100110,
  B01111100,
  B01100000,
  B01100000
},{
  B00000000,
  B00111100,
  B01100110,
  B01100110,
  B01100110,
  B01101110,
  B00111100,
  B00000110
},{
  B00000000,
  B01111100,
  B01100110,
  B01100110,
  B01111100,
  B01111000,
  B01101100,
  B01100110
},{
  B00000000,
  B00111100,
  B01100110,
  B01100000,
  B00111100,
  B00000110,
  B01100110,
  B00111100
},{
  B00000000,
  B01111110,
  B01011010,
  B00011000,
  B00011000,
  B00011000,
  B00011000,
  B00011000
},{
  B00000000,
  B01100110,
  B01100110,
  B01100110,
  B01100110,
  B01100110,
  B01100110,
  B00111110
},{
  B00000000,
  B01100110,
  B01100110,
  B01100110,
  B01100110,
  B01100110,
  B00111100,
  B00011000
},{
  B00000000,
  B01100011,
  B01100011,
  B01100011,
  B01101011,
  B01111111,
  B01110111,
  B01100011
},{
  B00000000,
  B01100011,
  B01100011,
  B00110110,
  B00011100,
  B00110110,
  B01100011,
  B01100011
},{
  B00000000,
  B01100110,
  B01100110,
  B01100110,
  B00111100,
  B00011000,
  B00011000,
  B00011000
},{
  B00000000,
  B01111110,
  B00000110,
  B00001100,
  B00011000,
  B00110000,
  B01100000,
  B01111110
},{
  B00000000,
  B00000000,
  B00000000,
  B00111100,
  B00000110,
  B00111110,
  B01100110,
  B00111110
},{
  B00000000,
  B01100000,
  B01100000,
  B01100000,
  B01111100,
  B01100110,
  B01100110,
  B01111100
},{
  B00000000,
  B00000000,
  B00000000,
  B00111100,
  B01100110,
  B01100000,
  B01100110,
  B00111100
},{
  B00000000,
  B00000110,
  B00000110,
  B00000110,
  B00111110,
  B01100110,
  B01100110,
  B00111110
},{
  B00000000,
  B00000000,
  B00000000,
  B00111100,
  B01100110,
  B01111110,
  B01100000,
  B00111100
},{
  B00000000,
  B00011100,
  B00110110,
  B00110000,
  B00110000,
  B01111100,
  B00110000,
  B00110000
},{
  B00000000,
  B00000000,
  B00111110,
  B01100110,
  B01100110,
  B00111110,
  B00000110,
  B00111100
},{
  B00000000,
  B01100000,
  B01100000,
  B01100000,
  B01111100,
  B01100110,
  B01100110,
  B01100110
},{
  B00000000,
  B00000000,
  B00011000,
  B00000000,
  B00011000,
  B00011000,
  B00011000,
  B00111100
},{
  B00000000,
  B00001100,
  B00000000,
  B00001100,
  B00001100,
  B01101100,
  B01101100,
  B00111000
},{
  B00000000,
  B01100000,
  B01100000,
  B01100110,
  B01101100,
  B01111000,
  B01101100,
  B01100110
},{
  B00000000,
  B00011000,
  B00011000,
  B00011000,
  B00011000,
  B00011000,
  B00011000,
  B00011000
},{
  B00000000,
  B00000000,
  B00000000,
  B01100011,
  B01110111,
  B01111111,
  B01101011,
  B01101011
},{
  B00000000,
  B00000000,
  B00000000,
  B01111100,
  B01111110,
  B01100110,
  B01100110,
  B01100110
},{
  B00000000,
  B00000000,
  B00000000,
  B00111100,
  B01100110,
  B01100110,
  B01100110,
  B00111100
},{
  B00000000,
  B00000000,
  B01111100,
  B01100110,
  B01100110,
  B01111100,
  B01100000,
  B01100000
},{
  B00000000,
  B00000000,
  B00111100,
  B01101100,
  B01101100,
  B00111100,
  B00001101,
  B00001111
},{
  B00000000,
  B00000000,
  B00000000,
  B01111100,
  B01100110,
  B01100110,
  B01100000,
  B01100000
},{
  B00000000,
  B00000000,
  B00000000,
  B00111110,
  B01000000,
  B00111100,
  B00000010,
  B01111100
},{
  B00000000,
  B00000000,
  B00011000,
  B00011000,
  B01111110,
  B00011000,
  B00011000,
  B00011000
},{
  B00000000,
  B00000000,
  B00000000,
  B01100110,
  B01100110,
  B01100110,
  B01100110,
  B00111110
},{
  B00000000,
  B00000000,
  B00000000,
  B00000000,
  B01100110,
  B01100110,
  B00111100,
  B00011000
},{
  B00000000,
  B00000000,
  B00000000,
  B01100011,
  B01101011,
  B01101011,
  B01101011,
  B00111110
},{
  B00000000,
  B00000000,
  B00000000,
  B01100110,
  B00111100,
  B00011000,
  B00111100,
  B01100110
},{
  B00000000,
  B00000000,
  B00000000,
  B01100110,
  B01100110,
  B00111110,
  B00000110,
  B00111100
},{
  B00000000,
  B00000000,
  B00000000,
  B00111100,
  B00001100,
  B00011000,
  B00110000,
  B00111100
}};
// 기호
byte symbols[][8] = {
{
  B00000000,
  B00000000,
  B00000000,
  B00000000,
  B00000000,
  B00000000,
  B00000000,
  B00000000
},
{
  B00000000,
  B00011000,
  B00111100,
  B00111100,
  B00011000,
  B00011000,
  B00000000,
  B00011000
},{
  B00000000,
  B00111100,
  B01100110,
  B00000110,
  B00011100,
  B00011000,
  B00000000,
  B00011000
}};
//
void setup() {
  ledSetup(); // LED모듈 초기화
  // buffers 초기화
  for (int i = 0; i < 3; i++) {
    memcpy(&buffers[i], &symbols[0], sizeof(symbols[0]));
  }
}
void loop() {
  // 출력 테스트
  if (millis() - testInterval >= 500) {
    if (blinkMode) {
      for (int i = 0; i < 3; i++) {
        memcpy(&buffers[i], &symbols[0], sizeof(symbols[0]));
        blinkMode = false;
      }
    } else {
      for (int i = 0; i < 3; i++) {
        memcpy(&buffers[i], &chars[i], sizeof(chars[0]));
        blinkMode = true;
      }
    }
    testInterval = millis();
  } 
  buffersOut(); // LED 출력
}
// buffers를 LED 모듈에 출력하는 함수
void buffersOut() {
  if (millis() - refreshed >= refreshInterval ) {  
    for (int i = 0; i < 3; i++) {
      for (int j = 0; j < 8; j++) {
        lc.setRow(i, j, buffers[i][j]);
      }
    }
    refreshed = millis();
  }
}
// LED모듈 초기화 함수
void ledSetup() {
  lc.shutdown(0, false);
  lc.shutdown(1, false);
  lc.shutdown(2, false);
  //
  lc.setIntensity(0,2);
  lc.setIntensity(1,2);
  lc.setIntensity(2,2);
  //
  lc.clearDisplay(0);
  lc.clearDisplay(1);
  lc.clearDisplay(2);
}

출력 주기를 0.05초로 설정하고 실행한 화면과 전체 소스입니다. 원했던 대로 blink됨을 확인할 수 있습니다. 또, 화면 갱신 주기(refresh율)도 사용자가 변경하여 쓸 수 있도록 refreshInterval 이라는 변수로 대체해서 사용하였습니다.

이번 글은 여기에서 마무리하고, 다음 글에선 버퍼 데이터(패턴)를 처리하는 함수를 작성해보겠습니다.

Comments