1. GMG12864 LCD
이전 글을 통하여, 라즈베리 파이 PICO 보드에서 16×2 형태의 LCD를 사용하는 방법을 소개한 바 있었다.
그런데 이러한 16×2 LCD는 저렴하고 사용하기도 쉽지만, 화면에 동시에 표시할 수 있는 글자의 수가 32자에 불과한 아쉬움이 있었다. 이 때문에, 좀 더 많은 글자를 한 번에 표시할 수 있는 디스플레이들을 찾게 되었는데, 그 과정에서, 다양한 사이즈의 OLED 장치와, 2.8인치로 화면이 크면서도 컬러까지 표시되는 TFT 디스플레이 사용법을 소개한 바 있었다. (https://kongyine.com/223261916154 )
그런데, 정작 LCD 자체로는 16×2대 비 더 커진 LCD를 한동안 찾지 못하다가, 다음과 같은 LCD를 발견하게 되었다. 이름은 GMG-12864-06D라는 제품으로, 화면의 크기는 58x28mm로 화면의 대각선 길이는 64mm로 약 2.53″에 해당되는 제품이다. 사용하는 드라이버는 ST7568R 이란 칩을 사용한다고 한다.
통신용 인터페이스는 SPI이다. (I2C 버전도 찾아보았으나, 이 제품 구입 시점에서는 구할 수 없었다.)
판매처에서 제시하는 디스플레이 해상도는 128×64로, 내장 폰트(8×8)를 이용하는 경우, 가로 16글자 x 세로 8줄을 동시 표시할 수 있어, 기존의 대표적인 LCD 장치 (16×2)에 비해 4배 많은 글자를 표시할 수 있고, 글자의 크기가 커서 읽기에 유리하고, 그래픽 명령어들도 지원하는 장점이 있다.
이 제품의 가격은 약 4500원 정도이며, 배송료를 포함하면 약 6000원 수준의 제품인데, 이 제품의 특징 중 하나는 COG(Circuit on Glass)라고 하며, 아마도 유리판에 회로를 형성한 특징이 있는 것 같다. 다만 실제에 있어 어떤 장점이 있는지는 명확하지 않다.
2. SPI Interface 핀 연결
이 제품의 후면 모양은 다음과 같으며,
통신용 인터페이스를 위한 단자는 다음과 같이 생겼는데,
SPI 접속에는 위의 사진 속의 CS~VSS 구간의 핀들이 사용되며, 각 핀들의 기능은 다음과 같다.
* CS : CS (Chip Select) – SPI 연결 시 연결된 장치 인식을 위한 핀
* RST(RSE로 표기하기도 한다.)
* RS(DC, Data, A0라고 표기하기도 한다.)
* SCL SPI의 SCK
* SI Data 입력 핀으로 SPI 채널의 TX에 연결
* VDD System 용 VCC로 3.3V 연결
* VSS GND
* A Backlight의 전원용 VCC (3.3V)
* K Backlight의 전원용 GND
참고로, 접속용 핀들 중 IC_SCL, IC_CSL, IC_SO, IC_SI 핀들은, 중국어 폰트 정보를 내장하고 있는 U1 칩을 사용하기 위한 핀들로 일반적인 SPI 접속에서는 사용하지 않는다.
3. 인터페이스 연결
다음과 같이 GMG-12864 LCD와, 피코 보드를 연결하여 SPI 통신을 준비하였다.
GMG-12864 LCD의 핀들은 피코 보드의 다음 핀들에 연결하였다.
SI : GP3
SCL : GP6
CS : GP13
RST : GP14
RS(DC) : GP15
VDD, A : 3.3V
VSS, K : GND
4. 라이브러리
Github에서 ST7565 용 Python 라이브러리를 검색하면 다음과 같은 결과를 얻는데, 나는 좀 더 직관적이고, 사용이 편리한 다음 라이브러리를 사용하였다.
선택한 항목을 들어가면 다음과 같이 st7565.py라는 라이브러리를 찾을 수 있는데, 이를 다운로드 또는 내용을 복사하여 동일한 이름으로 피코 보드에 저장해 주면 된다.
다만, 이 라이브러리를 사용하는 과정에서 내용상 오타가 있는 것을 발견되었는데, DISPLAY_OFF 부분의 지정 값을 “OxAE”로 바꾸어 주면 된다.
또한 이 라이브러리는 LCD의 화면 표시 설정을 라이브러리의 앞부분에 미리 지정해 두었는데,
먼저 해상도를 다음과 같이 지정해 두었다. 이 값을 변경하면 화면 표시가 깨어지므로 변경하면 안 된다.
(Note: 일부에서는 이 LCD를 132×64로 사용하는 것을 시도하는 경우도 있음.)
또한 LCD의 Contrast도 0x1B이 기본값으로 지정되어 있는데, 이 경우 너무 흐릿해서, 적절한 값으로 조정하는 게 필요하다.
사용 가능한 값은 0x10부터
0x1F까지인데, 0x1C나 0x1D 정도로 설정하면 적절해 보인다.
위에서 언급한 오류를 수정하고, Contrast도 0x1C로 수정한 수정본 라이브러리 파일을 여기 첨부해 둔다.
2de3c99b-acc5-4ab2-aaea-0e6ab119d41a”dc49c073613f38e4c92647794ba5d6a30e57aa4c87/EFsQbrZLxbfO9dhRLuoSggWaFwbSq-l_Y1wGJTkPkAUoGYm-VH0u6va9C-81xil5qx6dQU7W-J0EsY4pkA95invBcPH_/st7565.py
5. 주요 동작 Demo
이 라이브러리를 이용하여 LCD에 사용할 수 있는 주요 명령들은 다음과 같다.
display_init( ) –> display를 초기화해주고, 기존에 내려진 명령들을 무효화 시킨다.
display.reset( ) –> LCD 동작을 멈추는 효과
display.fill(0) –> LCD 화면을 지운다.
display.fill(1) –> LCD 화면을 지우되 반전상태를 만든다.
display.text(“문자열”, 가로축 좌표, 세로축 좌표, 1) –> 문자열을 표시한다.
display.show( ) –> 화면에 반영된 것을 나타내주는 명령
아무리 출력을 해도, LCD에 반영되는 것은 이 명령 이후에 표시에 반영된다.
display.rect(시작 X, 시작 Y, X 방향 길이, 세로방향 길이, 1)
–> 시작점으로부터 가로 세로방향으로 주어진 숫자 크기로 사각형을 그린다.
가로방향과 세로방향 길이는 상대 좌표임
display.line(시작점 X, 시작점 Y, 끝점 X, 끝점 Y, 1) –> 선 그리기 명령이며 절대좌표임
display.pixel(X, Y, 1) –> 특정
display.write_cmd(cmd) –> 제어 명령어 입력 (사전에 정의된 16진수를 입력하면 된다.)
라이브러리에 정의된 명령부호를 이용하여 LCD 제어에 사용
이러한 명령어를 이용하여, 다음과 같은 코드를 만들어 각각의 동작을 시간차를 두고 실행해 보았으며,
import machine
import utime
from st7565 import ST7565
sck=machine.Pin(6)
tx=machine.Pin(3)
#rx=machine.Pin(4) # 이 핀을 실제로는 연결할 필요는 없으나 SPI 기본 설정 형식때문에 지정은 필요
CS = machine.Pin(13, machine.Pin.OUT)
A0 = machine.Pin(15, machine.Pin.OUT)
RST = machine.Pin(14, machine.Pin.OUT)
spi = machine.SPI(0, baudrate=50000000, sck=sck, mosi=tx) #, miso=rx) # miso 부분을 포함하거나 삭제하거나 문제없음
#spi = machine.SPI(0, baudrate=1000000, polarity=1, phase=1) # SPI를 이렇게 설정해도 동작
display = ST7565(spi, A0, CS, RST)
display.display_init() # LCD 설정 명령어들을 초기화
display.write_cmd(0xA6) # Display Normal - 반전 없는 정상 화면
display.text("Normal from 0,0 ", 0, 0, 1)
display.text("1234567890123456", 0, 8, 1)
display.text("234567890123456", 0, 16, 1)
display.text("34567890123456", 0, 24, 1)
display.text("4567890123456", 0, 32, 1)
display.text("567890123456", 0, 40, 1)
display.text("67890123456", 0, 48, 1)
display.text("7890123456", 0, 56, 1)
display.text("890123456", 0, 64, 1)
display.show()
utime.sleep(5)
display.fill(0) #화면을 Clear
display.text("Normal from 4,0", 4, 0, 1)
display.text("1234567890123456", 4, 8, 1)
display.text("234567890123456", 4, 16, 1)
display.text("34567890123456", 4, 24, 1)
display.text("4567890123456", 4, 32, 1)
display.text("567890123456", 4, 40, 1)
display.text("67890123456", 4, 48, 1)
display.text("7890123456", 4, 56, 1)
display.text("890123456", 4, 64, 1)
display.show()
utime.sleep(5)
display.fill(0)
display.write_cmd(0xA7) # 화면 반전
display.text("Reverse 4,0", 4, 0, 1)
display.text("1234567890123456", 4, 8, 1)
display.text("23456789012345", 4, 16, 1)
display.show()
utime.sleep(5)
display.write_cmd(0xA6) # 정상 화면으로 전환
display.fill(0)
display.rect(4, 0, 124, 64, 1)
display.show()
utime.sleep(2)
display.rect(14, 10, 104, 44, 1)
display.show()
utime.sleep(2)
display.line(20, 14, 110, 14, 1)
display.show()
utime.sleep(2)
display.line(20, 45, 110, 45, 1)
display.show()
utime.sleep(2)
display.line(20, 14, 110, 45, 1)
display.show()
utime.sleep(2)
display.line(110, 14, 20, 45, 1)
display.show()
utime.sleep(2)
display.pixel(40, 35, 1)
display.pixel(45, 35, 1)
display.pixel(50, 35, 1)
display.show()
utime.sleep(5)
display.text("Display", 30, 20, 1)
display.text("Off & On", 30, 30, 1)
display.show()
utime.sleep(4)
display.write_cmd(0xAE) #LCD 화면표시 끄기 (Backlight는 유지)
utime.sleep(3)
display.write_cmd(0xAF) #LCD 화면 표시 켜기
utime.sleep(3)
실제 동작 모습은 다음과 같다.
한 가지 뜻밖의 결과는 이 LCD가 128×64 화소이기는 하지만, 가로축으로 0~3번 화소가 표시되지 않아, 0,0부터 출력하면 글자 왼쪽 부분이 깨어지고, 가로축 4번 화소부터 사용하여야 정상적으로 출력이 가능하였다.
(가로축으로 4~127, 세로축으로는 0~64까지 출력되어, 가로축으로 15자, 세로축으로 8줄을 출력할 수 있었다.)


