아두이노 강좌 #24 8x8 LED Dot Matrix 내부 구성과 기본 동작 방법
Lucy Archive
Lucy / Facilitate4U
2020. 8. 17. 02:03

Arduino Uno LED MatrixArduino Uno LED Matrix

Arduino Uno 8x8 LED Dot Matrix Basic

LED Dot Matrix 는 옥외 전광판 등에서 볼 수 있는 LED타입의 표시 장치입니다. 표시 장치로 LED를 사용하는 경우 LCD에 비해 가시거리가 먼 장점이 있습니다. 그래서 야외에 사용되는 광고판, 신호등, 지하철 운행 알림등의 표시 장치들은 대부분 LED로 구성되어 있습니다. 8x8 LED는 아두이노에서 많이 사용되는 LED 표시 장치입니다. 본 포스트에서는

8x8 LED의 내부 구성과 기본적인 동작 방법

에 대해 설명합니다.

8x8 LED Dot Matrix

8x8 LED Matrix 외관 및 내부 회로

아래 그림은 제가 가지고 있는 8x8 LED Dot Matrix 의 외형과 내부 회로를 도식화한 그림입니다. 8x8 LED Matrix 는 제조사 및 기타 종류에 따라 핀 번호 및 내부 회로 구성이 달라, 사용하시는 부품의 데이터시트를 꼭 확인하셔야 합니다. 본 포스트에서는 아래와 같은 구성의 LED Matrix 기준으로 설명을 할 예정입니다.

8x8 LED Matrix8x8 LED Matrix

위와 같은 8x8 LED Matrix 가 있는 경우 빨간색으로 표시된 LED 를 켜기 위해서 Column 4 번은 HIGH, Row 3 번은 LOW로 입력 되어야 LED가 켜집니다. 다른 LED가 켜지는 원리도 동일 합니다. 

8x8 LED 매트릭스 구동 방법

위의 설명에서 한 개의 LED를 켜기 위한 방법은 이해하는데 어려움이 없을 것이라 생각합니다. 

아래와 도형을 출력 하기 위해서는 한 줄씩 LED 를 구동을 하는 방식으로 코딩하여 8x8 LED Display 를 사용 하 실 수 있습니다. 위의 회로와 같은 경우 아래와 같은 순서로 코드를 작성 할 수 있습니다.

  • 1st ROW 데이터 8개의 Column 핀에 HIGH 또는 LOW 입력 : LED 모두 OFF 인 상태에서
  • ROW 1번핀 'LOW' 입력 : LOW 되는 동안 LED 가 켜져 있는 시간
  • ROW 1번핀 'HIGH' 입력 : LED 는 모두 OFF 상태
  • 2nd ROW 데이터 8개의 Column 핀에 HIGH 또는 LOW 입력 : LED 모두 OFF 인 상태에서
  • ROW 2번 핀 'LOW' 입력 : LOW 되는 동안 LED 가 켜져 있는 시간
  • ROW 2번 핀 'HIGH' 입력 : LED 는 모두 OFF 상태
  • 위의 순서대로 동작 반복....

LED Dot Matrix 동작 방식LED Dot Matrix 동작 방식

LED Matrix 동작시 항상 모든 LED를 OFF상태에서 Column 의 데이터를 변경하시길 권장 드립니다. 각 ROW 활성화 하는 타이밍을 잘 조절 하면 문제가 없지만, LED OFF 상태에서 데이터 변경하지 않는 경우 잔상 효과가 있을 수 있습니다. 


Hardware

아두이노 우노 보드에서 8x8 LED Dot Matrix 를 사용하기 위해 아래와 같이 회로를 연결 합니다.

Arduino Uno 8x8 LED Matrix 연결 회로도 및 연결 예시Arduino Uno 8x8 LED Matrix 연결 회로도 및 연결 예시

회로 고려사항

아두이노 핀맵과 8x8 LED Dot Matrix 연결시 연결 핀은 연결하기 편한 다른 방법을 사용해도 무방합니다. 

2.2kΩ 의 높은 저항을 사용한 이유는 Arduino Uno 에서 공급 할 수 있는 전류를 고려하여, 최대한 적은 전류도 구동하기 위해 사용되었습니다 .

2.2kΩ 이 Column Pin 에 연결되어야 하는지 또는 Row Pin 에 연결되어야 하는 기준은 8 Bit데이터를 기록되는 곳이 Column 이면 Column pin 에, Row 이면 Row pin 에 저항이 연결되어야 합니다. 아래 예제에서는 Column 핀에 데이터를 입력 후 한행(ROW) 씩 LED 를 켜고 끄는 방식을 사용하여 Column 핀에 저항을 연결하였습니다.


예제1 : 하트모양 출력1

코드

아래는 위의 회로도를 이용하여 LED Matrix 에 하트를 출력하는 예제입니다. 연결하는 Pinmap 이 다른 경우 선언문 #define 문에서 수정하여 반영 할 수 있습니다. 지난 FND 관련 예제의 코드와 유사한 방법으로 작성하였습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
// Coloumn Pin 할당
#define C1 9
#define C2 12
#define C3 7
#define C4 13
#define C5 A2
#define C6 6
#define C7 3
#define C8 A5
// Row Pin 할당
#define R1 2
#define R2 11
#define R3 10
#define R4 A4
#define R5 8
#define R6 A3
#define R7 4
#define R8 5
 
int colPin[8= {C1, C2, C3, C4, C5, C6, C7, C8};
int rowPin[8= {R1, R2, R3, R4, R5, R6, R7, R8};
 
int matrixHeart[8][8= {
                    { 00000000 }, // 0
                    { 01100110 }, // 1
                    { 11111111 }, // 2
                    { 11111111 }, // 3
                    { 11111111 }, // 4
                    { 01111110 }, // 5
                    { 00111100 }, // 6
                    { 00011000 }, // 7
};
 
void setup() {
    for(int i = 0 ; i < 8 ; i++)
    {
        pinMode(colPin[i], OUTPUT);
        digitalWrite(colPin[i], LOW); // Column 핀은 LOW 로 초기화
        pinMode(rowPin[i], OUTPUT);
        digitalWrite(rowPin[i], HIGH); // Row 핀은 HIGH 로 초기화
    }
}
 
void loop() {
    for(int i = 0 ; i < 8 ; i++)
    {
        for(int j = 0 ; j < 8 ; j++)
        {
            digitalWrite(colPin[j], matrixHeart[i][j]); // Column 핀에 데이터 쓰기
        }
        digitalWrite(rowPin[i], LOW); // i LOW 켜기
        delayMicroseconds(100);
        digitalWrite(rowPin[i], HIGH); // i LOW 끄기 -> 모든 LED 끄기
    }
}
cs

코드 설명

LED Dot Matrix 출력 코드의 핵심은 아래 그림과 같이 Dot Matrix 에 출력할 데이터와, 출력하는 코드 입니다. matrixHeart 배열은 아래 그림과 같이 Heart 모양의 출력을 보내기 위한 데이터 배열입니다. loop() 함수내의 for문에서 수행하는 내용은 matrixHeart 배열의 첫 번째 인덱스 데이터를 Column 8핀에 데이터를 각가 입력 후 Row1 만 활성화, 다음 배열 인덱스의 데이터를 Column 8핀에 데이터 입력 후 Row 2만 활성화 하는 과정을 반복합니다. 

LED Dot Matrix 코드 설명 그림LED Dot Matrix 코드 설명 그림

실행 결과

프로그램을 실행하면 아래 그림과 같이 LED Matrix 에 하트 모양이 출력 됩니다.

예제1 하트 모양 출력 결과예제1 하트 모양 출력 결과


예제1 문제점 : 데이터 사이즈

예제1의 코드는 이해를 돕기 위해 지난 FND 출력 코드 스타일과 유사하게 작성하였습니다. 이와 같이 코드를 사용하는 경우 출력 데이터를 담고 있는 matrixHeart 의 데이터 크기가 불필요하게 크다는 단점이 있습니다. 예제1코드에서 사용한 matrixHeart 의 데이터 크기는 int 형(Arduino Uno 기준 2Byte)으로 선언되어 8 x 8 x 2Byte = 128 Byte 입니다. 8x8 디스플레이에 하트를 출력하기 위해 128 Byte 를 사용하였습니다. 

Arduino Uno 의 경우 전역 변수가 저장될 수 있는 데이터 공간은 2KByte 입니다. 예제1과 같이 표시할 데이터를 저장하는 경우 대략 2,048 / 128 = 16 문자 정도만 처리 가능합니다. 이는 아주 단순하게 계산한 것으로 프로그램 메모리는 제외된 상태입니다. 즉, 많은 데이터 출력을 하기 위해서 출력할 데이터 저장 방식이 변경 될 필요성이 있습니다. 

예제2는 8x8 LED Dot Matrix 를 사용하기 위해 1Pixel 당 1bit 의 용량을 사용하도록 수정된 코드입니다. 예제1는 1Pixel 처리를 위해 16Bits (2Byte) 가 사용되었습니다. 

예제2 : 하트모양 출력2

코드

예제1과 동일한 동작을 하지만, 데이터 저장 방법과 처리 방법을 변경하였습니다. 예제1은 8x8 1화면을 출력하기 위해 128 Byte 를 사용하였으나, 예제2는 8Byte 를 사용합니다. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
// Coloumn Pin 할당
#define C1 9
#define C2 12
#define C3 7
#define C4 13
#define C5 A2
#define C6 6
#define C7 3
#define C8 A5
// Row Pin 할당
#define R1 2
#define R2 11
#define R3 10
#define R4 A4
#define R5 8
#define R6 A3
#define R7 4
#define R8 5
 
// Bit 추출 메크로 : data 에서 loc 번째 비트 부터 area 영역 만큼 추출
// ex) extract_bits( 0b00000010, 1, 2) 결과 1 -> 0b00000010 데이터의 2번째 비트 1크기 만큼 추출  
#define extract_bits(data, area, loc)   (((data) >> (loc)) & (area))
 
int colPin[8= {C1, C2, C3, C4, C5, C6, C7, C8};
int rowPin[8= {R1, R2, R3, R4, R5, R6, R7, R8};
 
const byte heart8x8[8= {
    0b00000000,
    0b01100110,
    0b11111111,
    0b11111111,
    0b11111111,
    0b01111110,
    0b00111100,
    0b00011000
};
 
void setup() {
    for(int i = 0 ; i < 8 ; i++)
    {
        pinMode(colPin[i], OUTPUT);
        digitalWrite(colPin[i], LOW); // Column 핀은 LOW 로 초기화
        pinMode(rowPin[i], OUTPUT);
        digitalWrite(rowPin[i], HIGH); // Row 핀은 HIGH 로 초기화
    }
}
 
void loop() {
    for(int i = 0 ; i < 8 ; i++)
    {
        for(int j = 0 ; j < 8 ; j++)
        {
            digitalWrite(colPin[j], extract_bits(heart8x8[i],0x01,j)); // Coloumn 핀에 데이터 쓰기
        }
        digitalWrite(rowPin[i], LOW); // i 행 활성화
        delayMicroseconds(100);
        digitalWrite(rowPin[i], HIGH); // i 행 비활성화
    }
}
cs

코드 설명

예제1과 차이점은 27번 줄의 heart8x8 배열 선언 방법과 53번 줄에서 Column 핀에 데이터를 출력하는 방식이 변경 되었습니다. 

heart8x8 배열은 1차원 배열로 1개의 인덱스당 8bit 의 데이터를 가지고 있습니다. 

53번 줄에 사용된 extract_bits() 는 데이터 비트 연산으로, 22번 줄에 메크로로 정의 되어 있습니다. extract_bits(heart8x8[i], 0x01, j) 에서 반환하는 값은 heart8x8 의 i 인덱스에서, j번째 비트를 추출 합니다. 

실행 결과는 예제 1과 동일합니다.

LED Dot Matrix 코드 설명 그림LED Dot Matrix 코드 설명 그림


예제1, 예제2 차이점

아래 그림은 예제1, 예제2 각각 빌드 후 메모리 사용량을 비교한 그림입니다. 표시할 데이터가 늘어나면 늘어날수록 차이가 커진다는 점을 참고해주세요.

예제1, 예제2 메모리 용량 비교예제1, 예제2 메모리 용량 비교


마무리

본 포스트에서는 8x8

LED Matrix 의 내부 구성과, Arduino Uno 를 사용하여 기본적인 동작 방법 및 코드 작성 주의 사항

에 대해 소개하였습니다. LED Matrix 동작 방식이나 본 포스트의 코드가 이해 되지 않으시는 분은 이전의 FND 관련 포스트를 보시면 이해하는데 도움이 될 수 있습니다. 필요하시면 하단의 링크를 참고해주세요.

끝까지 읽어주셔서 감사합니다.^^😁

관련포스트

👉 아두이노 LED Matrix 관련글 목록 보기

👉 아두이노 디스플레이 장치 관련글 목록 보기

👉 아두이노 관련글 전체 목록 보기