ESP-WROOM-02でTFTに漢字を表示する

タッチパネルの動作


手元に、2.4インチTFT/2.8インチTFTが、それぞれ2個あります。
タッチパネル・コントローラの有無と、実装されているコントローラICの型番が違いま す。
2.4インチTFT その1:タッチパネル・コントローラあり  HR2046
2.4インチTFT その2:タッチパネル・コントローラあり XPT2046
2.8インチTFT その1:タッチパネル・コントローラ無し
2.8インチTFT その2:タッチパネル・コントローラあり XPT2046



枠内がタッチパネル・コントローラ。右上の2.8インチはタッチ用のピンは出ていますが、コントローラ無しです。
基盤シルクの型番はどちらも「TJCTM24028-SP1」ですが、Aliではよくあることです。

下の写真は2.4インチのコントローラー部分ですが、実装されているタッチパネル・コントローラが違います。
基盤シルクの型番も微妙に違っています。




XPT2046が実装されている場合、2.4インチも2.8インチも、以下のスケッチでタッチパネルが動きました。
HR2046のデータシートを探してみましたがどこにもありません。
おそらく互換チップと思われますが、同じスケッチで動く場合と、動かない場合が有るようです。
私の持っているHR2046では動きませんでした。
/*
 * タッチセンサーの動作確認
*/

#include <Adafruit_GFX.h>    // https://github.com/adafruit/Adafruit-GFX-Library
#include <Fontx.h>              // https://github.com/h-nari/Fontx
#include <Humblesoft_GFX.h>     // https://github.com/h-nari/Humblesoft_GFX
#include <Humblesoft_ILI9341.h> // https://github.com/h-nari/Humblesoft_ILI9341
#include <XPT2046_Touchscreen.h> //https://github.com/PaulStoffregen/XPT2046_Touchscreen

#define CS_PIN  16 // ChipSelect for TouchScreen

#define LOWER 1000
#define MIDLE 3000

//フォントファイルのパスは絶対パス
IMPORT_BIN("/fontx/ILGH16XB.FNT", ILH16XB); //16ドット半角ゴシックフォント
IMPORT_BIN("/fontx/ILGZ16XB.FNT", ILZ16XB); //16ドット全角ゴシックフォント
//IMPORT_BIN("/fontx/ILMH16XB.FNT", ILH16XB); //16ドット半角明朝フォント
//IMPORT_BIN("/fontx/ILMZ16XB.FNT", ILZ16XB); //16ドット全角明朝フォント
extern const uint8_t ILH16XB[], ILZ16XB[];

Humblesoft_ILI9341 tft = Humblesoft_ILI9341();
RomFontx fontx(ILH16XB,ILZ16XB);

XPT2046_Touchscreen ts(CS_PIN);

void drawTextAndBounds(int16_t cx, int16_t cy, char *str, uint16_t color)
{
  int16_t x, y;
  uint16_t w, h;

//  tft.getTextBounds(str, cx, cy, &x, &y, &w, &h);
//  tft.drawRect(x, y, w, h, ILI9341_RED);
  tft.setCursor(cx, cy);
  tft.setTextColor(color);
  tft.print(str);
}

void showPosition(uint16_t pos, uint16_t color) {
  if (pos == 1) drawTextAndBounds(60,100, "右下です",color);
  if (pos == 2) drawTextAndBounds(60,100, "右です",color);
  if (pos == 3) drawTextAndBounds(60,100, "右上です",color);
  if (pos == 11) drawTextAndBounds(60,100, "下です",color);
  if (pos == 12) drawTextAndBounds(60,100, "中央です",color);
  if (pos == 13) drawTextAndBounds(60,100, "上です",color);
  if (pos == 21) drawTextAndBounds(60,100, "左下です",color);
  if (pos == 22) drawTextAndBounds(60,100, "左です",color);
  if (pos == 23) drawTextAndBounds(60,100, "左上です",color);
}

uint16_t white,black;

void setup()
{
  delay(500);Serial.begin(9600);
  Serial.println();
  Serial.println("Reset:");
  white   = tft.rgb("white");
  black   = tft.rgb("black");
 
  tft.begin();
  tft.setRotation(3);
  tft.fillScreen("WHITE");

  tft.setTextSize(2);
//  tft.setCursor(20, 20);
  tft.setTextColor("BLUE");
  tft.setFont(&fontx);
  tft.print("画面をタッチ\nしてください");
  tft.setTextSize(3);
//  drawTextAndBounds(60,100, "右上です",black);

  ts.begin();
  while (!Serial && (millis() <= 1000));
}

void loop(){
  static int prev=0;

  if (ts.touched()) {
    TS_Point p = ts.getPoint();
    Serial.print("Pressure = ");
    Serial.print(p.z);
    Serial.print(", x = ");
    Serial.print(p.x);
    Serial.print(", y = ");
    Serial.print(p.y);
    Serial.println();
    if (p.x < LOWER) {
      if (p.y < LOWER) {
        showPosition(prev, white);
        prev=1;
        showPosition(prev, black);
      } else if (p.y < MIDLE) {
        showPosition(prev, white);
        prev=2;
        showPosition(prev, black);
      } else {
        showPosition(prev, white);
        prev=3;
        showPosition(prev, black);
      }
    } else if (p.x < MIDLE) {
      if (p.y < LOWER) {
        showPosition(prev, white);
        prev=11;
        showPosition(prev, black);
      } else if (p.y < MIDLE) {
        showPosition(prev, white);
        prev=12;
        showPosition(prev, black);
      } else {
        showPosition(prev, white);
        prev=13;
        showPosition(prev, black);
      }
    } else {
      if (p.y < LOWER) {
        showPosition(prev, white);
        prev=21;
        showPosition(prev, black);
      } else if (p.y < MIDLE) {
        showPosition(prev, white);
        prev=22;
        showPosition(prev, black);
      } else {
        showPosition(prev, white);
        prev=23;
        showPosition(prev, black);
      }
    }
    delay(100);
  }
}






HR2046のモジュールでは、基盤のSP1をショートさせてT_IRQのGPIO4を有効にした後、
以下のスケッチでX座標だけは取れましたが、Y座標をとることができません。
常にY座標に同じ値が戻ってきてしまいます。
原因不明ですが基盤ではなくTFTモジュール側(実装されているHR2046コントローラー)の問題と思われます。
/*
 * Simple Touch Screen Test for HR2046
*/
#include <SPI.h>
#include <XPT2046.h> // https://github.com/spapadim/XPT2046

#define CS_PIN  16
#define TIRQ_PIN  4

XPT2046 ts(CS_PIN, TIRQ_PIN);  // Param 2 - Touch IRQ Pin - interrupt enabled polling

void setup() {
  Serial.begin(9600);
  delay(500);
  Serial.println();
  Serial.println("Start");
  ts.begin(320,240);
  while (!Serial && (millis() <= 1000));
}


void loop() {
  uint16_t x, y;
  if (ts.isTouching()) {
//    ts.getPosition(x, y);
    ts.getRaw(x, y);
    Serial.print("x = ");
    Serial.print(x);
    Serial.print(", y = ");
    Serial.print(y);
    Serial.println();
    delay(100);
  }
}

なお、タッチパネル・コントローラの有無はTFT裏面を見れば一目瞭然ですが、表面からでも判断できます。
左がタッチパネル・コントローラ無し、右がタッチパネル・コントローラありのモジュールです。
有りのモジュールは基盤から4線のフラットケーブルが出ています。


次回はインターネットから週間天気予報を取り込んで表示する手順を紹介しま す。