【Arduino】LCDモジュール(ILI9488)と静電容量タッチパネル(GT911)を使う

it

LCDモジュール(ILI9488)と静電容量タッチパネル(GT911)を使ってみます。
Arduino環境でRaspberry Pi Pico と ESP32-WROOM32を使ってLCD制御をしました。
静電容量タッチパネルで多点入力を試してみました。

記事の目的と内容

Arduino環境で使用できるLCD ILI9488と静電容量タッチパネル GT911を使ってみます。

主な記事の内容は
・ILI9488とGT911を使ってみた
・Arduino環境で使用するための準備一覧
・ESP32-WROOMを使ってLCDの表示
・ESP32-WROOMを使ってタッチパネルからの入力
・RP2040(RaspberryPi Pico)で使用できるようにライブラリを修正する

こんな方にお勧め
・Arduinoマイコンから中型のLCDを使いたい
・静電容量式のタッチパネルを制御したい

LCD ILI9488 + GT911静電容量タッチパネル

主な製品情報

Ali Expressのbit motionで購入。
マイコンで利用できる小型のパネルでも静電容量式が増えてきましたが、珍しいGT911静電容量タッチパネル付きのモデルです。

※GT911を使用するためのライブラリはESP32系しか見つけることができなかったため、本記事ではESP32-WROOM NodeMCUで制御します。
この記事ではライブラリを修正することでRP2040搭載基板(RaspberryPi Pico)で使用します。

LCDドライバILI9488
LCDサイズ3.5
LCD解像度(W, H)480, 320
パネルTN
動作電圧3.3 ~ 5V
SDカードリーダを使う場合は5V
LCD部通信方式SPI
タッチパネルドライバGT911
タッチパネル方式静電容量式(CTP)
タッチパネル分解能(W, H)320, 240
タッチパネル部通信方式I2C
SDカードリーダ通信方式SPI

ILI9488を使ったLCDでは感圧抵抗を使ったタッチパネルのものもあり、サイズも4.0インチまであるようです。
今回は3.5インチで、静電容量式タッチパネル(GT911)のモデルを使います。

◆関連記事

ST7735の記事です。
小型で安価、SPIで通信するLCDをRaspberry Pi Picoで表示、タッチパネル、SDカードリーダを使いました。
Nextion のHMI NX3224T024を使った記事です。
NextionEditorのセットアップと簡単な使い方、Raspberry Pi Picoと連動した画面制御について記事にしました。
ILI9341の記事です。
Arduino環境で使える中型サイズのLCDを使いました。
表示制御、タッチパネルとトラブル、SDカードからのJPG表示を記事にしました。
ILI9488の記事です。
表示制御以外にGT911静電容量式タッチパネルの多点タッチを使いました。
ESP32以外にRaspberry Pi Picoでも使用できるスケッチの修正を紹介しています。
ST7789の記事です。
IPS方式で発色のきれいなLCDです。
表示やタッチ制御以外にTNとIPS方式の視野角についても比べてみました。
SSD1331 カラーOLEDの記事です。
OLEDの鮮やかな発色と広い視野角のディスプレイです。
Raspberry Pi PicoとESP32-WROOM32での表示をしました。

◆関連記事

ピン配置

外観

使ってみた

タッチパネルには感圧式と静電容量式があります。
今回使った静電容量式(画像上側)は入力操作もやさしくなぞるだけで十分な入力ができますが、手袋をした状態では入力感知されません。

感圧式タッチパネル(画像下側)は画像のようにタッチパネルのシートがたわむほどの入力をしますが、手袋をはめた状態でも入力操作できます。

GT911では最大5ポイントの同時サンプリングと各タッチポイントのタッチ範囲を読み取ることができました。

マイコンから手軽に静電容量式タッチを使うことができます。
今回使用したライブラリも多点タッチやタッチしているポイントの範囲の情報までサポートしていて、簡単に読み取ることができました。

まとめ

Good

高い入力感度で座標ばらつきが小さい。
最大5点入力で入力ポイントの接地サイズも読み取れる。

Bad

入手困難。あまり販売されていない。
GT911ライブラリのはESP32系のみの対応(ライブラリが見つけられていないかもしれません)
(ライブラリを修正することでRP2040搭載基板(Raspberrypi Pico)でも使用できます。

準備

ライブラリ

今回使用したのは以下のライブラリです。
LCDはILI9488ですが、ILI9486ライブラリが使えたのでそのまま使用しました。

ライブラリ名用途検索確認時バージョン
ILI9486_SPI by Jean-Marc ZinggLCDILI94861.0.5
Adafruit GFX Library by AdafruitLCDILI94861.11.9
bb_captouch by Larry BankタッチパネルGT9111.2.0

Adafruit GFX Library By Adafruit は ILI9486_SPI by Jean-Marc Zingg の依存関係です。
インストール時に同時にインストールします。

使い方

LCDの表示

説明

画面に次の文字列を表示します。
“TAMANEGI”
“4.0inch LCD”
“Res=480 x 320”
“ILI9488”

LCDドライバはILI9488ですが、ILI9486ライブラリが使用できたのでそのまま使用しています。
マクロ定義名はILI9488に変更しています。

配線

スケッチ

#include <SPI.h>
#include <ILI9486_SPI.h>
#include <Adafruit_GFX.h>

#define TFT_CS       5    // CS
#define TFT_RST      27   // Reset 
#define TFT_DC       26   // DC
#define TFT_MOSI     23   // MOSI
#define TFT_SCK      18   // Clock

#define ILI9488_BLACK     (0x0000)
#define ILI9488_WHITE     (0xFFFF)
#define ILI9488_RED       (0xF800)
#define ILI9488_GREEN     (0x07E0)
#define ILI9488_BLUE      (0x001F)
#define ILI9488_CYAN      (0x07FF)
#define ILI9488_MAGENTA   (0xF81F)
#define ILI9488_YELLOW    (0xFFE0)
#define ILI9488_ORANGE    (0xFC00)

ILI9486_SPI tft(TFT_CS, TFT_DC, TFT_RST);

void setup(void)
{
  //SPIピン設定
  SPI.begin(TFT_SCK, -1, TFT_MOSI, TFT_CS); 

  //TFTの初期化と初期設定
  tft.setSpiKludge(false);              // false to disable rpi_spi16_mode
  tft.init();

  tft.fillScreen(ILI9488_BLACK);        //背景の塗りつぶし

  //テキスト表示
  tft.setRotation(3);                         //画面回転
  tft.setTextSize(7);                         //サイズ

  tft.setCursor(0, 10);                       //カーソル位置                      
  tft.setTextColor(ILI9488_GREEN);             //緑
  tft.printf("TAMANEGI\n\n");

  tft.setTextSize(4);                         //サイズ
  tft.setTextColor(ILI9488_RED);               //赤
  tft.printf("4.0inch LCD\n");
  tft.setTextColor(ILI9488_YELLOW);            //黄
  tft.printf("Res=480 x 320\n");
  tft.setTextColor(ILI9488_BLUE);              //青
  tft.printf("ILI9488\n");
}

void loop(void)
{
}

結果

タッチパネル

説明

タップした位置とタップした位置の大きさを読み取ります。
読み取り情報をCOM出力し、LCDにはタップした位置にドットを表示します。
最大5点同時タップまでのドットを表示することができます。

静電容量タッチドライバを使うためには、INTとRSTの信号を適切に操作する必要があります。
信号のタイミングはこちらのサイトを参考にしました。

配線

スケッチ

LCDドライバはILI9488ですが、ILI9486ライブラリを使用しています。

#include <SPI.h>
#include <ILI9486_SPI.h>
#include <Adafruit_GFX.h>

#include <bb_captouch.h>
#include <Wire.h>

#define TOUCH_SDA  21
#define TOUCH_SCL  22
#define TOUCH_INT 16
#define TOUCH_RST 17
#define TOUCH_WIDTH  640
#define TOUCH_HEIGHT 480

#define TFT_CS       5    // CS
#define TFT_RST      27   // Reset 
#define TFT_DC       26   // DC
#define TFT_MOSI     23   // MOSI
#define TFT_SCK      18   // Clock

#define ILI9488_BLACK     (0x0000)
#define ILI9488_WHITE     (0xFFFF)
#define ILI9488_RED       (0xF800)
#define ILI9488_GREEN     (0x07E0)
#define ILI9488_BLUE      (0x001F)
#define ILI9488_CYAN      (0x07FF)
#define ILI9488_MAGENTA   (0xF81F)
#define ILI9488_YELLOW    (0xFFE0)
#define ILI9488_ORANGE    (0xFC00)

ILI9486_SPI tft(TFT_CS, TFT_DC, TFT_RST);

BBCapTouch bbct;

void setup() {

  Serial.begin(115200);
  while (!Serial);

  //タッチパネルの初期化処理
  //GT911を使用するためのINT, RST信号の操作
  pinMode(TOUCH_RST, OUTPUT);
  pinMode(TOUCH_INT, OUTPUT);

  digitalWrite(TOUCH_RST, LOW);
  digitalWrite(TOUCH_INT, LOW);
  
  delay(10);  
  digitalWrite(TOUCH_INT, HIGH);
  delayMicroseconds(100);
  digitalWrite(TOUCH_RST, HIGH);
  delay(5);
  digitalWrite(TOUCH_INT, LOW);
  delay(50);

  //タッチパネルの原点位置
  // bbct.setOrientation(0, 0, 0);           //右上
  // bbct.setOrientation(90, 320, 0);        //右下
  // bbct.setOrientation(180, 320, 480);     //左下
  bbct.setOrientation(270, 0, 480);       //左上
  bbct.init(TOUCH_SDA, TOUCH_SCL, TOUCH_RST, TOUCH_INT);

  //LCDの初期化処理
  SPI.begin(TFT_SCK, -1, TFT_MOSI, TFT_CS); 

  //TFTの初期化と初期設定
  tft.setSpiKludge(false);
  tft.init();
  tft.fillScreen(ILI9488_BLACK);
  tft.setRotation(3);                         //画面回転

}

void loop() {

 TOUCHINFO ti;

  while (1) {
    if (bbct.getSamples(&ti)) {
      for (int i = 0; i < ti.count; i ++){
        //タッチ位置にポイント表示
        tft.fillCircle(ti.x[i], ti.y[i], 10, ILI9488_WHITE);
        Serial.printf("Touch[%d] : (x, y) = (%3d, %3d) : size = %3d\r\n", (i + 1), ti.x[i], ti.y[i], ti.area[i]);
      }
      Serial.println();
    } 
  }
}

結果

軽くなぞるだけでタッチの入力ができます。
下図結果は1点入力で絵を描きましたが、5ポイント同時サンプリングまでできます。

RP2040(RaspberryPi Pico)で使用できるようにライブラリを修正する

説明

静電容量タッチパネルドライバ(GT911)の制御ライブラリ 「bb_captouch by Larry Bank」を修正し、RP2040搭載基板 RaspberryPi Picoでも使用できるようにします。

ライブラリは修正箇所のみを記載します。
動作確認サンプルは、当記事「タッチパネル」のサンプルソースをRP2040でも動作するように修正します。

修正(ライブラリ)

ライブラリは
C:\Users\xxxx\OneDrive\ドキュメント\Arduino\libraries\bb_captouch\src
(xxxxはPCのログインアカウントです)
bb_captouch.cppをメモ帳などテキストエディタで編集します。

int BBCapTouch::init(…)関数(90行目)を検索します。
ESPボードのI2Cピン設定箇所にRP2040ボード用の#ifdef 文を追記します。

94行目を以下のコードに置き換えます。

#ifdef ARDUINO_ARCH_RP2040  //Added for RP2040 MCUs
    Wire.setSDA(iSDA);
    Wire.setSCL(iSCL);
    Wire.begin();
#else
    Wire.begin(iSDA, iSCL); // this is specific to ESP32 MCUs
#endif

修正(サンプルソース)

「タッチパネル」のサンプルソースに#ifdef分を追記してESP32-WROOM (Node MCU)、またはRP2040(RaspberryPi Pico)のどちらでもコンパイルできる変更をしています。

#include <SPI.h>
#include <ILI9486_SPI.h>
#include <Adafruit_GFX.h>

#include <bb_captouch.h>
#include <Wire.h>

#ifdef ARDUINO_ARCH_RP2040
  #define TOUCH_SDA   0
  #define TOUCH_SCL   1
  #define TOUCH_INT   2
  #define TOUCH_RST   3

  #define TFT_CS      17   // CS
  #define TFT_RST     22   // Reset 
  #define TFT_DC      28   // D/C
  #define TFT_MOSI    19   // SDI(MOSI)
  #define TFT_SCK     18   // SCK

#else
  #define TOUCH_SDA   21
  #define TOUCH_SCL   22
  #define TOUCH_INT   16
  #define TOUCH_RST   17

  #define TFT_CS      5    // CS
  #define TFT_RST     27   // Reset 
  #define TFT_DC      26   // DC
  #define TFT_MOSI    23   // MOSI
  #define TFT_SCK     18   // Clock
#endif

#define TOUCH_WIDTH  640
#define TOUCH_HEIGHT 480

#define ILI9488_BLACK     (0x0000)
#define ILI9488_WHITE     (0xFFFF)
#define ILI9488_RED       (0xF800)
#define ILI9488_GREEN     (0x07E0)
#define ILI9488_BLUE      (0x001F)
#define ILI9488_CYAN      (0x07FF)
#define ILI9488_MAGENTA   (0xF81F)
#define ILI9488_YELLOW    (0xFFE0)
#define ILI9488_ORANGE    (0xFC00)

ILI9486_SPI tft(TFT_CS, TFT_DC, TFT_RST);

BBCapTouch bbct;

void setup() {

  Serial.begin(115200);
  while (!Serial);

  //タッチパネルの初期化処理
  //GT911を使用するためのINT, RST信号の操作
  pinMode(TOUCH_RST, OUTPUT);
  pinMode(TOUCH_INT, OUTPUT);

  digitalWrite(TOUCH_RST, LOW);
  digitalWrite(TOUCH_INT, LOW);
  
  delay(10);  
  digitalWrite(TOUCH_INT, HIGH);
  delayMicroseconds(100);
  digitalWrite(TOUCH_RST, HIGH);
  delay(5);
  digitalWrite(TOUCH_INT, LOW);
  delay(50);

  //タッチパネルの原点位置
  // bbct.setOrientation(0, 0, 0);           //右上
  // bbct.setOrientation(90, 320, 0);        //右下
  // bbct.setOrientation(180, 320, 480);     //左下
  bbct.setOrientation(270, 0, 480);       //左上
  bbct.init(TOUCH_SDA, TOUCH_SCL, TOUCH_RST, TOUCH_INT);

  //LCDの初期化処理

#ifdef ARDUINO_ARCH_RP2040
  SPI.setMOSI(TFT_MOSI);
  SPI.setSCK(TFT_SCK);
  SPI.begin();
#else
  SPI.begin(TFT_SCK, -1, TFT_MOSI, TFT_CS); 
#endif

  //TFTの初期化と初期設定
  tft.setSpiKludge(false);
  tft.init();
  tft.fillScreen(ILI9488_BLACK);
  tft.setRotation(3);                         //画面回転
}

void loop() {

 TOUCHINFO ti;

  while (1) {
    if (bbct.getSamples(&ti)) {
      for (int i = 0; i < ti.count; i ++){
        //タッチ位置にポイント表示
        tft.fillCircle(ti.x[i], ti.y[i], 10, ILI9488_WHITE);
        Serial.printf("Touch[%d] : (x, y) = (%3d, %3d) : size = %3d\r\n", (i + 1), ti.x[i], ti.y[i], ti.area[i]);
      }
      Serial.println();
    } 
  }
}

配線

結果

ESP32-WROOMと同様タッチ入力ができました。
画像はRaspberryPi Pico Hで実行していますが、RaspberryPi Picoを使用しても同じ動作をします。


コメント

タイトルとURLをコピーしました