이번엔 도트매트릭스를 이용한 전광판을 만들어 보자.
요즘에 길거리에 LED를 사용한 광고판들이 많이 보인다. 각종 광고 및 안내 용도로, 단색, 3색, 5색, 256색까지 다양한 LED 전광판들을 어렵지 않게 볼 수 있다.
 지금까지는 아무 생각없이 보고 지나쳤지만 어떤 원리로 글자가 만들어지고 표시되는지 알아보도록 하자.
우리가 최종적으로 만들 것은 아래와 같은 전광판이다.



 도트매트릭스는 단지 LED 여러개를 미리 땜질하여 놓은 LED의 배열일 뿐이다.
위의 사진을 보면 세로로 LED가 16칸, 가로로 64칸이다(8X8 도트매트릭스 16개 사용). 각각의 LED는 녹색, 빨간색, 주황의 3색 LED이다.
 
주황색은 따로 주황색 LED가 있는 것이 아니라 녹색과 빨간색 LED를 같이 켜면 사람 눈에 주황색으로 보인다.
역시 사람 눈의 오점을 이용한 교묘한 수법. 멀리서 보면 주황색으로 보이지만 가까이서 본다면 녹색과 빨간색 LED가 보이는 것을 알 수 있다. 직접 확인해보고 싶다면 근처 전철역이나 버스 정류장에서 확인해 보도록 하자.
 같은 원리로 잉크젯 프린터가 있다. 잉크젯 프린터 역시 다양한 색을 나타내기 위해 3개의 색을 섞어서 표현하는 것이 아니라, 3개의 색을 적당히 뿌려서 사람눈에 적당히 원하는 색으로 보이게끔 눈속임할 뿐이다.

 그럼 이제 저 전광판을 만들기 위해 몇개의 I/O 포트가 필요한가를 계산해 보자.(LED를 켜보았다면 LED하나를 제어하기 위해 1개의 I/O 포트가 필요하다는 것을 알것이다.)
우선 하나의 도트매트릭스에 필요한 I/O Port만 계산해보면
 8X8 = 64개 이고, 각각 빨간색, 녹색 2개의 LED가 들어있으므로 도트매트릭스 하나당 128개의 I/O 포트가 필요하다!
그 도트매트릭스가 16개 있으므로 I/O포트가 총 128*16 = 2048개가 필요하다.
하지만 우린 I/O Port가 2000개나 되는 MPU를 구할 길이 없으므로 전광판 만드는 것을 포기하도록 하자.


 하지만 '아니, 그럼 너님은 어떻게 만들었는데?'라는 생각이 든다면 어떻게 만들었는지 같이 알아보도록 하자. 우리의 지혜로운 선조들은 돈을 아끼기 위한(I/O 포트가 곧 돈이다) 여러가지 기법을 개발해 놓았다.
 그 기법들을 알기 위해 아래 링크를 참조하도록 한다.

디코더 및 래치의 원리

그럼 이제 도트매트릭스의 원리를 알게 되었으니, 실제로 전광판을 만들어 보도록 하자.
도트매트릭스는 연결해야 하는 포트가 많은 만큼 회로 구성 및 땜질에 있어서 상당한 노가다를 요구한다.
그렇기 때문에 실제로 회로를 땜질전 회로가 제대로 동작하는지 확인이 필요하다.


 위에서 구성한 회로는 래치회로가 제대로 동작하는지 확인하기 위한 회로이다.  디코더 및 트랜지스터 부분은 따로 테스트를 했기 때문에 여기서는 빠져있다.(디코더와 트랜지스터가 빠졌음에도 연결해야하는 선이 상당히 많은 것을 알 수 있다.)
 어쨌든 원하는데로 도트매트릭스가 잘 동작하는 것을 확인했으니 땜질을 하도록 한다.


 땜질 완료한 후에 테스트 해본 사진이다. 모든 래치를 enable상태로 놓고 포트에 0xFF 시그널을 주었으므로, 모든 LED가 들어와 주황색이 켜져야 한다. 위 사진에서 보면 RED LED 2개와 가로로 RED LED 한줄이 안들어 오는 것을 알 수 있는데, 불이 안들어오는 원인에는 도트매트릭스의 LED가 죽었거나, 땜질이 잘못되었을 경우이다. 우선 도트매트릭스가 나갔는지는 도트매트릭스를 교체해 보면 알 수 있고, 위와 같은 경우에는 회로도를 보거나 땜질한 부분을 직접 살펴보고 문제점을 금방 찾을 수 있다.
 그리고 사진에서 보면 알 수 있겠지만 도트매트릭스 별로 약간씩 밝기가 다른 것을 알 수 있다. 이는 회로의 문제가 아닌 도트매트릭스 자체의 문제이므로 도트매트릭스를 적절히 재배치하여 눈에 튀지 않게 구성하도록 하자.


 이제 어렵게 도트 회로를 완성하였으니, 실제 글자를 넣어주도록 하자.
지금 만든 도트매트릭스는 16X64개의 LED로 구성되어 있으므로 기본적으로 2byte짜리의 배열을 [84]개 만들어 놓고 원하는 글자를 해당 배열을 참조하여 실제 I/O포트에 값을 넣어주는 형태로 만들 수가 있다.(2byte는 16bit이므로 2byte의 배열을 84개 만들면 될 것이다.)
 일정시간단위로 해당 배열의 데이터를 이용하여 래치에 각각의 데이터를 넣어주고, 디코더 값을 증가시키는 역할을 하는 부분을 따로 만들면 실제 프로그래밍시에는 디코더와 래치를 신경쓰지 않고 해당 배열의 데이터만 바꾸는 작업으로 실제 표시되는 글자를 바꿀 수가 있게 될 것이다.

일반적으로 프로그램은 H/W를 직접적으로 접근하는 드라이버단과 그 위에서 드라이버단을 사용하는 어플리케이션단으로 나누어 짜는 방법이 있는데, 이렇게 역할별로 잘 분리하여 프로그램을 짤 경우 유지보수 측면에서 상당한 이득을 얻을 수 있게 된다. 위에서 보라색으로 표시한 부분을 드라이버단, 해당 배열에 데이터를 바꾸어주는 부분을 어플리케이션단으로 나누어서 프로그램 구조를 잡을 것이다. 이렇게 할 경우, 문제 발생시 어느쪽의 문제인지 파악하여 그 부분의 문제만 수정하게 되면 프로그램의 구조의 변경없이 수정을 쉽게 할 수 있을 것이다. 또한 H/W 변경시에도 어플리케이션단의 소스는 그대로 활용할 수 있게 된다.
 하지만 이렇게 나눌 경우 Main Application단에서 해당 배열에 값을 넣고 있는 중에 인터럽트가 걸리게 되면 문제가 발생할 소지가 있다. 이러한 경우에 대비하기 위해 배열의 값을 변경할 때에는 인터럽트가 걸리지 않도록 꺼주어야 한다.
(크리티컬 섹션이라고 하며, 이 구간은 짧을 수록 좋다. 자세한 내용은 OS의 크리티컬 섹션, 뮤텍스, 세마포어 등을 참조하도록 하자)


우선 일정시간단위로  래치에 각각의 데이터를 넣고 디코더 값을 바꿔주는 일을 해야하므로 타이머 인터럽트를 사용하도록 한다. 


 

위의 소스코드를 살펴보면 타이머 인터럽트 발생시 decorder의 sequence를 0에서 7까지의 범위로 증가시켜주고 displayArrayData()를 호출하여 gData[] Array의 데이터를 각각의 래치에 담는 작업을 한다.
이렇게 드라이버단을 만들어 놓은 후 main() 함수에서는 gData[]의 값만 바꿔주면 실제 도트매트릭스에 입력되는 데이터가 바뀌어 실제 도트매트릭스에 해당 값으로 불이 들어오게 된다.
(위의 소스에서는 GREEN에 해당하는 데이터만 처리하도록 되어있다. RED도 같은 원리로 제어할 수 있을 것이다.)

 이것을 이용하여 여러가지 효과를 주어 아래와 같은 전광판을 만들어 보도록 하자.