だいぶ前に買った2.4インチTFT液晶ディスプレイ 

 

 あれはまだArduinoが流行りだした黎明期。 バンコクの秋葉原ことバンモー地区でこの液晶ディスプレイを見つけた。

商品名は、2.4" TFT LCD Shield+Touch Panel Display With SD Reader for Arduino UNO と書かれている。

値段は370バーツ。 今となっては高い気もするが、当時では安く感じたので買ったのだろう。

で、付属品はタッチペンのみ。 そう、説明書もソフトウェアも何もない。

 

 裏面を見ると、Arduino UNOの入出力ポートと合うように配置されたピンがある。 つまりはこれをArduino UNOにパイルダーオンさせて使うようになっている。

もちろん繋げたからってすぐに使わるわけではない。 当時はまだ情報も少なかったから苦労したが、どうやらこのディスプレイの制御ICは"ILI9341"っぽいことがわかった。 定番っちゃ定番よね。

 

 後はライブラリなどのソフトウェアをダウンロードしてインストールしてプログラミングすればよい。 だけだと終わっちゃうので、どれだけ道を外した使い方ができるか。 そこを徹底的に検証していきたい。 サンプルプログラムだけを動かして満足するキャッスルではないのだよ。

 

 さて、商品名にも書かれているとおり、Arduino UNO で使う事を前提に設計されている。 このUNOは当然だがUNO R3のことだ。 なのでArduino UNO R4では動かない、というかコンパイルすらできない。 まずはUNO R4で動くようにしてみようと思う。

 

ILI9341ドライバーのライブラリをインストールすると、サンプルプログラムがいくつか入っている。 ほとんどのサンプルは、超便利ライブラリのAdafruit_GFX.hをつかっているのだが、最初のサンプルだけは一切ライブラリを使うことなく、全てをマニュアルで制御している。 うん、これだ。 やっぱオートマよりマニュアルの方が技術は上がるっていうしね。

 

 マニュアル制御で用意されているサンプルプログラムは、Arduino UNO R3用とMEGA2560用の二つ。

それをチャチャチャーっと改造して、とりあえずオールマイティプログラムにしてみた。 プログラム自体は下に掲載しておく。

 オールマイティと言うのには理由があって、このディスプレイと接続できるArduinoボードの何でも使えるようになっているから。

キャッスルが検証した中では、

Arduino UNO R3

Arduino MEGA2560

Arduino DUE

Arduino UNO R4 MINIMA

Arduino UNO R4 WiFi

の全てで動作は確認できた。 一応はね・・・

 

プログラムの内容は、ディスプレを初期化して、全画面ベタ塗りで5色、ランダムの大きさの4角形を300回描画、その処理にかかった時間をシリアルモニターで表示。

これからの検証はこのサンプルプログラムを基準にしていこうと思う。

#define LCD_RD   A0
#define LCD_WR   A1     
#define LCD_RS   A2        
#define LCD_CS   A3       
#define LCD_REST A4

void Lcd_Writ_Bus(unsigned char d)
{
  digitalWrite(8, d & B00000001);
  digitalWrite(9, d & B00000010);
  digitalWrite(2, d & B00000100);
  digitalWrite(3, d & B00001000);
  digitalWrite(4, d & B00010000);
  digitalWrite(5, d & B00100000);
  digitalWrite(6, d & B01000000);
  digitalWrite(7, d & B10000000);

  digitalWrite(LCD_WR, LOW);
  digitalWrite(LCD_WR, HIGH);
}

void Lcd_Write_Com(unsigned char VH)  
{   
  digitalWrite(LCD_RS, LOW);
  Lcd_Writ_Bus(VH);
}

void Lcd_Write_Data(unsigned char VH)
{
  digitalWrite(LCD_RS, HIGH);
  Lcd_Writ_Bus(VH);
}

void Address_set(unsigned int x1,unsigned int y1,unsigned int x2,unsigned int y2)
{
  Lcd_Write_Com(0x2a);
  Lcd_Write_Data(x1>>8);
  Lcd_Write_Data(x1);
  Lcd_Write_Data(x2>>8);
  Lcd_Write_Data(x2);

  Lcd_Write_Com(0x2b);
  Lcd_Write_Data(y1>>8);
  Lcd_Write_Data(y1);
  Lcd_Write_Data(y2>>8);
  Lcd_Write_Data(y2);

  Lcd_Write_Com(0x2c);               
}

void Lcd_Init(void)
{
  digitalWrite(LCD_REST, HIGH);
  delay(5); 
  digitalWrite(LCD_REST, LOW);
  delay(15);
  digitalWrite(LCD_REST, HIGH);
  delay(15);

  digitalWrite(LCD_CS, HIGH);
  digitalWrite(LCD_WR, HIGH);
  digitalWrite(LCD_CS, LOW);

  Lcd_Write_Com(0xCB);    //Power control A (CBh)
  Lcd_Write_Data(0x39); 
  Lcd_Write_Data(0x2C); 
  Lcd_Write_Data(0x00); 
  Lcd_Write_Data(0x34); 
  Lcd_Write_Data(0x02); 

  Lcd_Write_Com(0xCF);    //Power control B (CFh)
  Lcd_Write_Data(0x00); 
  Lcd_Write_Data(0X81); 
  Lcd_Write_Data(0X30); 

  Lcd_Write_Com(0xE8);    //Driver timing control A (E8h)
  Lcd_Write_Data(0x84); 
  Lcd_Write_Data(0x11); 
  Lcd_Write_Data(0x7A); 

  Lcd_Write_Com(0xEA);    //Driver timing control B (EAh)
  Lcd_Write_Data(0x66); 
  Lcd_Write_Data(0x00); 

  Lcd_Write_Com(0xED);    //Power on sequence control (EDh)
  Lcd_Write_Data(0x55); 
  Lcd_Write_Data(0x01); 
  Lcd_Write_Data(0X23); 
  Lcd_Write_Data(0X01); 

  Lcd_Write_Com(0xF7);    //Pump ratio control (F7h)
  Lcd_Write_Data(0x10); 

  Lcd_Write_Com(0xC0);    //Power control 
  Lcd_Write_Data(0x23);   //VRH[5:0] 

  Lcd_Write_Com(0xC1);    //Power control 
  Lcd_Write_Data(0x10);   //SAP[2:0];BT[3:0] 

  Lcd_Write_Com(0xC5);    //VCM control 
  Lcd_Write_Data(0x3e);   //Contrast
  Lcd_Write_Data(0x28); 

  Lcd_Write_Com(0xC7);    //VCM control2 
  Lcd_Write_Data(0x86);   //--

  Lcd_Write_Com(0x36);    // Memory Access Control 
  Lcd_Write_Data(0x48);   

  Lcd_Write_Com(0x21);    //Display Inversion ON 

  Lcd_Write_Com(0x3A);    
  Lcd_Write_Data(0x55); 

  Lcd_Write_Com(0xB1);    
  Lcd_Write_Data(0x00);  
  Lcd_Write_Data(0x18); 

  Lcd_Write_Com(0xB6);    // Display Function Control 
  Lcd_Write_Data(0x08); 
  Lcd_Write_Data(0x82);
  Lcd_Write_Data(0x27);  

  Lcd_Write_Com(0x11);    //Exit Sleep 
  delay(120); 
  Lcd_Write_Com(0x29);    //Display on 
}

void H_line(unsigned int x, unsigned int y, unsigned int l, unsigned int c)                   
{ 
  unsigned int i, j;
  digitalWrite(LCD_RS, HIGH);
  digitalWrite(LCD_CS, LOW);
  l = l + x;
  Address_set(x, y, l, y);
  j = l * 2;
  for(i = 1; i <= j; i++)
    Lcd_Write_Data(c);
  digitalWrite(LCD_CS, HIGH);   
}

void V_line(unsigned int x, unsigned int y, unsigned int l, unsigned int c)                   
{ 
  unsigned int i, j;
  digitalWrite(LCD_RS, HIGH);
  digitalWrite(LCD_CS, LOW);
  l = l + y;
  Address_set(x, y, x, l);
  j = l * 2;
  for(i = 1; i <= j; i++)
    Lcd_Write_Data(c);
  digitalWrite(LCD_CS, HIGH);   
}

void Rect(unsigned int x,unsigned int y,unsigned int w,unsigned int h,unsigned int c)
{
  H_line(x  , y  , w, c);
  H_line(x  , y+h, w, c);
  V_line(x  , y  , h, c);
  V_line(x+w, y  , h, c);
}

void LCD_Clear(unsigned int j)                   
{ 
  unsigned int i,m;
  digitalWrite(LCD_RS, HIGH);
  digitalWrite(LCD_CS, LOW);
  Address_set(0, 0, 239, 319);

  for(i = 0; i < 240; i++)
    for(m = 0; m < 320; m++){
      Lcd_Write_Data(j>>8);
      Lcd_Write_Data(j);
    }
  digitalWrite(LCD_CS, HIGH);   
}

void setup()
{
  Serial.begin(9600);

  pinMode(2, OUTPUT);   //Data 8bit
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  
  pinMode(A0,OUTPUT);
  pinMode(A1,OUTPUT);
  pinMode(A2,OUTPUT);
  pinMode(A3,OUTPUT);
  pinMode(A4,OUTPUT);
  digitalWrite(A0, HIGH);
  digitalWrite(A1, HIGH);
  digitalWrite(A2, HIGH);
  digitalWrite(A3, HIGH);
  digitalWrite(A4, HIGH);

  Lcd_Init();
}

void loop()
{  
  unsigned long start = micros();

   LCD_Clear(0xFFFF); 
   LCD_Clear(0x0000); 
   LCD_Clear(0xf800);
   LCD_Clear(0x07E0);
   LCD_Clear(0x001F);
  for(int i = 0; i < 300; i++)
    Rect(random(300), random(300),
         random(300), random(300),
         random(65535));

  Serial.println(micros() - start);
}