Computer Science/Arduino, RB Pi

Arduino] LED 도트 매트릭스

TwinParadox 2017. 5. 13. 15:30
728x90

Arduino] LED 도트 매트릭스 사용하기



LED 도트매트릭스라고 이야기를 하면

아예 무지한 사람들은 전혀 감을 잡지 못한다.

그냥 도심에서 크게 보이는 전광판이나,

대형식당 등에서 간간히 보이는 LED 전광판이라고 생각하면 편하다.


통상적으로 베이직 키트 등의 세트에 포함된 도트 매트릭스는

5X8형태의 매트릭스가 많고,

널리 사용되는 만큼 이를 사용하는 방법에 대해서 많이 알려져 있어

네이버에 검색만 해도 쏟아져 나올 법하지만,

그래도 필자가 지난날 과제를 수행하면서 정리하였던 도트 매트릭스와 관한 내용과

경험을 되짚어 보면서 이야기를 하고자 이렇게 글을 끄적여본다.


LED 도트 매트릭스 단어 자체를 보면,

LED를 여러 개 배열하여 이를 매트릭스(행렬) 구조로 만들어놓은 소자임을 알 수 있다.








보는 것처럼 이런 형상으로 존재한다.

고정적인 문자를 출력하는 것은 물론이고

잔상을 이용해서 이를 흘러가는 문자나 그림을 출력할 수도 있다.




대략 이런 식의 회로도가 나온다.

필자의 방식과는 약간의 차이가 있으니,

대강 어떻게 설계하는지에 대해 알아두는 차원에서만 보도록 하자.


아무튼 행렬 구조로 이루어진 다이오드이기 때문에,

행과 열의 신호를 적절하게 이용해야 원하는 LED를 점등할 수 있으며

필자가 사용했던 소자는 열을 통해 전원을 공급하고(HIGH),

행을 LOW로 두도록 하여 LED를 출력하게 했다.

여기서 열을 스캔 라인, 행을 데이터 라인이라고도 부른다.


소자의 구성에 따라서 HIGH, LOW로 지정해야 되는 부분이 다 다르기 때문에,

자기가 사용하는 소자에 대한 명칭을 확실히 알고 있으면,

소자에 대한 내용이 자세히 적혀 있는 데이터 시트를 찾을 수 있고

이를 바탕으로 회로를 설계하고 코드를 작성할 수 있으니

되도록이면 사용하는 소자에 대한 정보를 사전에 입수해두는 것이 좋다.


이제 회로 상으로 출력이 어떻게 돌아가는지 감은 올 것이다.

하지만 아두이노에서 코드를 어떻게 설계할까?

5x7이라는 점을 다시 한 번 생각해보자.

이차원 배열에 출력을 1과 0(다른 값이어도 무방하다. 명백히 HIGH, LOW만 나타낼 수 있는 값이면 된다.)으로

출력할 도트와 그렇지 않은 도트를 정해 출력하면

우리가 원하는 것을 출력해줄 수 있을 것이다.






출력을 변경할 때마다 이차원 배열을 새로 짜지 말고

전처리구문을 통해서 미리 글자를 정의하는 것이 정신건강에 이롭다.


사전에 정의내린 글자를 번갈아 출력하는 것도 나쁘지 않은 결과물이지만,

도심에서 보는 흐르는 전광판을 시도해보는 것이 더 좋을 것 같다.


일정 주기마다 도트 출력을 변경해나간다면

위 동영상처럼 글자가 흘러가는 효과를 만들 수도 있다.


상단 동영상에 사용한 소스는 아래와 같다.



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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#include <MsTimer2.h>
 
#define SPACE { \
  {0 ,0 ,0 ,0 ,0 ,0 ,0}, \
  {0 ,0 ,0 ,0 ,0 ,0 ,0}, \
  {0 ,0 ,0 ,0 ,0 ,0 ,0}, \
  {0 ,0 ,0 ,0 ,0 ,0 ,0}, \
  {0 ,0 ,0 ,0 ,0 ,0 ,0} \
}
#define I { \
{01111,ㅈ 00}, \
{0011000}, \
{0011000}, \
{0011000}, \
{0111100} \
}
#define Heart { \
{0110110}, \
{1111111}, \
{0111110}, \
{0011100}, \
{0001000} \
}
#define Y { \
{0110011}, \
{0110011}, \
{0011110}, \
{0001100}, \
{0001100} \
}
#define O { \
{0011100}, \
{0110110}, \
{0110110}, \
{0110110}, \
{0011100} \
}
#define U { \
{0110011}, \
{0110011}, \
{0110011}, \
{0110011}, \
{0011110} \
}
 
byte col = 0;
int row = 0;
byte leds[5][7];
int font = 0;
int i,j,k;
int pins[13= {-19,173145161215102813};
int cols[5= {pins[1] , pins[3] , pins[10], pins[7], pins[8]};
int rows[7= {pins[12] , pins[11], pins[2], pins[9], pins[4], pins[5], pins[6]};
const int numFonts = 6;
byte fonts[numFonts][5][7= {I , Heart , Y , O , U , SPACE};
 
void setFont(int font){
  for (int i = 0; i<5; i++){
    for (int j=0; j<7; j++){
      leds[i][j] = fonts[font][i][j];
    }
  }
}
 
void slideFont(int font, int del){
  for(k=0;k<7;k++){
    for(i=0;i<6;i++){
      for(j=0;j<5;j++){
        leds[j][i]=leds[j][i+1];
      }
    }
    for (j=0;j<5;j++){
      leds[j][6= fonts[font][j][0+k];
    }
    delay(del);
  }
}
 
void dotDisplay(){
  digitalWrite(cols[col],HIGH);
  col++;
  if(col==5){
    col=0;
  }
  for(row =0; row<7; row++){
    if(leds[col][6-row] == 1){
      digitalWrite(rows[row], HIGH);
    }
    else {
      digitalWrite(rows[row], LOW);
    }
  }
digitalWrite(cols[col], LOW);
}
 
void setup(){
  for(int i=1; i<=12;i++){
    pinMode(pins[i], OUTPUT);
  }
  MsTimer2::set(2,dotDisplay);
  MsTimer2::start();
  setFont(font);
}
void loop(){
font = ++font % numFonts;
  slideFont(font,100);
}
 
cs



필자는 여기서 MsTimer2라는 라이브러리를 활용하여

주기적으로 함수를 호출하도록 하였는데,

이 라이브러리에 관한 정보나 활용 방법에 대해서는 생략하겠다.

(차후 이에 대해 다룰 생각이지만, 아직은 예정에 없다.)

728x90