본문 바로가기

프로젝트/TFT LCD 한글 출력 (아두이노)

TFT LCD에서 SD카드 한글 출력 인덱스 사용( 속도 빨라짐) (6)

 

앞의 (5)번글에서 상당이 속도가 느렸다.

글자당 폰트파일 하나를 만드는 방식은 폰트를 찾을 때 한글코드로 바로 찾을 수 있는 장점이 있다.

예로 '가'는 EAB080으로 폰트 파일은  EAB080.utf 로 바로 찾을 수 있다.

여러가지 실험 끝에 파일 오픈에 매우 많은 시간이 소요 되었다. 그래서 글자마다 계속 하나씩 파일 오픈하니 속도가 느려질 수밖에 없었다. 

그래서 폰트 파일을 하나의 파일로 만들었다   Hangul.utf 파일을 프로그램 시작시 오픈 한 후 계속 사용하면

오픈에 소용되는 시간이 없어져 속도가 크게 개선 될것이다. 구조는 레코드당 ( 한글코드+폰트)로 만들었다.   

근데 문제는 한글코드로 폰트 위치 찾기였다.

일단 단순하게 레코드의 한글코드를  모두 비교하여 코드를 찾았다.  시간이 별로 개선이 없었다.

코드 찾는 시간이 너무 걸렸다.

UTF-8코는 중간 중간 비어 있어  탐색시간을 줄이는 메뚜기법도 아무 소용 없다. ㅠㅠ

(참고)   메뚜기 탐색은 먼저 Data의 중간 값과 비교 하여 작으면 Data범위가 앞쪽의 반(1/2)으로 준다,
            다시 이범위의 중간 값과 비교 하면  다 반으로(1/4) 준다...
            이렇게 비교하면 전체 비교 보다 휠씬 시간이 단축된다. Datark 100이고 35번째 자료라면
           50 -> 25 -> 35   (3번만에 찾음)    여기 폰트는 만 천개가 넘는다. 여기 적용하면
           10000 ->  5000 -> 2500->  1250 -> 625 -> 312 ->156 -> 78 -> 39 -> 19 -> 29 -> 34->36  -> 35
            평균 5000검색보다 엄청 효율적이다.  다만 Data가 연속적인 순번을 가져야 가능 하다.

그래서 계속 연구하다 임의적으로 순번을 갖는 Data를 만들기로 했다.

한글 UTF-8 은  0xE384B1 ~  0xED9EA3 (특수문자등을 추가하면 범위는 유동적임 )  가지고 

중간중간 많은 빈코드가 있다.    빈코드의 폰트를 채우면  연속적인 순번을  가지게 된다. 

하지만  파일이 너무 너무 크진다. SD공간이 넉넉하니 그냥 무시 해도 무방하지만.....

하지만 차후 여러개의 폰트파일 관리를 위하여  폰트파일은 순수 폰트정보만 있는 빈공간없이

비순차적으로 만들고 대신 4byte정수를 가지는 인덱스 파일을 만들었다.   

아두이노의  int는 2Byte임 C#은 4Byte 그래서 아두이노 코딩때는 long을 사용 해야함.

C#코딩부분은 int로 해야함.( 폰트파일, 인덱스파일 만들 때)

인텍스 파일의 빈 코드는 -1로 채웠다. ( 아무것이나 상관 없지만 그래도 폰트파일의 Index가

0부터 시작하니 중복을 피하기 위해... 작동에는 아무 상관 없음)

 

 (한글코드 - 0xE384B1)*4 하면 바로 코드에 대응하는 인텍스의  해당포인터( IndexIndex )가 된다.

 그 저장값이  폰트파일의 포인터이다( FontIndex )이다.  엄청 속도가 빨라진다.. 빨라졌다. .ㅎㅎㅎ

이정도 속도면 인젠 사용에 문제 없을 것이다.

코드에 폰트를 올리는 방법과 속도 차이 별로 없음

한글코드에서 폰트 얻는 과정 
Index의 Index    구하기    IndexIndex   (한글코드 - 0xE384B1)*4 
한글폰트의 Index 구하기 Index파일에서 FontIndex   = IndexFile.seek( IndexIndex  )
한글 폰트 얻기 Font파일에서 Font위치     = FontFile.seek(  FontIndex  )

       

 

그럼 동영상으로 속도 차이를 보시기 바랍니다.

앞글의  속도가 느린동영상은 맨 아래에 둘께요  

(1번 동영상 보기)

(  2번 동영상   툭수문자와 자유롭게 확대 축소가 가능한  )

 


속도가 느린 동영상보기

 


2번 동영상 아두이노 코드  (   Hangul_TFT class 제외 )


#define   _TFTLCD_      myLcd     // LCD 이름 지정   
#include "D:\\Program Files (x86)\\Arduino\\myHeader\\HanGul_TFT.H"                                                                                                                   // 한글 출력을 위한 라이브러리 파일
HanGul_TFT  ht;      //  클래스 생성

void setup()
{        
        ht.start();         //  한글 시작                                        

        myLcd.InitLCD();            
        myLcd.setRotation(3);   //3 가로방향  //2  세로방향
        myLcd.clrScr();                 
  
       ht.color(cYellow);
       ht.print(F("한글 English ☏☎ 123"),5,0);           //  5,0에 문자표시
       ht.print(F("한글 English ☏☎ 123"),5,20,2);      //   2배 표시
       ht.print(F("한글 English ☏☎ 123"),5,60,2,1);   //  가로 2배 세로 1배
       ht.print(F("한글 English ☏☎ 123"),5,80,1,2);   //   가로1배 세로 2배
       ht.print(F("한글 English ☏☎ 123"),5,120,1,3); //   가로 1배 세로 3배
       ht.print(F("한글 Eng ☏☎ 13"),5,180,3,1);        //    가로 3배 세로 1배
       ht.color(cWHITE);
       ht.print(F("한글출력 Demo"),5,210,2);      
       ht.color(cGREEN);
       ht.print(F("가로 세로 따로 조절 가능"),5,250,2);
       ht.print(F("보다 빠른 속도 개선"),5,290,2);  

 

       for(int i=0 ;i<480;i++)
      {
             myLcd.vertScroll(0,480,i);
             delay(5);  
        }

 

       ht.color( cGray);     
       for(int i=0 ;i<480;i++)  
      {
          if( i%2 ==1)myLcd.drawLine(i,0,i,320);
          myLcd.vertScroll(0,480,i);
          delay(1);  
       }
      ht.color( cBlack);
     myLcd.fillRect(0,0,480,320);
 
     ht.color(cWhite);
     for(int i=1 ;i<480;i++)
     {
         if( i==100 ) ht.print("아",140,100,3,3);
         if( i==200 )ht.print("두",190,100,3,3);
         if( i==300 ) ht.print("이",240,100,3,3);
         if( i==400 )ht.print("노",290,100,3,3);
         myLcd.vertScroll(0,480,i);
        delay(5);      
       }

   

      for(int i=100;i <=150 ; i++)
        {     
          ht.color(cYellow);
          myLcd.fillRect(100,i,380,i+5);
          ht.color(cWhite);   
          ht.print("아",140,100,3,3);
          ht.print("두",190,100,3,3);
           ht.print("이",240,100,3,3);
           ht.print("노",290,100,3,3);
 
           ht.color(cBlack);
          myLcd.fillRect(100,i,380,i+5);
        }
 

       for(int i=150;i >=100 ; i--)
       {     
          ht.color(cYellow);
          myLcd.drawRect(100,150,380,i);
           ht.color(cWhite);   
           ht.print("아",140,100,3,3);
           ht.print("두",190,100,3,3);
           ht.print("이",240,100,3,3);
           ht.print("노",290,100,3,3);
 
           ht.color(cBlack);
           myLcd.drawRect(100,150,380,i);
         }


          ht.color(cYellow);
          myLcd.drawRect(100,150,380,100);

          // ht.close();   //  사용 안해도 됨
}

void loop()

 
}