Arduino LedControl Library #3
이전 글에 이어서 LedControl Library의 setRow()
함수에 대한 활용과 또 다른 출력 함수인 setColumn()
함수에 대해서 알아 보겠습니다.
setRow() with Array
byte value0 = B00000000;
byte value1 = B00100010;
byte value2 = B01110111;
byte value3 = B01111111;
byte value4 = B01111111;
byte value5 = B00111110;
byte value6 = B00011100;
byte value7 = B00001000;
lc.setRow(0, 0, value0);
lc.setRow(0, 1, value1);
lc.setRow(0, 2, value2);
lc.setRow(0, 3, value3);
lc.setRow(0, 4, value4);
lc.setRow(0, 5, value5);
lc.setRow(0, 6, value6);
lc.setRow(0, 7, value7);
이제 까지의 예제는 모든 행이 같은 값을 출력했습니다. 따라서 byte 값도 하나만 있으면 됐고, For문을 이용해서 쉽게 처리가 가능했습니다. 하지만, 위 코드와 같이 모든 행의 내용이 다를 경우에는 코드가 복잡해 집니다. 이를 해결하기 위해서 byte 데이터를 배열로 구성할 수 있습니다.
byte value[8] = { B00000000,
B00100010,
B01110111,
B01111111,
B01111111,
B00111110,
B00011100,
B00001000 };
int i;
for (i = 0; i < 8; i++) {
lc.setRow(0, i, value[i]);
}
같은 코드를 배열을 이용하여 표현하였습니다. byte type 배열 value는 크기가 8이므로 "0"부터 "7"까지의 배열 멤버를 가지게 되고, 각각 초기화로 주어진 8개의 값을 저장합니다. 또, setRow()
함수에서 정수형 변수 i 가 두 군데 사용되었기 때문에 배열 멤버를 같은 인덱스의 row에 출력합니다. 이 때문에, 배열 멤버 0번부터 7번까지 순환하는 것과 LED 모듈 0번 행부터 7번 행까지 순환하는 것이 하나의 For문으로 가능하게 되었습니다.
#include "LedControl.h"
LedControl lc = LedControl(12,11,10,3);
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() {
byte value[8] = { B00000000,
B00100010,
B01110111,
B01111111,
B01111111,
B00111110,
B00011100,
B00001000 };
int i;
for (i = 0; i < 8; i++) {
lc.setRow(0, i, value[i]);
lc.setRow(1, i, value[i]);
lc.setRow(2, i, value[i]);
}
delay(1000);
lc.clearDisplay(0);
lc.clearDisplay(1);
lc.clearDisplay(2);
delay(1000);
}
위의 배열을 이용한 예제입니다. delay()
함수와 clearDisplay()
함수를 이용해서 하트 모양이 blink 하도록 했습니다. For문에 의해 첫 번째 행부터 마지막 행까지 차례로 출력하지만 워낙 실행 속도가 빠르기 때문에 한번에 화면 전체를 출력하는 듯 보이게 됩니다.
결과 화면입니다.
#include "LedControl.h"
LedControl lc = LedControl(12,11,10,3);
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() {
byte value[8] = { B00000000,
B00100010,
B01110111,
B01111111,
B01111111,
B00111110,
B00011100,
B00001000 };
int i;
for (i = 0; i < 8; i++) {
lc.setRow(0, i, value[i]);
lc.setRow(1, i, value[i]);
lc.setRow(2, i, value[i]);
delay(500);
}
delay(500);
lc.clearDisplay(0);
lc.clearDisplay(1);
lc.clearDisplay(2);
delay(500);
}
이번 예제는 For문 안쪽에 delay()
함수를 한번 더 넣어서 한 줄씩 출력되는 것을 확인할 수 있도록 했습니다.
setColumn(), examples
LedControl 라이브러리에서 제공하는 LED matrix 출력함수 중 마지막 하나는 setColumn()
함수입니다. setRow()
함수와 동작은 동일하나 이름 그대로 행(row)이 아닌 열(column) 방향으로 byte 단위 출력을 합니다. 바로 위에서 실행한 setRow()
함수 예제에서 함수명만 setColumn()
으로 변경하면 아래와 같습니다.
#include "LedControl.h"
LedControl lc = LedControl(12,11,10,3);
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() {
byte value[8] = { B00000000,
B00100010,
B01110111,
B01111111,
B01111111,
B00111110,
B00011100,
B00001000 };
int i;
for (i = 0; i < 8; i++) {
lc.setColumn(0, i, value[i]);
lc.setColumn(1, i, value[i]);
lc.setColumn(2, i, value[i]);
delay(500);
}
delay(500);
lc.clearDisplay(0);
lc.clearDisplay(1);
lc.clearDisplay(2);
delay(500);
}
결과 화면을 보면 하트 모양이 왼쪽으로 회전하여 출력되었습니다. setRow()
함수와 결과는 같으면서 출력하는 동작만 열 방향으로 하고 싶다면 출력 데이터를 그에 맞게 제공해야 합니다.
byte value1[8] = {
B00000000,
B00011000,
B00111100,
B00111100,
B00011000,
B00011000,
B00000000,
B00011000
};
byte value2[8] = {
B00000000,
B00111100,
B01100110,
B00000110,
B00011100,
B00011000,
B00000000,
B00011000
};
추가로 예제 몇 가지 만들어 보겠습니다. 이제까지 예제들은 패턴이 하트 모양 하나였지만, 패턴이 늘어나 바로 위 코드처럼 매번 배열을 하나씩 만든다면 코딩하기가 까다롭습니다.
byte value[2][8] = {
{
B00000000,
B00011000,
B00111100,
B00111100,
B00011000,
B00011000,
B00000000,
B00011000
},
{
B00000000,
B00111100,
B01100110,
B00000110,
B00011100,
B00011000,
B00000000,
B00011000
}
};
패턴이 많아 진다면 위와 같이 2차원 배열로 데이터를 구성하는 것이 좋습니다. 패턴이 많아져도 배열명 하나로 모두 처리할 수 있고, 또 For문을 이용해 자동화할 수도 있기 때문입니다.
#include "LedControl.h"
LedControl lc = LedControl(12,11,10,3);
byte value[2][8] = {
{
B00000000,
B00011000,
B00111100,
B00111100,
B00011000,
B00011000,
B00000000,
B00011000
},
{
B00000000,
B00111100,
B01100110,
B00000110,
B00011100,
B00011000,
B00000000,
B00011000
}
};
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() {
int i;
for (i = 0; i < 8; i++) {
lc.setRow(0, i, value[0][i]);
lc.setRow(1, i, value[0][i]);
lc.setRow(2, i, value[0][i]);
}
delay(1000);
for (i = 0; i < 8; i++) {
lc.setRow(0, i, value[1][i]);
lc.setRow(1, i, value[1][i]);
lc.setRow(2, i, value[1][i]);
}
delay(1000);
}
2차원 배열을 이용해 2가지 패턴을 번갈아 출력하는 소스입니다. 배열 선언 부분을 setup()
함수 위쪽으로 올려서 loop()
함수내에서 매번 선언되는 것을 피했습니다.
#include "LedControl.h"
LedControl lc = LedControl(12,11,10,3);
byte value[][8] = {
{
B00000000,
B00100000,
B00110000,
B11111000,
B11111100,
B11111000,
B00110000,
B00100000
},
{
B00000000,
B00001000,
B00001100,
B01111110,
B01111111,
B01111110,
B00001100,
B00001000
},
{
B00000000,
B00000010,
B00000011,
B00011111,
B00011111,
B00011111,
B00000011,
B00000010
},
{
B00000000,
B00000000,
B00000000,
B00000111,
B00000111,
B00000111,
B00000000,
B00000000
}
};
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() {
int i, j;
for (i = 0; i < 4; i++) {
for (j = 0; j < 8; j++) {
lc.setRow(0, j, value[i][j]);
lc.setRow(1, j, value[i][j]);
lc.setRow(2, j, value[i][j]);
}
delay(500);
}
lc.clearDisplay(0);
lc.clearDisplay(1);
lc.clearDisplay(2);
delay(500);
}
패턴이 4가지입니다. 2차원 배열로 구성했으며 중첩 For문을 이용해서 출력하도록 했습니다.
#include "LedControl.h"
LedControl lc = LedControl(12,11,10,3);
byte value[][8] = {
{
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000
},{
B00000000,
B00000000,
B00000000,
B10000000,
B11000000,
B10000000,
B00000000,
B00000000
},{
B00000000,
B10000000,
B11000000,
B11100000,
B11110000,
B11100000,
B11000000,
B10000000
},{
B00000000,
B00100000,
B00110000,
B11111000,
B11111100,
B11111000,
B00110000,
B00100000
},{
B00000000,
B00001000,
B00001100,
B01111110,
B01111111,
B01111110,
B00001100,
B00001000
},{
B00000000,
B00000010,
B00000011,
B00011111,
B00011111,
B00011111,
B00000011,
B00000010
},{
B00000000,
B00000000,
B00000000,
B00000111,
B00000111,
B00000111,
B00000000,
B00000000
},{
B00000000,
B00000000,
B00000000,
B00000001,
B00000001,
B00000001,
B00000000,
B00000000
}};
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() {
int i, j;
for (i = 0; i < 8; i++) {
for (j = 0; j < 8; j++) {
lc.setRow(0, j, value[i][j]);
lc.setRow(1, j, value[i][j]);
lc.setRow(2, j, value[i][j]);
}
delay(500);
}
}
패턴을 8개로 늘렸습니다. 데이터를 2차원 배열로 선언하는 부분에서 첫 번째 첨자는 생략되어 있습니다. 초기화하는 인수 개수에 따라 자동으로 범위가 정해지기 때문에 생략 가능합니다.
#include "LedControl.h"
LedControl lc = LedControl(12,11,10,3);
byte value[][8] = {
{
B00000000,
B00000000,
B00000000,
B10000000,
B11000000,
B10000000,
B00000000,
B00000000
},
{
B00000000,
B10000000,
B11000000,
B11100000,
B11110000,
B11100000,
B11000000,
B10000000
},
{
B00000000,
B00100000,
B00110000,
B11111000,
B11111100,
B11111000,
B00110000,
B00100000
},
{
B00000000,
B00001000,
B00001100,
B01111110,
B01111111,
B01111110,
B00001100,
B00001000
},
{
B00000000,
B00000010,
B00000011,
B00011111,
B00011111,
B00011111,
B00000011,
B00000010
},
{
B00000000,
B00000000,
B00000000,
B00000111,
B00000111,
B00000111,
B00000000,
B00000000
},
{
B00000000,
B00000000,
B00000000,
B00000001,
B00000001,
B00000001,
B00000000,
B00000000
},
{
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000
}
};
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() {
int i, j;
for (i = 0; i < 16; i++) {
for (j = 0; j < 8; j++) {
if (i <= 7) {
lc.setRow(0, j, value[i][j]);
}
if (i >= 4 && i <= 11) {
lc.setRow(1, j, value[i - 4][j]);
}
if (i >= 8) {
lc.setRow(2, j, value[i - 8][j]);
}
}
delay(500);
}
}
패턴은 8개로 동일하고 For문만 약간 수정해서 3개 모듈을 통과하는 Flow animation을 표현했습니다. Flow animation은 다음 글에서 좀더 좋은 방식으로 구성하도록 할 예정입니다.
이상으로 LedControl Library에 대한 소개를 마치고, 다음 글에선 숫자, 문자 출력 등 라이브러리를 활용하는 예제를 작성해 보겠습니다.