nRF5 SDK (8) - 3.2 inch (ILI9341 SPI module) LCD 개발 <2>

Updated:

8. nRF5 SDK 이용해서 3.2 inch LCD 개발하기 <2>

📰 이전 포스트 에 이어서 진행됩니다.

8.1 BMP image in nRF5 SDK gfx example

MSP3218 LCD 개발 관련해서.. 아래 링크에 들어가보면 데이터 시트랑 매뉴얼 등이 있고, .bmp 이미지를 코드로 변환해주는 프로그램도 있다.

이전 포스트에서 확인했듯이, nRF5 SDKgfx 예제를 실행시켜보면 LCD 에 nRF52-DK 그림이 출력되는 것을 볼 수 있을텐데, 해당 이미지는 실제로 uint16_t 타입의 배열로 정의되어 있다.

위 그림에서 배열에 포함된 요소 하나하나가 하나의 BMP 그림 pixel 각각의 색상 값을 가리킨다고 보면된다.


8.2 65K RGB color image

.bmp 이미지를 코드로 변환하는 프로그램 사용법에 대해 소개하기에 앞서 65K RGB color 에 대해 잠깐 설명하자면.. 일단, ILI9341 driver 에서는 565RGB color 를 제공한다. 흔히 보편적으로 알려진 RGB 색상은 888RGB 에 해당한다, Red, Green, Blue 색상에 대해 각각 8 bits: 0 ~ 255 의 값으로 구분할 수 있는 색상을 가리킨다.

565RGB 는 Red 와 Blue 색상에는 5 bits 가, Green 색상에는 6 bits 가 할당된 색상 코드이며, 따라서 최종적으로 표현되는 색상은 5 + 6 + 5 = 16 bits 로 표현되기 때문에 2^16 = 65,536 이므로, 이를 65K RGB color 라고 부르기도 한다.


8.2.1 memory issue

위 그림의 코드를 보면 320*240 해상도의 LCD 에 그려지는 nRF52-DK 그림에 대한 변수가 const 로 정의 되어있는 것을 볼 수 있고, 이는 nRF52840 chip 의 flash memory 영역에 저장된다. 320 x 240 = 76,800 이고, 하나의 pixel 은 16 bits = 2 Bytes 크기의 변수로 표현된다.

❗ 즉, 320 x 240 해상도의 그림을 위와 같은 방식으로 호출하게 되면, 76,800 * 2 = 153.6 KB 만큼의 flash memory 를 사용하게 되므로 주의해야 한다.

  • nRF52832 chip 같은 경우에는 최대 512 KB 의 flash memory 를 갖고 있고, nRF52840 chip 은 1 MB 의 flash memory 를 갖는다. (SD 카드 없이 nRF chip 만을 가지고 LCD application 을 구현하기에는 부족할 수 있음.)

  • 참고로, image 코드를 static 전역 변수에 저장하는 경우에는 RAM 영역의 memory 자원을 사용하는데, 보통 nRF chip 에서 RAM 은 flash 보다 1/4 정도 크기이므로 그것도 생각보다는 쉽지 않을 것이다.

아무튼 이와 같은 memory issue 가 있음을 소개하기 위해 언급하였다~ 이말이야


8.3 image upload example (with nRF5 SDK)

위에서 소개한 http://www.lcdwiki.com/3.2inch_SPI_Module_ILI9341_SKU:MSP3218 페이지의 항목들을 보다보면 .bmp 이미지를 코드로 변환해주는 프로그램을 같이 제공해주는 것을 볼 수 있다. 다운 받아서 압축풀어보면 아마도(?) 아래와 같은 구성의 폴더가 있을 것이다.

Img2Lcd.exe 프로그램을 이용해서 이미지를 코드로 변환할 수 있다. 설명이 중국어(?) 로 되어있긴한데.. 굳이 설명을 안봐도 대충 어떻게 쓰는지 느낌이 옴..

위의 그림은 예시를 보여주기 위해, 인터넷에서 .bmp 파일을 하나 임의로 다운 받아서 적용하였다 (https://learn.adafruit.com/assets/81909 여기서 이미지 가져옴 ㅋㅋ).

간단하게 (?) 설명하자면,

  • Open 버튼을 눌러서 원하는 .bmp 파일 선택.
  • Output file type 은 .c array 로 설정.
  • Scan mode 메뉴하고 Scan Right to Left / Bottom to Top 항목을 이용해 그림이 그려지는 방향을 고려해 출력 파일이 생성된다.
  • 색상은 65K RGB 코드를 사용하기 때문에 16-bit TrueColor 를 선택하면 되고, 하단의 메뉴에서 565RGB로 선택할 것.

이미지와 옵션 선택 후, Save 버튼을 누르고 파일 이름을 입력해주면, 아래 그림과 같이 선택한 이미지가 char type 의 배열로 생성되는 것을 확인할 수 있다.

본 예시에서 사용하는 그림의 경우는 120*160 크기의 그림이므로, 19,200 사이즈의 16 bits 배열이 필요하다. 변환된 코드는 char 타입 (8 bits)으로 생성되었고, 19,200 의 두 배에 해당하는 38,400 사이즈이므로, 생성된 데이터의 사이즈는 원본 그림 크기와 일치한다.

그런데, 문제는 앞서 본 것처럼 nRF5 SDK 에서는 uint16_t 타입의 배열로 .bmp 이미지를 저장하기 때문에 이를 char 타입으로 얻어진 변수를 두 개씩 묶어줘야 한다. 여기서부터는 본인 재량껏 하면 되는데, 나는 Python 을 이용해서 적당히 16 bits 사이즈 배열로 합쳤다. 본 포스트의 과정을 똑같이 따라하고 있다면, 0XB4, 0xBD, ... 로 생성된 데이터를 0XB4BD, ... 형태로 합치면 된다.

  • 코드 적용 예시

8.4 Image upload result

아래 그림은 위의 과정을 통해 추가한 .bmp 포맷의 이미지를 LCD 에 출력한 결과이다. 물론 gfx 예제에서 제공해주는 라이브러리를 조금 수정해야하긴 하는데, 일단 제대로 출력되는 것을 확인했음.

8.4.1 Notice

이 부분은 확실하진 않은데.. 위의 gfx 예제에서 .bmp 이미지를 출력을 담당하는 함수를 따라가다가 보면, 결국에는 nrf_gfx.c 파일에 정의된 nrf_gfx_bmp565_draw(...) 함수를 이용해 그림을 그리는 것을 확인할 수 있다.

그런데 본인의 경우는 그림의 width 값이 홀수일 때, 이미지가 정상적으로 출력되지 않는 문제가 있었다. (Python 으로 디버깅해보면 위에서 사용한 프로그램에서는 코드가 제대로 변환된 것 같음). 최종적으로는 문제가 뭔지 몰라서 width 값이 홀수인 이미지를 출력할 때, Python 이용해서 char 타입의 배열을 uint16_t 타입으로 합치는 단계에서 dummy column 을 하나 추가하거나 제거해서 짝수로 맞추는 방식으로 개발했음.


Reference

http://www.lcdwiki.com/3.2inch_SPI_Module_ILI9341_SKU:MSP3218

Comments