71歳の挑戦... 4"TFT-LCD(NT35510,800x480,16bitパラレル接続)をPico2で動かしてみた

　前回に続き、Pico2の動作確認を兼ねて16ビットパラレル接続の4インチディスプレイモジュールを動作させてみました。

     4.0 inch Arduino Display-Mega2560 NT35510

 (保護されていない通信)
 http://www.lcdwiki.com/4.0inch_Arduino_Display-Mega2560_NT35510
「arduino Forum」サイト

 https://forum.arduino.cc/t/arduino-due-and-nt35510-tft-screen/1131769/3
 
より転載
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3189926/ab761415-2ee2-4f81-82f9-b8760eada3ed.png)

Pico2 との接続は次のようになります。

|ボード|pico2のGPIO|
|------|-----|
|TFT_D0|   0|  
|TFT_D1|   1|
|TFT_D2|   2|
|TFT_D3|   3|  
|TFT_D4|   4|
|TFT_D5|   5|
|TFT_D6|   6|
|TFT_D7|   7|
|TFT_D8|   8|
|TFT_D9|   9|
|TFT_D10|  10|
|TFT_D11|  11|
|TFT_D12|  12|
|TFT_D13|  13|
|TFT_D14|  14|
|TFT_D15|  15|
|TFT_CS |  17|  
|TFT_RS(DC)|19|
|TFT_RST|  16| 
|TFT_WR |  18| 
|TFT_RD |  -1|

![NT35510.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3189926/6f63ac18-d281-41e1-aaff-1d90beec9e72.jpeg)


普通に Arduino_GFX_Library で動かした結果、1ループに要する時間が「840msecs」ほどでした。試してから少し時間が経っており記憶が定かではありませんが、メモを参考にすると他のマイコンボードとの比較は次のようです。

|ボード| 1ループに要した時間（ミリ秒）|
|------|-----------|
|Pico (133MHz)| 1510msec|
|ESP32ｰS3 (240MHz)| 830Msecs|
|Pico2 (150MHz)| 844Msecs|

Pico2 はかなり優秀であることがわかります。Arduino IDE 2.3.4 でのスケッチを以下に示します。

```c:Pico_UTFT_Demo_800x480.ino
/******************************************************
 * Start of Arduino_GFX setting
 *****************************************************/
#include <Arduino_GFX_Library.h>
// at GFX_Library_for_Arduino /databus & /display

#define TFT_D0   0  
#define TFT_D1   1
#define TFT_D2   2 
#define TFT_D3   3  
#define TFT_D4   4
#define TFT_D5   5
#define TFT_D6   6
#define TFT_D7   7
#define TFT_D8   8
#define TFT_D9   9
#define TFT_D10  10
#define TFT_D11  11
#define TFT_D12  12
#define TFT_D13  13
#define TFT_D14  14
#define TFT_D15  15

#define TFT_CS   17  
#define TFT_RS   19  // DC
#define TFT_RST  16 
#define TFT_WR   18 
#define TFT_RD   -1

Arduino_DataBus *bus = new Arduino_RPiPicoPAR16(
  TFT_RS /* DC=RS */, TFT_CS /* CS */, TFT_WR /* WR */, TFT_RD /* RD */);

Arduino_GFX *tft = new Arduino_NT35510(
  bus, TFT_RST /* RST */, 0 /* rotation */);

#define WAIT 0  // Delay between tests, set to 0 to demo speed, 
                // 2000 to see what it does!
#define GREY 0x7BEF

uint32_t runTime = 0; // 1500-1510 msecs at 133MHz(pico)
                      // 820-830 msecs at 240MHz(ESP32)
int W, H;
void setup(void) {
  Serial.begin(115200);
  Serial.println("Arduino_GFX Hello World Gfxfont example");

  if (!tft->begin()) {
    Serial.println("tft->begin() failed!");
  }

  tft->fillScreen(BLACK);
  tft->setRotation(1);
  W=tft->width(); // after tft->setRotation(1);
  H=tft->height();
}

void loop()
{
  int buf[798];// tft->width() - 2
  int x, x2;
  int y, y2;
  int r;

  runTime = millis();
// Clear the screen and draw the frame
  tft->fillScreen(BLACK);

  tft->fillRect(0, 0, W, 13, RED);

  tft->fillRect(0, H-15, W, H, GREY);
  tft->setTextColor(BLACK,RED);
  tft->setCursor(W/2-50, 3);
  tft->println("Standard Graphic");
  tft->setTextColor(YELLOW);
  tft->setCursor(309,1);
  tft->println("Adapted by Bodmer");
  tft->drawRect(0, 14, W-1, H-15-14, BLUE);

  //delay(WAIT);

// Draw crosshairs
  tft->drawLine(W/2-1, 15, W/2-1, H-1-15, BLUE);
  tft->drawLine(1, H/2-1, W-2,H/2-1 , BLUE);
  for (int i=9; i<W-10; i+=10)
    tft->drawLine(i, H/2-3, i, H/2+1, BLUE);
  for (int i=19; i<H-10; i+=10)
    tft->drawLine(W/2-3, i, W/2+1, i, BLUE);

  //delay(WAIT);

// Draw sin-, cos- and tan-lines  
  tft->setTextColor(CYAN);
  tft->setCursor(5, 15);
  tft->println("Sin");
  for (int i=1; i<W-2; i++)
  {
    tft->drawPixel(i,H/2-1+(H/2-10)*sin(((i*1.13)*3.14)/180),CYAN);
  }
  
  //delay(WAIT);

  tft->setTextColor(RED);
  tft->setCursor(5, 30);
  tft->println("Cos");
  for (int i=1; i<W-2; i++)
  {
    tft->drawPixel(i,H/2-1+(H/2-10)*cos(((i*1.13)*3.14)/180),RED);
  }

  //delay(WAIT);

  tft->setTextColor(YELLOW);
  tft->setCursor(5, 45);
  tft->println("Tan");
  for (int i=1; i<W-2; i++)
  {
    tft->drawPixel(i,H/2-1+(tan(((i*1.13)*3.14)/180)),YELLOW);
  }

  //delay(WAIT);

  tft->fillRect(1,15,W-2-1,H-16-15,BLACK);
  tft->drawLine(W-2-1, 15, W-2-1, H-16,BLUE);
  tft->drawLine(1, H-1, W-2, H-1,BLUE);

// Draw a moving sinewave
int col = 0;
  x=1;
  for (int i=1; i<((W-3)*15); i++) 
  {
    x++;
    if (x==W-2)
      x=1;
    if (i>W-2)
    {
      if ((x==W/2-1)||(buf[x-1]==H/2-1))
        col = BLUE;
      else
        tft->drawPixel(x,buf[x-1],BLACK);
    }
    y=H/2-1+(sin(((i*0.7)*3.14)/180)*(90-(i / 100)));
    tft->drawPixel(x,y, BLUE);
    buf[x-1]=y;
    //delay(1);
  }

  //delay(WAIT);
  
  tft->fillRect(1,15,W-2,H-16-15,BLACK);

// Draw some filled rectangles
  for (int i=1; i<6; i++)
  {
    switch (i)
    {
      case 1:
        col = MAGENTA;
        break;
      case 2:
        col = RED;
        break;
      case 3:
        col = GREEN;
        break;
      case 4:
        col = BLUE;
        break;
      case 5:
        col = YELLOW;
        break;
    }
    tft->fillRect(H/2-10+(i*20), 70+(i*20), 60, 60,col);
  }

  //delay(WAIT);
  
  tft->fillRect(1,15,W-2-1,H-16-15,BLACK);

// Draw some filled, rounded rectangles
  for (int i=1; i<6; i++)
  {
    switch (i)
    {
      case 1:
        col = MAGENTA;
        break;
      case 2:
        col = RED;
        break;
      case 3:
        col = GREEN;
        break;
      case 4:
        col = BLUE;
        break;
      case 5:
        col = YELLOW;
        break;
    }
    tft->fillRoundRect(270-(i*20), 70+(i*20), 60, 60, 3, col);
  }
  
  //delay(WAIT);
  
  tft->fillRect(1,15,W-2-1,H-16-15,BLACK);

// Draw some filled circles
  for (int i=1; i<6; i++)
  {
    switch (i)
    {
      case 1:
        col = MAGENTA;
        break;
      case 2:
        col = RED;
        break;
      case 3:
        col = GREEN;
        break;
      case 4:
        col = BLUE;
        break;
      case 5:
        col = YELLOW;
        break;
    }
    tft->fillCircle(180+(i*20),100+(i*20), 30,col);
  }
  
  //delay(WAIT);
  
  tft->fillRect(1,15,W-2-1,H-16-15,BLACK);

// Draw some lines in a pattern

  for (int i=15; i<H-16; i+=5)
  {
    tft->drawLine(1, i, (i*1.6)-10, H-17, RED);
  }

  for (int i=H-16; i>15; i-=5)
  {
    tft->drawLine(W-3, i, (i*1.6)-11, 15, RED);
  }

  for (int i=H-16; i>15; i-=5)
  {
    tft->drawLine(1, i, W+11-(i*1.6), 15, CYAN);
  }

  for (int i=15; i<H-16; i+=5)
  {
    tft->drawLine(W-3, i, H+10-(i*1.6), H-17, CYAN);
  }
  
  //delay(WAIT);
  
  tft->fillRect(1,15,W-2-1,H-16-15,BLACK);

// Draw some random circles
  for (int i=0; i<100; i++)
  {
    x=32+random(W-64);
    y=45+random(H-90-4);
    r=random(30);
    tft->drawCircle(x, y, r,random(0xFFFF));
  }

  //delay(WAIT);
  
  tft->fillRect(1,15,W-2-1,H-16-15,BLACK);

// Draw some random rectangles
  for (int i=0; i<100; i++)
  {
    x=2+random(W-4);
    y=16+random(H-30-1);
    x2=2+random(W-4);
    y2=16+random(H-30-1);
    if (x2<x) {
      r=x;x=x2;x2=r;
    }
    if (y2<y) {
      r=y;y=y2;y2=r;
    }
    tft->drawRect(x, y, x2-x, y2-y,random(0xFFFF));
  }

  //delay(WAIT);
  
  tft->fillRect(1,15,W-2-1,H-16-15,BLACK);

// Draw some random rounded rectangles
  for (int i=0; i<100; i++)
  {
    x=2+random(W-4);
    y=16+random(H-30-1);
    x2=2+random(W-4);
    y2=16+random(H-30-1);
    if (x2<x) {
      r=x;x=x2;x2=r;
    }
    if (y2<y) {
      r=y;y=y2;y2=r;
    }
    tft->drawRoundRect(x, y, x2-x, y2-y, 3,random(0xFFFF));
  }

  //delay(WAIT);
  
  tft->fillRect(1,15,W-2-1,H-16-15,BLACK);

  for (int i=0; i<100; i++)
  {
    x=2+random(W-4);
    y=16+random(H-30-1);
    x2=2+random(W-4);
    y2=16+random(H-30-1);
    col=random(0xFFFF);
    tft->drawLine(x, y, x2, y2,col);
  }

  //delay(WAIT);
  
  tft->fillRect(1,15,W-1-2,H-16-15,BLACK);

  for (int i=0; i<10000; i++)
  {
    tft->drawPixel(2+random(W-4), 16+random(H-30-1),random(0xFFFF));
  }

  //delay(WAIT);

  tft->fillRect(0, 0, W, H, BLUE);
  tft->fillRoundRect(160, 70, W-161-160, H-71-70, 3,RED);
  
  tft->setTextSize(2);
  tft->setTextColor(WHITE);
  tft->setCursor(W/2 - 50, H/2-70);
  tft->println("That's it!");
  tft->setCursor(W/2 - 60, H/2-45);
  tft->println("Restarting in  a");
  tft->setCursor(W/2 - 60, H/2-20);
  tft->println("few seconds...");
  tft->setTextColor(GREEN);
  tft->setCursor(W/2 - 60, H/2+40);
  tft->println("Runtime: (msecs)");
  //tft->setTextDatum(TC_DATUM);
  runTime = millis()-runTime;
  tft->setCursor(W/2 - 60, H/2+80);
  tft->println(String(runTime)); // 820-830
  //tft->setTextDatum(TL_DATUM);
  delay (10000);
}
```
　最後まで見ていただきありがとうございました。