본문 바로가기
  • SDXL 1.0 + 한복 LoRA
  • SDXL 1.0 + 한복 LoRA
Study/아두이노

아두이노 스마트 미러 만들기 #2

by 마즈다 2017. 1. 21.
반응형


진짜를 만들어보자 - 2. LCD 폰트 살펴보기


지난 글에서 밝혔듯이 아두이노를 이용하여 TFT LCD에 문자열을 출력하는 방식은 꽤나 
생소했다. 그냥 일반적인 웹 시스템이나 모바일 애플리케이션을 개발할 때는 그냥 폰트 파일
하나 가져다 놓고(물론 폰트 파일의 구조가 어떻게 생겼는지는 알 필요도 없다. 그냥 폰트
이름만 알면 되지) 이름과 size만 지정해서 사용하면 그만이었는데…


아무튼 새로운 지식의 장벽 앞에 조금 막막했다.


닥글링? (닥치고 구글링?)


우선 ‘아두이노’, ‘LCD’, ‘폰트’, ‘TFT LCD’ 등등의 검색어로 구글링을 해보았다. 물론 네이버
검색도…역시나 검색의 바다에는 쓸만한 정보들이 차고 넘친다. 먼저 내가 참조한 사이트들의
링크를 공유한다.


사실 대부분의 내용들이 자세히 살펴보지 않으면 상세한 부분까지 알기 힘든 수준이었다.
특히나 나같은 문돌이들은 일단 수학적인 개념이 들어가면 멘붕 상태에서 이리저리 헤매기
일쑤고…-.- 그래도 그나마 그림으로 표현한 내용들은 어느 정도 이해를 할 수 있었다.


폰트의 구조 - 장인의 한 땀…


일단 위에 링크된 곳들을 돌아다니면서 LCD 화면에 폰트가 어떤식으로 표시되는지는 대략
알 수가 있었다.


LCD상의 하나의 점(pixel)을 하나의 bit로 표시하고 그 점들의 그룹을 한 문자의 영역(이
영역이 바로 폰트의 사이즈라고 보면 되겠다. 8 X 12, 8 X 16, 16 X 22 등)으로 삼고
그 영역 내에서 문자의 형태를 bit값 1로 채워나가는 것이다. (첫 번째 링크의 3. Bitmap
font(비트맵 폰트)의 구조 참조)


그래서 일단 waveshare에서 제공하는 라이브러리에 포함된 font.c 파일에 있는 배열 중
하나에서 ‘A’라고 주석된 배열을 한 번 풀어보기로 했다. 배열의 요소들은 16진수로 표현
되어있으니 이걸 다시 2진수로 만들어보았다.


원본 배열 : 0x00,0x40,0x07,0xC0,0x39,0x00,0x0F,0x00,0x01,0xC0,0x00,0x40
2진수로 변환한 배열 : 00000000,01000000,00000111,11000000,00111001,00000000,
00001111,00000000,00000001,11000000,00000000,01000000


그리고 이렇게 2진수로 변환한 배열을 2개(2byte)씩 잘라 세로로 배치를 해보았다.
그랬더니 아래와 같은 모양이 되었다(블로그에 사용된 폰트가 가변폭이라서 이미지로 첨부
하였다).




오호~!!! 뭔가 보이는가? 조금 더 알아보기 쉽게 0울 모두 지워보자





마치 그냥 암호처럼 보이던 배열이 이렇게 풀어놓고 보니 어렴풋이 문자의 형상이 나타난다. 
이렇게 풀어놓은 것 중에 1로 표시된 것들이 LCD상에서 빛을 내며 문자로 출력되는 것이다. 
비트맵 폰트라는 것이 이렇게 모눈종이같은 영역에 한땀한땀 정성들여 만들어진다는 것을 
처음 알았다…ㅠ.ㅠ


끝이 아니네?


아하~! 일단 폰트의 구조를 알았으니 응용하면 되겠구나.
하지만 나에게는 장인정신이 없으니 한땀한땀 폰트를 만들 수는 없는 일!
대충 비슷한 폰트 크기 큰걸루다가 구해서 쓰면 내가 산 LCD에도 큰 폰트를 출력할 수 있겠네~


그리고 다시 폰트를 찾기 위해 구글링…그러다가 아래의 사이트를 찾았다. 


굉장히 친절한 사이트였다. LCD 모듈도 파는 것 같고 다양한 LCD 라이브러리도 있고 중요한 
것은 이미지 파일로 폰트 파일을 만들어주기도 하고 아예 그렇게 만들어진 폰트를 다운로드 할
수도 있다. 그것도 모양과 크기도 다양하게!


오호 횡재다~ 하고 다양한 폰트를 다운로드 받었으나…웬걸…내가 가진 폰트는 2차원 배열로
구성되어있는데 다운로드 받은 폰트파일은 1차원 배열이네? 게다가 처음 한 줄은 뭔가 byte
수도 모자라고…




다행히 라인별로 아스키 문자가 주석으로 붙어 있어서 각 라인을 하나의 배열로 만들어 2차원
배열로 만들면 되겠다는 것을 쉽게 알 수 있었다. 나중에 알았지만 처음 4바이트는 폰트의
크기와 종류를 나타내는 값이었다. 그래서 일단 폰트 파일을 다음과 같이 수정했다.




자~ 이제 준비는 끝났고 출력만 해보면 되겠다~물론 라이브러리에서 상수 지정하고 새로
지정한 상수 선택시 추가한 폰트를 표시하도록 몇가지 수정을 거쳤다. 그리고 기운차게
스케치의 업로드 버튼을 클릭!!!


악!!! 이거 왜이래!!!




폰트가 나오기는 나왔는데 이게 영 상태가 병맛이다. 옆으로 누워있는데다가 가운데는 홍해가
갈라지듯 갈라져있고 게다가 이게 시계방향으로 돌려도 문자의 좌우가 뒤집힌 것이 분명한…
이게 아예 글자도 아닌 것 같이 찍혔으면 아예 뭔가 크게 잘못되었구나 하고 처음부터 차근차근
다시 해볼텐데…뭔가 글자인 것 분명한데 돌아가고 뒤집히고 한 모양이다보니 괜히 이리저리
머리를 쓰게 만든다…ㅠ.ㅠ for문을 고쳐볼까? 배열에서 요소들의 순서를 바꿔볼까?
아는가? 뭔가 조금만 손대면 될 것 같은데 어디를 손대야 할 지 모를 때 엄습하는 그 답답함…ㅠ.ㅠ


상투적인 것이 가장 확실하다!


사실 이 문제 해결을 위해 하루를 꼬박 보냈다. for문도 수차례 고쳐보았고, 배열 요소의 순서도
여러번 바꿔보았다. 하지만 도무지 답이 나오지 않았다. 결국 처음 폰트에 대해 이해할 때 했듯
배열을 분해해보기로 했다. 짜잔~ 분해했더니 아래 그림과 같이 거대한 문자가 하나 나왔다.
이거 나름 상당한 노가다다…-.- (로봇을 만들 때도 그렇고 이 것도 그렇고…분명 뭔가 지식 산업
에 대한 과제를 하는 듯한데 왜이리 육체노동을 하는 느낌이지…ㅠ.ㅠ???)




일단 풀어는 놨는데…뭔가 이상하다. 물론 크기가 엄청 큰 것도 있지만 그 것 말고도 뭔가
이상하다…waveshare에 포함된 폰트는 풀어헤쳐놓으니 대가리를 왼쪽으로 향하고 누운
모양이었는데 이 UTFT 폰트는 정상적인 형태로 똑바로 서있는 것이다!


라이브러리에 포함된 출력 함수가 옆으로 누운 폰트를 화면상에 똑바로 보이도록 처리해주는
함수였으니 똑바로 선 폰트가 이상하게 출력되는 것은 당연한 일인 것이다. 함수를 좀
분석해보려 하니 짧은 함수이지만 shift 연산도 있고 또 16진수 bit 연산도 있고…간만에
보니 뒷골 땡기는 연산들이 좀 있어서 일단 그림으로 이해해보기로 하였다.



                



그림을 보니 A와 D를 축으로 회전한 모양이다. 그러고보니 UTFT 폰트가 이상하게 나왔던
모양과도 딱 들어맞는다. 결국 함수를 고치는 수밖에는 답이 없어보였다. 그나마 다행인 것은
사용하려는 폰트가 똑바로 선 형태의 폰트이다보니 좌표때문에 머리아플 일은 없다는 것이다.
그냥 순서대로 x좌표를 이동하면서 출력하다가 폰트 사이즈에 따라 적절한 시점에 y좌표를
증가시켜주기만 하면 된다.


그리고 드디어~!




waveshare 라이브러리에서 UTFT의 다양한 폰트를 사용할 수 있게 된 것이다…ㅠ.ㅠ
(그럼에도 불구하고 마지막 Cyan 색상의 가장 큰 폰트는 뭔가 폰트 이미지하고 모양이
맞지 않는다…-.-)


아직도 남아있는 숙제들


다행히 사용하고자 하는 폰트가 똑바로 선 형태라 쉽게 함수를 만들어 사용할 수 있게
되었다. 하지만 아직 숙제가 있다. 바로 화면 회전에 따라 가로모드 세로모드에서 모두
자유자재로 정상적인 형태의 폰트를 보여주는 것! 그리고 가장 중요한 한글의 처리!!!


이와 관련된 자료도 위에 링크한 사이트에 많은 설명이 있지만 좌표 예기만 들어도
머리가 지끈거린다…ㅠ.ㅠ 일단 머리아픈 일은 여기까지 마무리 하고 새로 주문한
LCD들이 UTFT 라이브러리를 지원한다고 하니 조금은 편하게 작업을 좀 해보자…ㅠ.ㅠ


다음 과제는 Wi-Fi 센서를 통해 웹 서버로부터 날씨나 시간 데이터를 가져와서 예쁘게
뿌려주는 것이다!


수정한 라이브러리를 공유드리고 싶은데 라이센스 정보를 확인 못해서 일단 확인 후
별다른 제약이 없으면 UTFT 폰트를 사용할 수 있도록 수정한 라이브러리를 공유하도록
하겠습니다.

반응형