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)のモデルを使います。
◆関連記事
◆関連記事
ピン配置

外観


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

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

マイコンから手軽に静電容量式タッチを使うことができます。
今回使用したライブラリも多点タッチやタッチしているポイントの範囲の情報までサポートしていて、簡単に読み取ることができました。
まとめ
Good
高い入力感度で座標ばらつきが小さい。
最大5点入力で入力ポイントの接地サイズも読み取れる。
Bad
入手困難。あまり販売されていない。
GT911ライブラリのはESP32系のみの対応(ライブラリが見つけられていないかもしれません)
(ライブラリを修正することでRP2040搭載基板(Raspberrypi Pico)でも使用できます。
準備
ライブラリ
今回使用したのは以下のライブラリです。
LCDはILI9488ですが、ILI9486ライブラリが使えたのでそのまま使用しました。
ライブラリ名 | 用途 | 検索 | 確認時バージョン |
---|---|---|---|
ILI9486_SPI by Jean-Marc Zingg | LCD | ILI9486 | 1.0.5 |
Adafruit GFX Library by Adafruit | LCD | ILI9486 | 1.11.9 |
bb_captouch by Larry Bank | タッチパネル | GT911 | 1.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を使用しても同じ動作をします。

コメント