개발 목적
 우리가 일반적으로 사용하는 휴대용 디스플레이어의 경우 소형화면을 채택하므로 이동 중에 볼 경우 화면이 흔들려 제대로 된 화면을 볼 수 없다. 이러한 불편을 해소하기 위해 이동 중에도 흔들림 없이 화면을 볼 수 있는 보정장치를 개발하게 되었다.

기본 구조
 가속도센서에서 움직임이 검출되면 움직임에 대한 가속도 값을 픽셀로 변환 후 해당되는 픽셀만큼 화면을 이동시켜 움직임을 보상한다.

Processor : ARM7(AT91SAM7S256)

LCD : 2.4" TFT-LCD(320X240)

Sensor : 3-Axis Acceleration Sensor


기본 원리



구현 영상

아래의 영상은 극적인 효과를 위해 보정 범위를 크게 했으나, 실제 응용엔 보정 값을 작게하여 미세한 움직임에 대해 보정하도록 하면 눈의 부담을 크게 줄여 줄 수 있을 것이다.

영상 뒷 부분의 그래프는 가속도 센서에서 나온 값을 필터링 한 결과를 보여준다.

- 녹색 : 필터링 되기 전의 센서 값 - 노이즈가 많이 발생함

- 연두색 : 노이즈 제거를 위한 이동 평균 필터 적용

- 하얀색 : 가속도 센서의 경우, 현재 센서의 기울어진 정도(pitch, yaw, roll)에 영향을 받기 때문에, 제대로 된 가속도 값을 얻기 위해 그 값을 필터링 한 결과.






포터블 도트매트릭스

우리는 전에 도트매트릭스를 이용한 전광판을 만들어 보았다.(도트매트릭스 전광판 참조)
 기존에 만든 전광판은 원래 짜여진 각본대로 출력하는 수동적인 바보티비에 불과했지만 이번엔 기울기센서를 추가하여 사용자의 입력에 따라 출력을 바꾸어주는 능동적인 디스플레이어를 만들어 보도록 하자.
 기본적인 하드웨어 구성은 다음과 같다.


기본적인 도트매트릭스 회로에 기울기센서 및 진동모터를 추가되었다.
 기울기센서는 현재 기울어진 각도에 따라 전압을 다르게 출력해준다. 그렇다면 역시 A/D Converter를 사용해야 한다는 얘기인데, 여기서는 기울기 센서를 두개 사용하여 X축 및 Y축에 대한 기울기 값으로 현재 기판이 기울어진 정도를 얻을 수 있게 구성하였다.
 ATMEGA128의 경우에는 기본적으로 A/D Converter가 포함되어 있기 때문에 따로 회로를 구성하지 않아도 된다, 기울기 센서에 기준전압만 넣어주고 기울기센서의 출력만 PF0/ADC0, PF1/ADC1에 연결하면 회로 구성은 끝. 참 쉽죠?

 기울기 센서를 통해 입력을 받을 수 있게 되면서 도트매트릭스가 할 수 있는 일은 무궁무진해졌다.
여기서는 아래와 같이 4가지 기능을 구현해 보았다.
- 지렁이 게임
- 길찾기 게임
- 사용자의 입력에 따라 글자 및 색상을 바꿔 표시할 수 있는 전광판  
- 현재 각도에 맞게 글자를 회전 시키는 회전 전광판

전광판



길찾기 


지렁이


 글자회전

 

 
 이번엔 도트매트릭스를 이용한 전광판을 만들어 보자.
요즘에 길거리에 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도 같은 원리로 제어할 수 있을 것이다.)

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