아두이노 Mega 사용시 주의할 점
SD카드를 사용 하려면 Uno와 SPI핀 번호가 달라 다음 2가지 중
하나의 방법으로 해야 한다.
쉴드를 아두이노 Mega에서 SD카드 사용을 위한 방법(Uno와 SPI핀 다름) | |
Uno의 SPI핀번호에 해당하는 핀을 SPI핀과 연결함 | 번거롭다(납땜이 필요) 핀4개 사용불가 |
SD모듈을 따로 구입하여 사용한다. | 얼마 안함 저렴함.( 추천 ) |
폰트화일과 인덱스파일은 스스로 만들어 보세요. 규격은 여기로 대부분의 경우 따로 폰트가 필요 없는 Hangul_Direct.H를 Mega보드(120자 정도)와 같이 사용 하면 됩니다.
HanGul.SD ver 1.0 | ||
|
// HanGul.SD ver 1.0 아두이노용 한글 출력 클래스
//
// 제작자 : 신 옥 진
//
// 재배포 금지 링크를 사용 하세요.
//
// Index1 구조 ( 4 Byte Record ) [폰트offset : 4byte Long]
// Index2 구조 ( 8 Byte Record ) [폰트코드 : 4byte Long][폰트offset : 4byte Long]
//
// Index2 사용시 소스코드에 #define _INDEX_2_ 코드 넣어야 함
//
// < 소스 코드 순서 >
// #define _TFTLCD_ myLcd // myLcd는 원하는 이름으로 하고 include 앞에 선언
// #define _INDEX_TYPE_2_ // 인덱스방법 2로 사용시에 만 (없을시 방법1)
// #include "c:\\Arduino\\HanGul_TFT.H" // 헤더파일 전체 경로
// HanGul_TFT ht; // 한글출력 클래스
//
// 폰트파일과 인덱스파일은 SD카드 "UTF_8//" 에 있는 것으로 함
// 바꿀려면 아래 define 부분을 수정하면 됨 (주의) 디렉토리 표시가 윈도우와 다름 '\'아니고 '/'사용
#ifndef _Hangul_TFT_
#define _Hangul_TFT_
#ifdef _INDEX_2_
#define _INDEX_FILE_ "UTF_8//fIndex2.idx" // 인덱스2 파일
#else
#define _INDEX_FILE_ "UTF_8//fIndex1.idx" // 인댁스1 파일
#endif
#define _FONT_FILE_ "UTF_8//Hangul.utf" // 폰트 파일
#include <SPI.h>
#include <SD.h>
#include <Adafruit_GFX.h>
#include <UTFTGLUE.h>
#ifndef _MY_COLOR_ // Color 정의
#define _MY_COLOR_
#define cBlack 0x0000
#define cWhite 0xFFFF
#define cRed 0xF800
#define cGreen 0x0400
#define cBlue 0x001F
#define cSilver 0xC618
#define cGray 0x8410
#define cMaroon 0x8000
#define cYellow 0xFFE0
#define cOlive 0x8400
#define cLime 0x07E0
#define cAqua 0x07FF
#define cTeal 0x0410
#define cNavy 0x0010
#define cFuchsia 0xF81F
#define cPurple 0x8010
#define cTransparent 0xFFFFFFFF
#endif
UTFTGLUE _TFTLCD_(0x9488,A2,A1,A3,A4,A0);
#define BASE_CODE 0xE28A82
String readLine( File inf )
{
char buff[50];
int idx=0;
while(true)
{
byte b,b2;
b=inf.read();
if( b == 0x0d )
{
b2= inf.read();
if( b2 == 0x0a )
{
buff[idx]= 0;
return( String( buff ) );
}
buff[idx++] = b;
buff[idx++] = b2;
}
else buff[idx++] =b;
}
}
struct Box // 문자열의 사각형 좌표
{
int x,y,x2,y2;
} ;
class HanGul_TFT
{
private:
unsigned short _HANGUL_FONT[16]; // 폰트 저장변수
File _Index_File_,_Font_File_; // 인덱스파일 , 폰트파일
int _color=cWhite; // 폰트색상
int _bkColor = cBlack; // 폰트배경색
public:
Box box;
void start(); // 한글클래스 시작
void end(); // 한글클래스 종료 : 사용 안해도 됨
void color(int _c ) ; // 글자색
void color(int _c ,int _bk); // 글자색, 배경색
void fill(int _c); // 바로 앞에 출력한 문자열을 _c 색으로 채우기
void fill() ; // 배경색으로 채우기
void rect(int _c); // 바로 앞에 출력한 문자열에 _c 색으로 테두리 그리기
void rect(); // 문자색으로 테두리 그리기
void under(int _c); // 바로 앞에 출력한 문자열에 문자색으로 밑줄 그리기
void under(); // 문자색으로 밑줄 그리기
void print( String s, int x, int y , int mx, int my ); // x,y좌표에 가로 mx배 ,세로 my배로 문장 출력
void print( String s,int x, int y ); // 1배
void print( String s,int x, int y ,int m ); // m배
private:
void _setDot_Func( int col, int row, int x, int y,int mx,int my ,int c ); //폰트의 1bit에 해당하는 점 그리기
void _drawFont_Func( int x, int y, int mx , int my);
#ifdef _INDEX_2_
void getFont( long code );
#endif
};
void HanGul_TFT::start()
{
#ifdef _Mega_
SD.begin(53); // mega
#else
SD.begin(10); // uno
#endif
pinMode(A0, OUTPUT);
digitalWrite(A0, HIGH); // TFT LCD 시작
HanGul_TFT::_Index_File_ = SD.open(_INDEX_FILE_); // 인덱스 파일 오픈
HanGul_TFT::_Font_File_ = SD.open(_FONT_FILE_); // 폰트 파일 오픈
}
void HanGul_TFT::end() // 사용 안해도 됨
{
_Index_File_.close();
_Font_File_.close();
}
void HanGul_TFT::color(int _c )
{
_color=_c;
}
void HanGul_TFT::color(int _c ,int _bk)
{
_color=_c;
_bkColor=_bk;
}
void HanGul_TFT::fill(int _c) // 문자열을 _c색상으로 채우기
{
_TFTLCD_.setColor( _c );
_TFTLCD_.fillRect(box.x,box.y,box.x2,box.y2);
}
void HanGul_TFT::fill() { fill(_bkColor); } // 문자열을 배경색상으로 채우기 // 문자열 지우기에 이용
void HanGul_TFT::rect(int _c) // _c색상으로 문자열의 외곽선 그리기
{
_TFTLCD_.setColor( _c );
_TFTLCD_.drawRect(box.x,box.y,box.x2,box.y2);
}
void HanGul_TFT::rect() { rect(_color); } // 문자색상으로 문자열의 외곽선 그리기
void HanGul_TFT::under(int _c) // 문자열에 _c색상으로 밑줄
{
_TFTLCD_.setColor( _c );
_TFTLCD_.fillRect(box.x, box.y2-2,box.x2,box.y2+1);
}
void HanGul_TFT::under(){ under(_color); } // 문자열에 문자색상으로 밑줄
void HanGul_TFT::print( String s,int x, int y ) { print( s, x, y , 1 ,1 ); }
void HanGul_TFT::print( String s,int x, int y ,int m ) { print( s, x, y , m, m ); }
void HanGul_TFT::_setDot_Func( int col, int row, int x, int y,int mx,int my ,int c )
{
_TFTLCD_.setColor( c );
for(int dx=0 ; dx< mx ;dx++)
for( int dy=0;dy<my;dy++)
_TFTLCD_.drawPixel( x+col*mx+dx ,y+row*my+dy );
}
void HanGul_TFT::_drawFont_Func( int x, int y, int mx , int my)
{ // 문자(1자) 그리기
for( int row=0; row< 16 ; row++) // 폰트 bit 세로방향
{
for(int col=0;col<16;col++) // 폰트 bit 가로방향
{
if( _HANGUL_FONT[row] & 0b1000000000000000 ) _setDot_Func( col, row, x, y, mx, my, _color);
else _setDot_Func( col, row, x, y, mx, my, _bkColor );
_HANGUL_FONT[row] <<= 1; // bit가 1이면 점그리기 함수 호출
}
}
}
#ifdef _INDEX_2_ // Index 방법 2번이면
void HanGul_TFT::getFont( long code )
{
long low=0, high = 11746;
long now = 5873;
long hCode,hIdx;
long temp=-1;
while(true)
{
_Index_File_.seek(now*8);
_Index_File_.read(&hCode,4); // 한글코드 읽기
if( hCode == code )
{
_Index_File_.seek(now*8+4);
_Index_File_.read(&hIdx,4);
_Font_File_.seek(hIdx);
_Font_File_.read(_HANGUL_FONT ,32);
return;
}
else if( hCode > code ) high = now;
else low = now;
now=(low+high)/2;
if( now==temp) return;
else temp=now;
}
}
#endif
void HanGul_TFT::print( String s, int x, int y , int mx, int my )
{
box.x=x;
box.y=y;
box.y2=y+16*my-1;
_TFTLCD_.setTextSize(my*2);
for( int p=0; p <s.length() ;p++)
{
if( isAscii(s[p]) )
{
if( s[p]==0x0d )break;
_TFTLCD_.setCursor(x,y);
_TFTLCD_.setTextColor(_color,_bkColor);
_TFTLCD_.println(s[p]);
if( s[p]==0x20 ) x+=8*my;
else x+=12*my;
}
else
{
_TFTLCD_.setColor( _color) ;
long code =byte(s[p]);
code = code << 8;
code+=byte(s[p+1]);
code = code << 8;
code+=byte(s[p+2]);
#ifdef _INDEX_2_
getFont(code);
#else
code-= BASE_CODE;
_Index_File_.seek(code*4);
long fPoint;
_Index_File_.read( &fPoint,4);
_Font_File_.seek( fPoint);
_Font_File_.read( _HANGUL_FONT ,32);
#endif
_drawFont_Func( x, y, mx, my) ;
x+=16*mx;
p+=2;
} // isASCII else
}// p 스트링 길이 반복
box.x2=x-1;
}
/*
void HanGul_TFT::print( String s, int x, int y , int mx, int my )
{ // 문자열을 그리는 함수
box.x=x;
box.y=y; // 문자열 상자박스 좌표
box.y2=y+16*my-1;
_TFTLCD_.setTextSize(my*2); // TFT LCD 내장 폰트 사이즈 설정
for( int p=0; p <s.length() ;p++) //문자열 가로방향으로 진행
{
if( isAscii(s[p]) ) // 문자가 아스키코드(내장폰트)
{
if( s[p]==0x0d )break; // 문자열 끝이면 빠져 나감
_TFTLCD_.setCursor(x,y);
_TFTLCD_.setTextColor(_color,_bkColor); // 내장폰트 색깔
_TFTLCD_.println(s[p]);
if( s[p]==0x20 ) x+=8*my; //공백은 가로로 8dot 이동
else x+=12*my; //가로로 16Dot 이동
}
else
{
_TFTLCD_.setColor( _color) ;
long code =byte(s[p]); // 3Byte 문자(UTF-8)
code = code << 8; // 상위 Byte에서 하위byte로 읽어오기
code+=byte(s[p+1]);
code = code << 8;
code+=byte(s[p+2]);
code-= BASE_CODE;
_Index_File_.seek(code*4);
long fPoint;
_Index_File_.read( &fPoint,4);
_Font_File_.seek( fPoint);
_Font_File_.read( _HANGUL_FONT ,32);
//}
_drawFont_Func( x, y, mx, my) ;
x+=16*mx;
p+=2;
} // isASCII else
}// p 스트링 길이 반복
box.x2=x-1;
} */
#endif
|
Hangul_SD.ino | |
#define _TFTLCD_ myLcd // TFT LCD 이름 정의/ #define _INDEX_2_ // 인덱스방법 2로 사용시 // #define _Mega_ // Mega 사용시 #include "D:\\Program Files (x86)\\Arduino\\myHeader\\HanGul_SD.H" HanGul_TFT ht; // 한글출력 클래스 void setup() { Serial.begin(9600); unsigned long startTime=millis(); Serial.println(startTime); ht.start(); myLcd.InitLCD(); myLcd.setRotation(3); //3 가로 480x320 //2 세로 320x480 myLcd.clrScr(); ht.color(cWhite,cBlack); ht.print(F("┏┓┛┗┣┳┫┻╋┠┯"),5,0); ht.color(cWhite,cRed); ht.print(F("★○●◎◇◆"),5,20,2); ht.color(cRed,cBlack); ht.print(F("한글 English ☏☎ 123"),5,60,2,1); ht.rect(cRed); ht.color(cBlack,cYellow); ht.print(F("English ☏☎ 123"),5,80); ht.color(cWhite,cBlack); #ifdef _INDEX_2_ ht.print(F("인 덱 스 방 법 2"),5,120,1,2); #else ht.print(F("인 덱 스 방 법 1"),5,120,1,2); #endif ht.color(cRed); ht.print(F(" ☏☎ 123"),ht.box.x2,120,1,2); ht.color(cBlue,cBlack); ht.rect(cRed); ht.print(F("한글 Eng ☏☎ 13"),5,180,3,1); ht.color(cYellow,cRed); ht.print(F("한글출력 Demo"),5,210,2); ht.color(cWhite,cBlack); ht.print(F("가로 세로 따로 조절 가능"),5,250,2); ht.under(cRed); ht.print(F("보다 빠른 속도 개선Speed"),5,290,2); unsigned long endTime=millis(); Serial.println(endTime); Serial.println(endTime-startTime); } void loop() { } |
'프로젝트 > TFT LCD 한글 출력 (아두이노)' 카테고리의 다른 글
필요한 폰트를 메모리에 두지 말고 파일에 담아 사용하자. (0) | 2022.08.20 |
---|---|
F연산자와 readLine 함수 사용하여 메모리 확보하기 (0) | 2022.08.20 |
Hangul_Direct.h ( 필요한 폰트만 코드에 삽입 ) (10) | 2022.08.20 |
한글CLASS 메소드 (0) | 2022.08.14 |
한글출력 Class 폰트파일, 인덱스 규격 (0) | 2022.08.14 |