70歳の挑戦... TouchScreen に pinMode(*,OUTPUT) が重要であることが解りました

　先の投稿<a href="https://qiita.com/Mobu_Kyoto/items/57aa2ba98e9377ba1bf0">「8bitパラレルTFTのタッチ機能が使えました」</a>の後、”STM32F411（BlackPill）” に移植した結果を報告します。
　今回の構成です。

    １．STM32F411（BlackPill）
    ２．3.95" TFT LCD Shield，ILI9488 480x320 8bitParallel，4線式抵抗TouchScreen（と思われる）
    ３．Arduino IDE 2.3.2
    ４．TFT_eSPIライブラリ
    ５．ST-LINK V2（あった方が断然楽）

![F411_Calc.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3189926/bee2ee4f-211e-dbee-b6d6-84770bd7c266.jpeg)

　まずは、ピンの接続だけをBlackPill用に変更してみました。が勿論うまくゆくはずもなく...。でも初期画面表示は出来てタッチ機能も働いているようです。しかし、それに応じての新たな表示が出来ません。タッチする場所により画面の乱れ方も違います。ヒントは無いかと
 
     libraries\Adafruit_TouchScreen\TouchScreen.cpp

を眺めていると、"readTouchX" や "readTouchY" で "pinMode" が変更されていました。ひょっとしたらと、".getTouch()" のあと、表示をさせる前に "pinMode(*,OUTOUT)" を入れてみたところ、動作しました。

```c:
void tftOutput() {
  pinMode(XP, OUTPUT);
  pinMode(XM, OUTPUT);
  pinMode(YP, OUTPUT);
  pinMode(YM, OUTPUT);
}
```
Arduino IDE のTools の設定は次のようにしました。
![ToolSetting.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3189926/d3833ca6-4e12-fed9-a023-7cd5ca6ef02a.jpeg)

TFT_eSPI ライブラリで必要とされる "User_Setup.h" は以下です。
（なお、"User_Select_Setup.h" の中身は不要なので全行をコメント化しておきます。）

```html:User_Setup.h
#define USER_SETUP_INFO "User_Setup"
#define STM32
#define STM_PORTB_DATA_BUS
#define TFT_PARALLEL_8_BIT
#define ILI9488_DRIVER

#define TFT_PARALLEL_8_BIT
#define TFT_CNTRL_PORT GPIOA
#define TFT_DATA_PORT	GPIOB
#define TFT_DATA_SHIFT 0 // take the lower bits/pins 0..7

// The ESP32 and TFT the pins used for testing are:
#define TFT_RST  PA0  // Reset pin, toggles on startup
#define TFT_CS   PA1  // Chip select control pin (library pulls permanently low
#define TFT_DC   PA2  // Data Command control pin - must use a pin in the range 0-31
#define TFT_WR   PA3  // Write strobe control pin - must use a pin in the range 0-31
#define TFT_RD   PA4  // Read strobe control pin

#define TFT_D0   PB0  // Must use pins in the range 0-31 for the data bus
#define TFT_D1   PB1  // so a single register write sets/clears all bits.
#define TFT_D2   PB2  // Pins can be randomly assigned, this does not affect
#define TFT_D3   PB3  // TFT screen update performance.
#define TFT_D4   PB4
#define TFT_D5   PB5
#define TFT_D6   PB6
#define TFT_D7   PB7

#define LOAD_GLCD   // Font 1. Original Adafruit 8 pixel font needs ~1820 bytes in FLASH
#define LOAD_FONT2  // Font 2. Small 16 pixel high font, needs ~3534 bytes in FLASH, 96 characters
#define LOAD_FONT4  // Font 4. Medium 26 pixel high font, needs ~5848 bytes in FLASH, 96 characters
#define LOAD_FONT6  // Font 6. Large 48 pixel font, needs ~2666 bytes in FLASH, only characters 1234567890:-.apm
#define LOAD_FONT7  // Font 7. 7 segment 48 pixel font, needs ~2438 bytes in FLASH, only characters 1234567890:-.
#define LOAD_FONT8  // Font 8. Large 75 pixel font needs ~3256 bytes in FLASH, only characters 1234567890:-.
//#define LOAD_FONT8N // Font 8. Alternative to Font 8 above, slightly narrower, so 3 digits fit a 160 pixel TFT
#define LOAD_GFXFF  // FreeFonts. Include access to the 48 Adafruit_GFX free fonts FF1 to FF48 and custom fonts
#define SMOOTH_FONT

#define SPI_FREQUENCY  55000000 // STM32 SPI1 only (SPI2 maximum is 27MHz)
// #define SPI_FREQUENCY  80000000

// Optional reduced SPI frequency for reading TFT
#define SPI_READ_FREQUENCY  20000000

// The XPT2046 requires a lower SPI clock rate of 2.5MHz so we define that here:
#define SPI_TOUCH_FREQUENCY  2500000
```
次にino本体を示します。

```c:F411_8Para_TFTeSPI_Calc.ino
#include <TFT_eSPI.h>
#include "User_Setup.h"  // User_Setup_Select.h 内の全ての行はコメント化
#include <TouchScreen.h>

#define BLACK 0x0000  /* 5      6       5      */
#define WHITE 0xFFFF  /* ???? ? ??? ??? ? ???? */
#define RED 0xF800    /* 1111 1 000 000 0 0000 */
#define PINK 0xF81F   /* 1111 1 000 000 1 1111 */
#define YELLOW 0xFFE0 /* 1111 1 111 111 0 0000 */
#define GREEN 0x07E0  /* 0000 0 111 111 0 0000 */
#define CYAN 0x07FF   /* 0000 0 111 111 1 1111 */
#define BLUE 0x001F   /* 0000 0 000 000 1 1111 */

//#define TFT_D0   PB0
//#define TFT_D1   PB1
//#define TFT_CS   PA1
//#define TFT_DC   PA2
#define XP PB0  // D0     8 can be a digital pin at UNO
#define YP PB1  // D1     9 can be a digital pin at UNO
#define XM PA2  // DC=RS  A2 must be an analog pin, use "An" notation!
#define YM PA1  // CS     A3 must be an analog pin, use "An" notation!

TFT_eSPI tft = TFT_eSPI();

/*
   * @brief Construct a new Touch Screen object
   *
   * @param xp X+ pin. Must be an analog pin
   * @param yp Y+ pin. Must be an analog pin
   * @param xm X- pin. Can be a digital pin
   * @param ym Y- pin. Can be a digital pin 
   * @param rx The resistance in ohms between X+ & X- to calibrate pressure
   * sensing
*/
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 613);
// 613 ohms at mine. 300 is the default sensitivity
String symbol[4][4] = {
  { "7", "8", "9", "/" },
  { "4", "5", "6", "*" },
  { "1", "2", "3", "-" },
  { "C", "0", "=", "+" }
};

int16_t X, Y, Z;
int32_t Num1, Num2, Number;
char action;
boolean result = false;

void tftOutput() {
  pinMode(XP, OUTPUT);
  pinMode(XM, OUTPUT);
  pinMode(YP, OUTPUT);
  pinMode(YM, OUTPUT);
}

void setup(void) {
  Serial.begin(115200);  // CDC. generic Serial
  tft.init();
  tft.setRotation(2);
  tft.fillScreen(WHITE);
  draw_BoxNButtons();
  Number = Num1 = Num2 = 0;
}

void loop() {
  TSPoint p = ts.getPoint();

  X = map(p.x, 1023, 0, 0, tft.width());  // mapping for setRotation(2)
  Y = map(p.y, 1023, 0, 0, tft.height());
  Z = p.z;
  if (Z > 0 && X > 0 && Y > 0 && X < 320 && Y < 480) {
    /*
    Serial.print("X=");
    Serial.print(X);
    Serial.print(",Y=");
    Serial.print(Y);
    Serial.print(",Z=");
    Serial.println(Z);
    */
    tftOutput();  // Set the pins Output mode for displaying
    DetectButtons(X, Y);
    if (result == true)  // '=' key pressed
      CalculateResult();

    DisplayResult();
  }
  delay(200);
}

void DetectButtons(int X, int Y) {
  // Detecting Buttons on Column 0 ---------------------------------
  tft.setTextColor(BLACK);
  tft.setTextSize(3);
  if (X > 0 && X < 50) {
    if (Y > 269 && Y < 300) {  //If cancel Button is pressed
      Serial.println('C');
      Number = Num1 = Num2 = 0;
      tft.fillRect(220, 0, 20, 60, CYAN);
      tft.drawChar('C', 220, 2);
      result = false;
      delay(400);
      tft.fillRect(220, 0, 20, 30, CYAN);
    }
    if (Y > 210 && Y < 260) {  //If Button 1 is pressed
      Serial.println('1');
      if (Number == 0) Number = 1;
      else Number = (Number * 10) + 1;  //Pressed twice
    }
    if (Y > 160 && Y < 205) {  //If Button 4 is pressed
      Serial.println('4');
      if (Number == 0) Number = 4;
      else Number = (Number * 10) + 4;  //Pressed twice
    }
    if (Y > 108 && Y < 156) {  //If Button 7 is pressed
      Serial.println('7');
      if (Number == 0) Number = 7;
      else Number = (Number * 10) + 7;  //Pressed twice
    }
  }
  // Detecting Buttons on Column 1 --------------------------------
  if (X > 55 && X < 100) {
    if (Y > 269 && Y < 300) {
      Serial.println('0');  //Button 0 is Pressed
      if (Number == 0) Number = 0;
      else Number = (Number * 10) + 0;  //Pressed twice
    }
    if (Y > 214 && Y < 256) {
      Serial.println('2');
      if (Number == 0) Number = 2;
      else Number = (Number * 10) + 2;  //Pressed twice
    }
    if (Y > 160 && Y < 205) {
      Serial.println('5');
      if (Number == 0) Number = 5;
      else Number = (Number * 10) + 5;  //Pressed twic
    }
    if (Y > 108 && Y < 156) {
      Serial.println('8');
      if (Number == 0) Number = 8;
      else Number = (Number * 10) + 8;  //Pressed twic
    }
  }
  // Detecting Buttons on Column 2 ----------------------------------
  if (X > 115 && X < 175) {
    if (Y > 269 && Y < 300) {
      Serial.println('=');
      Num2 = Number;
      result = true;
      tft.drawChar('=', 220, 30);
    }
    if (Y > 210 && Y < 256) {
      Serial.println('3');
      if (Number == 0) Number = 3;
      else Number = (Number * 10) + 3;  //Pressed twice
    }
    if (Y > 160 && Y < 205) {
      Serial.println('6');
      if (Number == 0) Number = 6;
      else Number = (Number * 10) + 6;  //Pressed twice
    }
    if (Y > 108 && Y < 156) {
      Serial.println('9');
      if (Number == 0) Number = 9;
      else Number = (Number * 10) + 9;  //Pressed twice
    }
  }
  // Detecting Buttons on Column 3 --------------------------------------
  if (X > 182 && X < 236) {
    Num1 = Number;
    Number = 0;
    tft.fillRect(220, 0, 20, 30, CYAN);
    tft.setCursor(220, 2);
    if (Y > 108 && Y < 156) {
      Serial.println('/');
      action = 4;
      tft.println('/');
    }
    if (Y > 160 && Y < 205) {
      Serial.println('*');
      action = 3;
      tft.println('*');
    }
    if (Y > 214 && Y < 256) {
      Serial.println('-');
      action = 2;
      tft.println('-');
    }
    if (Y > 269 && Y < 300) {
      Serial.println('+');
      action = 1;
      tft.println('+');
    }
  }
  delay(100);
}

void CalculateResult() {
  if (action == 1)
    Number = Num1 + Num2;
  if (action == 2)
    Number = Num1 - Num2;
  if (action == 3)
    Number = Num1 * Num2;
  if (action == 4)
    Number = Num1 / Num2;
}

void DisplayResult() {
  Serial.println(Number);
  tft.fillRect(30, 30, 180, 50, CYAN);
  tft.setTextColor(BLACK);
  tft.drawNumber(Number, 30, 30);
}

void draw_BoxNButtons() {
  //Draw the Result Box
  tft.fillRect(0, 0, 240, 80, CYAN);
  //Draw Column 0
  tft.fillRect(0, 260, 60, 60, RED);
  tft.fillRect(0, 200, 60, 60, BLACK);
  tft.fillRect(0, 140, 60, 60, BLACK);
  tft.fillRect(0, 80, 60, 60, BLACK);
  //Draw Column 2
  tft.fillRect(120, 260, 60, 60, GREEN);
  tft.fillRect(120, 200, 60, 60, BLACK);
  tft.fillRect(120, 140, 60, 60, BLACK);
  tft.fillRect(120, 80, 60, 60, BLACK);
  //Draw Column 1,3
  for (int b = 260; b >= 80; b -= 60) {
    tft.fillRect(180, b, 60, 60, BLUE);
    tft.fillRect(60, b, 60, 60, BLACK);
  }
  //Draw Horizontal Lines
  for (int h = 80; h <= 320; h += 60)
    tft.drawFastHLine(0, h, 240, WHITE);
  //Draw Vertical Lines
  for (int v = 0; v <= 240; v += 60)
    tft.drawFastVLine(v, 80, 240, WHITE);
  //Display keypad lables
  tft.setTextSize(4);
  tft.setTextColor(WHITE);
  for (int j = 0; j < 4; j++) {
    for (int i = 0; i < 4; i++) {
      tft.setCursor(20 + (60 * i), 96 + (60 * j));
      tft.println(symbol[j][i]);
    }
  }
  tft.setTextSize(3);
  tft.setTextColor(BLACK);
  tft.drawNumber(Number, 30, 30);
}
```
　前回よりかなりシンプルになっていますが、これで動作しました。最後まで見ていただきありがとうございました。