0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

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

Last updated at Posted at 2024-07-08

 先の投稿「8bitパラレルTFTのタッチ機能が使えました」の後、”STM32F411(BlackPill)” に移植した結果を報告します。
 今回の構成です。

1.STM32F411(BlackPill)
2.3.95" TFT LCD Shield,ILI9488 480x320 8bitParallel,4線式抵抗TouchScreen(と思われる)
3.Arduino IDE 2.3.2
4.TFT_eSPIライブラリ
5.ST-LINK V2(あった方が断然楽)

F411_Calc.jpg

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

 libraries\Adafruit_TouchScreen\TouchScreen.cpp

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

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

Arduino IDE のTools の設定は次のようにしました。
ToolSetting.jpg

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

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本体を示します。

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);
}

 前回よりかなりシンプルになっていますが、これで動作しました。最後まで見ていただきありがとうございました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?