[HoloEye] 06_IPS TFT LCD MIRROR 모드
1. TFT_eSPI.h 라이브러리
이전부터 한창 활용했던 TFT_eSPI.h 라이브러리를 사용하는데 LCD 라이브러리들에 흔하디 흔한 MIRROR 또는 FLIP 함수가 없는 것이 아닌가!? 한참 찾고 검색했는데 혹시나 아시는 분 있으면 리플 부탁 드립니다. (–)(__)
그래서 이게 없을리가 없는데 없는데 하면서 라이브러리 코드까지 싹다 뒤졌는데 진짜 구현을 안해놨다.
쿨럭…
어쩔 수 없이 현재 사용하고 있는 TFT LCD 240x240 ST7789 드라이버의 데이터시트를 보고 기능을 직접 추가하기로 했다.
3시간 정도 검색하다가 라이브러리까지 싹 뒤진 것 같은데 진짜 없을 줄이야…
2. ST7789 데이터시트
https://www.rhydolabz.com/documents/33/ST7789.pdf
https://www.waveshare.com/w/upload/a/ae/ST7789_Datasheet.pdf
위 링크의 ST7789 데이터시트를 보면 DDRAM을 통해서 MIRROR 기능을 제공하고 있는데 레지스터 이름이 MADCTR 이다. (MAD가 들어가서 그런가 왠지 친근…)
MADCTR 레지스터 Parameter MV, MX, MY에 따라서 회전과 미러를 동시에 적용할 수 있다.
다행이 레지스터들은 코드상 #Define 을 잘해놨음
3. ST7789_Rotation.h
라이브러리에서 ST7789_Rotation.h 파일을 수정하면 된다.
참조경로는 아두이노 라이브리에 있다.
\Arduino\libraries\TFT_eSPI\TFT_Drivers
기존에 회전에 관련된 함수가 있는데 아두이노에서 다음과 같이 사용된다.
// TFT Setting
TFT_eSPI tft = TFT_eSPI();
tft.setRotation(0); // 0-3
이게 웃긴게 LCD 회전동작 4방향만 구현되어 있다. 때문에 입력파라메터가 0,1,2,3 까지만 가능하다.
여기에 MIRROR 기능을 추가하여 4,5,6,7 기능을 추가했다.
터치까지 offset 조절해서 구현하는 건 제외했다.(현재 만들고 있는 holo weather에는 필요 없음)
ST7789_Rotation.h 전체 코드
// This is the command sequence that rotates the ST7789 driver coordinate frame
writecommand(TFT_MADCTL);
rotation = m % 8;
switch (rotation) {
case 0: // Portrait
#ifdef CGRAM_OFFSET
if (_init_width == 135)
{
colstart = 52;
rowstart = 40;
}
else if(_init_height == 280)
{
colstart = 0;
rowstart = 20;
}
else if(_init_width == 172)
{
colstart = 34;
rowstart = 0;
}
else if(_init_width == 170)
{
colstart = 35;
rowstart = 0;
}
else
{
colstart = 0;
rowstart = 0;
}
#endif
writedata(TFT_MAD_COLOR_ORDER);
_width = _init_width;
_height = _init_height;
break;
case 1: // Landscape (Portrait + 90)
#ifdef CGRAM_OFFSET
if (_init_width == 135)
{
colstart = 40;
rowstart = 53;
}
else if(_init_height == 280)
{
colstart = 20;
rowstart = 0;
}
else if(_init_width == 172)
{
colstart = 0;
rowstart = 34;
}
else if(_init_width == 170)
{
colstart = 0;
rowstart = 35;
}
else
{
colstart = 0;
rowstart = 0;
}
#endif
writedata(TFT_MAD_MX | TFT_MAD_MV | TFT_MAD_COLOR_ORDER);
_width = _init_height;
_height = _init_width;
break;
case 2: // Inverter portrait
#ifdef CGRAM_OFFSET
if (_init_width == 135)
{
colstart = 53;
rowstart = 40;
}
else if(_init_height == 280)
{
colstart = 0;
rowstart = 20;
}
else if(_init_width == 172)
{
colstart = 34;
rowstart = 0;
}
else if(_init_width == 170)
{
colstart = 35;
rowstart = 0;
}
else
{
colstart = 0;
rowstart = 80;
}
#endif
writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_COLOR_ORDER);
_width = _init_width;
_height = _init_height;
break;
case 3: // Inverted landscape
#ifdef CGRAM_OFFSET
if (_init_width == 135)
{
colstart = 40;
rowstart = 52;
}
else if(_init_height == 280)
{
colstart = 20;
rowstart = 0;
}
else if(_init_width == 172)
{
colstart = 0;
rowstart = 34;
}
else if(_init_width == 170)
{
colstart = 0;
rowstart = 35;
}
else
{
colstart = 80;
rowstart = 0;
}
#endif
writedata(TFT_MAD_MV | TFT_MAD_MY | TFT_MAD_COLOR_ORDER);
_width = _init_height;
_height = _init_width;
break;
case 4:
#ifdef CGRAM_OFFSET
if (_init_width == 135)
{
colstart = 52;
rowstart = 40;
}
else if(_init_height == 280)
{
colstart = 0;
rowstart = 20;
}
else if(_init_width == 172)
{
colstart = 34;
rowstart = 0;
}
else if(_init_width == 170)
{
colstart = 35;
rowstart = 0;
}
else
{
colstart = 0;
rowstart = 0;
}
#endif
writedata(TFT_MAD_MX | TFT_MAD_COLOR_ORDER);
_width = _init_width;
_height = _init_height;
break;
case 5:
#ifdef CGRAM_OFFSET
if (_init_width == 135)
{
colstart = 40;
rowstart = 53;
}
else if(_init_height == 280)
{
colstart = 20;
rowstart = 0;
}
else if(_init_width == 172)
{
colstart = 0;
rowstart = 34;
}
else if(_init_width == 170)
{
colstart = 0;
rowstart = 35;
}
else
{
colstart = 80;
rowstart = 0;
}
#endif
writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_MV | TFT_MAD_COLOR_ORDER);
_width = _init_height;
_height = _init_width;
break;
case 6:
#ifdef CGRAM_OFFSET
if (_init_width == 135)
{
colstart = 53;
rowstart = 40;
}
else if(_init_height == 280)
{
colstart = 0;
rowstart = 20;
}
else if(_init_width == 172)
{
colstart = 34;
rowstart = 0;
}
else if(_init_width == 170)
{
colstart = 35;
rowstart = 0;
}
else
{
colstart = 0;
rowstart = 80;
}
#endif
writedata(TFT_MAD_MY | TFT_MAD_COLOR_ORDER);
_width = _init_width;
_height = _init_height;
break;
case 7:
#ifdef CGRAM_OFFSET
if (_init_width == 135)
{
colstart = 40;
rowstart = 52;
}
else if(_init_height == 280)
{
colstart = 20;
rowstart = 0;
}
else if(_init_width == 172)
{
colstart = 0;
rowstart = 34;
}
else if(_init_width == 170)
{
colstart = 0;
rowstart = 35;
}
else
{
colstart = 0;
rowstart = 0;
}
#endif
writedata(TFT_MAD_MV | TFT_MAD_COLOR_ORDER);
_width = _init_height;
_height = _init_width;
break;
}
기존에서 수정된 부분만 간단히 보면
- 회전방향이 0-3에서 0-7로 늘어났으므로 %3 에서 %7로 변경
rotation = m % 8;
- MIRROR 가 적용된 각 회전방향에 따른 case 문 추가
case 4:
writedata(TFT_MAD_MX | TFT_MAD_COLOR_ORDER);
_width = _init_width;
_height = _init_height;
break;
case 5:
writedata(TFT_MAD_MX | TFT_MAD_MY | TFT_MAD_MV | TFT_MAD_COLOR_ORDER);
_width = _init_height;
_height = _init_width;
break;
case 6:
writedata(TFT_MAD_MY | TFT_MAD_COLOR_ORDER);
_width = _init_width;
_height = _init_height;
break;
case 7:
writedata(TFT_MAD_MV | TFT_MAD_COLOR_ORDER);
_width = _init_height;
_height = _init_width;
break;
- MIRROR 적용으로 case 5, case 7 offset 변경
case 5:
else
{
colstart = 80;
rowstart = 0;
}
case 7:
else
{
colstart = 0;
rowstart = 0;
}
찾는게 어려웠지 코드 수정은 쏘 심플!!
다시 빌드해서 동작시켰는데 잘 된다
현재 실시간 날씨 현황을 홀로큐브로 동작시켜서 뿌려줄려고 만들고 있는데 완성되면 간단히 공유해보겠다.
끝 :)
도움이 되셨다면 더 좋은 정보 공유를 위해 광고 클릭 부탁 드립니다 :)
0 댓글