본문 바로가기

아두이노로 장난하기

아두이노로 LED 매트릭스 표시하기


안녕하세요 고군입니다~

이번시간에는 아두이노 우노를 사용하여 LED 매트릭스를 제어해보겠습니다.


LED 매트릭스는 LED를 매트릭스 형태로 배열하여 다양한 문자나 패턴을 표현 할 수 있도록 해주는 표시 장치의 일종으로 광고를 비롯한 다양한 분야에서 활용되고 있습니다. 8X8 크기의 매트릭스의 경우 알파벳 한 글자 숫자 등을 표현할 수 있어 정보 표시를 위해 많이 사용되고 있습니다.  8X8 크기의 LED 매트릭스는 LED만 포함한 제품에서 부터 제어를 위한 칩을 포함한 보드 형태로 제작된 제품 등 종류가 다양합니다. 매트릭스의 도트를 구성하는 LED도 단색, 이색, 등 다양한 종류가 있습니다.



위 사진의 LED 매트릭스 모듈은 16개의 핀을 가지는 모듈로 각 핀은 8개 행(Row)과 8개 열(Column)을 나타낸다. LED 매트릭스 모듈의 뒷면을 살펴보면 1 번 핀에 해당하는  위치에 숫자 1이 표시되어 있습니다. 일반적으로 모듈의 제품명이 기록된 면의 가장 왼쪽 핀이 1번으로 반 시계방향으로 번호가 증가합니다.


테스트에 사용한 모듈의 내부는 행이 LED의 (+)에, 열은 LED의 (-)에 공통으로 연결되도록 구성되어있으며(그림2 참조), 이를 공통 행 양극(common-row anode) 타입 또는 양극(anode)타입이라고 합니다. 이와 반대로 되어 있는 모듈도 있으니 테스트하기전에 데이터 시트를 확인해야 합니다.


▶ LED 매트릭스 특성 및 전자 회로


그림2. 매트릭스 모듈 내부 회로


아래 이미지를 클릭하시면 LED 매트릭스에 대한 더 많은 자료를 참고 하실 수 있는 카테고리로 이동합니다.




▶ 아두이노



[전자부품목록]


▶ 아두이노 보드: 1개 

▶ 브레드보드: 1개

▶ 점프선 : 다량

▶ 저항 220옴: 8개

▶ UDN2981: 1개

▶ ULN2803: 1개

▶ LED 매트릭스: 1개


아래 배선도에서 UDN2981은 싱크(Sink driver) 드라이버로 불리는 칩으로 8개의 드라이버로 구성된 칩으로 저전류, 저전압의 신호로 고전류, 고전압의 회로를 제어 할 수 있도록 한다. UDN2981 칩은 최대 80V, 500mA의 전원을 제어할 수 있다.

UDN2803은 8개의 달링턴 트랜지스터로 구성된 칩으로 UDN2981과 마찬가지로 저전류, 저전압의 신호로 고전류, 고전압의 회로를 제어할 수 있도록 해준다. ULN2803 칩은 최대 50V, 500mA의전원을 제어할 수 있습니다.

한가지 주의 할 점은 열 단위 제어를 하는 경우 LOW입력이 주어질 때 LED가 켜지지만, 안에 인버터가 내장되어 있어 HIGH일 때 LED가 켜집니다.


양극 타입 8x8 LED 도트매트릭를 아두이노에 연결한 모습

양극 타입 8x8 LED 매트릭스 아두이노 연결 회로도


양극 타입 8x8 LED 매트릭스 제어를 위한 핀 연결


▶ 아두이노 소스 예제


※예제 1 한 번에 하나의 도트만을 0.5초 간격으로 [ 1, 1 ] 도트에서    [8, 8 ] 까지 이동하는 예제입니다.



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
int rows[ ] = {23456789};
int cols[ ] = {10111213, A0, A1, A2, A3};
 
void setup( )
{
    for(int i = 0; i  < 8; i++)
    {
        //행과 열 제어 핀을 출력으로 설정
        pinMode(ros[i], OUTPUT);
        pinMode(cols[i], OUTPUT);
    }
}
 
// 모든 LED를 끈다.
// LED 점멸 상태를 변환시키지 전에 모든 도트를 
// 끄지 않으면 잔상이 생길 수 있다.
void clear( )
{
    for(int i = 0; i < 8; i++)
    {
        digitalWrite(rows[i], LOW);
        digitalWrite(cols[i], LOW);
    }
}
 
void loop( )
{
    for(int i = 0; i < 8; i++)
    {
        for(int j = 0; j < 8; j++)
        {    
            clear( );
            
            //i행 j열 도트를 켠다.
            digitalWrite(rows[i], HIGH);
            digitalWrite(cols[j], HIGH);    
 
            delay(500);
        }
    }
}
 
 
 
cs


※ 예제2. 엄지척 이미지를 표시하는 예제입니다.



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
int rows[ ] = {23456789};
int cols[ ] = {10111213, A0, A1, A2, A3};
 
byte smile_char[ ] = {
    B00100000,
    B00110000,
    B00110000,
    B11111111,
    B11111111,
    B11111111,
    B01111111,
    B00000111,
};
 
void setup( )
{
    for(int i = 0; i  < 8; i++)
    {
        //행과 열 제어 핀을 출력으로 설정
        pinMode(rows[i], OUTPUT);
        pinMode(cols[i], OUTPUT);
    }
}
 
// 모든 LED를 끈다.
// LED 점멸 상태를 변환시키지 전에 모든 도트를 
// 끄지 않으면 잔상이 생길 수 있다.
void clear( )
{
    for(int i = 0; i < 8; i++)
    {
        digitalWrite(rows[i], LOW);
        digitalWrite(cols[i], LOW);
    }
}
 
void loop( )
{
    for(int col = 0; col < 8; col++)
    {
    clear();                               // 모든 LED OFF
    digitalWrite(cols[col], HIGH);         // 해당 열 선택
      for(int row = 0; row < 8; row++)
      {    
      int shift = 7 - col;
      //각 행에 해당하는 ON/OFF 값 계산
      int OnOff = (smile_char[row] & (1<< shift)) >> shift;
 
      if(OnOff == 1)
          digitalWrite(rows[row], HIGH);  //ON
      else
          digitalWrite(rows[row], LOW);   //OFF    
      }
            delay(2);
    }
}
 
 
 
cs


※ 예제2. 엄지척 이미지를 움직이게 하는 예제입니다.

 



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
int rows[ ] = {23456789};         // 행
int cols[ ] = {10111213, A0, A1, A2, A3}; // 열
 
//문자에서 표시할 첫 번째 열 
int start_column = 0
//애니메이션 시간 계산을 위한 변수
unsigned int previous, current; 
byte thumb_char[ ] = { 0x00200x00300x00300x00FF
                       0x00FF0x00FF0x00FF0x0007 }; 
void setup( )
{
// 행과 열 제어 핀을 출력으로 설정
    for(int i = 0; i  < 8; i++)
    {
        //행과 열 제어 핀을 출력으로 설정
        pinMode(rows[i], OUTPUT);
        pinMode(cols[i], OUTPUT);
    }
    previous = millis(); // 이전시간
    current = millis();  // 현재시간 
}
 
// 모든 LED를 끈다.
// LED 점멸 상태를 변환시키지 전에 모든 도트를 
// 끄지 않으면 잔상이 생길 수 있다.
void clear( )
{
    for(int i = 0; i < 8; i++)
    {
        digitalWrite(rows[i], LOW);
        digitalWrite(cols[i], LOW);
    }
}
 
void loop( )
{
    current = millis(); // 현재시간
    //0.5초 경과하면 시작 열을 증가
    if(current - previous > 500)
    {
      previous = current;
      start_column = (start_column + 1) % 16;
    }
    for(int col = 0; col < 8; col++)
    {
    clear();                               // 모든 LED OFF
    digitalWrite(cols[col], HIGH);         // 해당 열 선택
      for(int row = 0; row < 8; row++)
      {
      int index = (start_column + 1) % 16;    
      int shift = 15 - index;
      //각 행에 해당하는 ON/OFF 값 계산
      int OnOff = (thumb_char[row] & (1<< shift)) >> shift;
 
      if(OnOff == 1)
          digitalWrite(rows[row], HIGH);  //ON
      else
          digitalWrite(rows[row], LOW);   //OFF    
      }
            delay(2);
    }
}
cs