ArduinoとタッチパネルTFT液晶(ILI9341)でタッチUI付きガジェットを自作する方法【回路図・スケッチ・メニュー実装】
「せっかくArduinoでガジェットを作ったのに、操作がボタン1個だけで味気ない…」そんな悩みを抱えていませんか?
実は、タッチパネル付きのTFT液晶(ILI9341)を使うと、スマホのような直感的なタッチUIをArduinoで実現できるんです。画面をタップしてメニューを操作したり、スライダーで値を変えたり——そんなリッチなガジェットが自作できますよ!
今回はILI9341搭載のタッチパネルTFT液晶をArduino UNOに接続して、タッチ対応のメニューUIをゼロから実装する方法を解説します。回路図・ライブラリ導入・スケッチまで一気にまとめましたので、ぜひ最後まで読んでみてください 😊
📦 必要なパーツ

まず用意するものを確認しておきましょう。
- Arduino UNO(またはUNO R4 MINIMA)
- 2.4インチ TFT液晶モジュール(ILI9341 + XPT2046タッチコントローラー内蔵)
- ジャンパーワイヤー(オス→メス 8本程度)
- ブレッドボード(任意)
ILI9341モジュールはSPI接続タイプが主流です。タッチ機能はXPT2046というICが担当しており、同じSPIバスを共有して使います。Amazonや秋月電子で「2.4インチ TFT タッチ」と検索すると見つかります。
🔌 配線(回路図)
ILI9341はSPI接続です。Arduino UNOとの接続は以下のとおりです。
| TFTモジュールのピン | Arduino UNOのピン | 用途 |
|---|---|---|
| VCC | 5V(または3.3V) | 電源 |
| GND | GND | グラウンド |
| CS(LCD CS) | D10 | 液晶チップセレクト |
| RESET | D9 | リセット |
| DC / RS | D8 | データ/コマンド切替 |
| MOSI / SDI | D11 | SPI データ送信 |
| SCK / CLK | D13 | SPI クロック |
| LED / BL | 3.3V または D3 | バックライト |
| T_CS | D4 | タッチチップセレクト |
| T_IRQ | D2 | タッチ割り込み(任意) |
| MISO | D12 | SPI データ受信(タッチ用) |
⚠️ 注意:モジュールによってピン名が微妙に異なる場合があります。データシートを必ず確認してください。SDO/MISO が別ピンに分かれているタイプもあります。
📚 ライブラリのインストール
Arduino IDEのライブラリマネージャーから以下の2つをインストールします。
- Adafruit ILI9341(液晶描画用)
- Adafruit GFX Library(グラフィックス基盤)
- XPT2046_Touchscreen(タッチ読み取り用/作者:Paul Stoffregen)
「ツール → ライブラリを管理」から各ライブラリ名で検索してインストールすればOKです。依存関係のライブラリも一緒にインストールするよう促されたら「全てインストール」を選びましょう。
🖥️ まずは画面に文字と図形を描いてみる
配線とライブラリが準備できたら、まず表示確認から始めましょう。以下のスケッチをArduinoに書き込んでみてください。
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
// ピン定義
#define TFT_CS 10
#define TFT_DC 8
#define TFT_RST 9
// TFTオブジェクトを作成
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
void setup() {
tft.begin(); // TFT初期化
tft.setRotation(1); // 横向き表示(0〜3で回転変更可)
tft.fillScreen(ILI9341_BLACK); // 画面を黒で塗りつぶす
// 白色でテキスト表示
tft.setTextColor(ILI9341_WHITE);
tft.setTextSize(2); // 文字サイズ(1〜6)
tft.setCursor(20, 20);
tft.println("Hello, TFT!");
// 青い四角形を描画
tft.fillRect(20, 60, 100, 40, ILI9341_BLUE);
// 赤い円を描画
tft.fillCircle(200, 80, 30, ILI9341_RED);
}
void loop() {
// 今はここは空でOK
}
ポイントをまとめるとこんな感じです。
setRotation(1)で横向きに。0が縦、1が横(左向き)、3が横(右向き)fillScreen()で背景色を一発塗りfillRect(x, y, 幅, 高さ, 色)で塗りつぶした四角形- 色定数は
ILI9341_RED/ILI9341_BLUE/ILI9341_WHITEなどが使える
画面に文字と図形が表示されればOKです ✅ 表示されない場合は配線を見直しましょう。
👆 タッチ座標を読み取ってみる
次にタッチパネルから座標を読み取るスケッチを試してみましょう。
#include <XPT2046_Touchscreen.h>
#include <SPI.h>
#define TOUCH_CS 4
#define TOUCH_IRQ 2
// タッチスクリーンオブジェクト
XPT2046_Touchscreen ts(TOUCH_CS, TOUCH_IRQ);
void setup() {
Serial.begin(9600);
ts.begin(); // タッチ初期化
ts.setRotation(1); // 液晶の回転に合わせる
Serial.println("Touch the screen!");
}
void loop() {
if (ts.touched()) {
TS_Point p = ts.getPoint(); // タッチ座標を取得
// 生の座標をシリアルモニタに出力
Serial.print("X=");
Serial.print(p.x);
Serial.print(" Y=");
Serial.print(p.y);
Serial.print(" Z=");
Serial.println(p.z); // Z(圧力)値
delay(100);
}
}
シリアルモニタを開いて(9600bps)、画面をタップしてみてください。X・Y・Zの値が流れてきたらタッチの取得成功です!
ひとつ注意点があります。XPT2046が返す座標は生の値(0〜4095程度)で、液晶の画素座標(320×240)とは異なります。次のセクションで変換方法も含めて実装します。
🎛️ タッチUI付きメニューを実装する
いよいよ本題です!画面に3つのボタンを表示して、タップした場所に応じて処理を切り替えるタッチメニューを実装しましょう。
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
#include <XPT2046_Touchscreen.h>
#include <SPI.h>
// ピン定義
#define TFT_CS 10
#define TFT_DC 8
#define TFT_RST 9
#define TOUCH_CS 4
#define TOUCH_IRQ 2
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
XPT2046_Touchscreen ts(TOUCH_CS, TOUCH_IRQ);
// 画面サイズ(横向き)
#define SCREEN_W 320
#define SCREEN_H 240
// タッチ座標→液晶座標のマッピング(要キャリブレーション)
#define TOUCH_X_MIN 300
#define TOUCH_X_MAX 3800
#define TOUCH_Y_MIN 300
#define TOUCH_Y_MAX 3800
// ボタンの定義(x, y, 幅, 高さ)
struct Button {
int x, y, w, h;
const char* label;
uint16_t color;
};
// 3つのメニューボタン
Button buttons[] = {
{20, 60, 280, 40, "LED ON", ILI9341_GREEN},
{20, 110, 280, 40, "LED OFF", ILI9341_RED},
{20, 160, 280, 40, "INFO", ILI9341_CYAN}
};
const int BTN_COUNT = 3;
// タッチ座標を液晶のピクセル座標に変換
int mapTouch(int val, int minVal, int maxVal, int screenSize) {
return map(val, minVal, maxVal, 0, screenSize);
}
void drawMenu() {
tft.fillScreen(ILI9341_BLACK);
tft.setTextColor(ILI9341_WHITE);
tft.setTextSize(2);
tft.setCursor(20, 20);
tft.println("Select Menu:");
for (int i = 0; i < BTN_COUNT; i++) {
Button& b = buttons[i];
tft.fillRoundRect(b.x, b.y, b.w, b.h, 8, b.color); // 角丸ボタン
tft.setTextColor(ILI9341_BLACK);
tft.setTextSize(2);
tft.setCursor(b.x + 10, b.y + 12);
tft.print(b.label);
}
}
void handleButton(int idx) {
tft.fillScreen(ILI9341_BLACK);
tft.setTextColor(ILI9341_WHITE);
tft.setTextSize(2);
tft.setCursor(10, 10);
if (idx == 0) {
tft.println("LED: ON");
digitalWrite(LED_BUILTIN, HIGH); // D13のLEDを点灯
} else if (idx == 1) {
tft.println("LED: OFF");
digitalWrite(LED_BUILTIN, LOW); // D13のLEDを消灯
} else if (idx == 2) {
tft.println("Arduino TFT UI");
tft.setCursor(10, 40);
tft.println("ILI9341 + XPT2046");
tft.setCursor(10, 70);
tft.println("Touch Menu Demo");
}
// 2秒後にメニューに戻る
delay(2000);
drawMenu();
}
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
tft.begin();
tft.setRotation(1);
ts.begin();
ts.setRotation(1);
drawMenu(); // 最初にメニューを描画
}
void loop() {
if (!ts.touched()) return;
TS_Point p = ts.getPoint();
// 生座標 → 液晶ピクセル座標に変換
int px = mapTouch(p.x, TOUCH_X_MIN, TOUCH_X_MAX, SCREEN_W);
int py = mapTouch(p.y, TOUCH_Y_MIN, TOUCH_Y_MAX, SCREEN_H);
// どのボタンが押されたか判定
for (int i = 0; i < BTN_COUNT; i++) {
Button& b = buttons[i];
if (px >= b.x && px <= b.x + b.w &&
py >= b.y && py <= b.y + b.h) {
handleButton(i);
break;
}
}
delay(150); // チャタリング防止
}
このスケッチのポイントはここです!
- Button構造体でボタンの位置・サイズ・ラベル・色をまとめて管理
fillRoundRect()で角丸ボタンを描画(見た目がぐっと良くなります)mapTouch()でXPT2046の生座標を画面座標に変換- タップした座標がどのボタン範囲内かを
forループで総当たり判定 - 処理後2秒でメニューに自動復帰
🔧 タッチがズレる場合はキャリブレーションを
タッチした場所と反応する座標がズレる場合は、キャリブレーションが必要です。
先ほどのタッチ座標確認スケッチを使って、画面の「左上・右上・左下・右下」をタップしたときのX・Zの生座標を記録してください。その最小値・最大値を TOUCH_X_MIN / TOUCH_X_MAX / TOUCH_Y_MIN / TOUCH_Y_MAX に設定すればOKです。
また、液晶の setRotation() とタッチの setRotation() を同じ値にすることも重要です。ここがズレているとX・Y軸が入れ替わったりします。
💡 応用アイデア
このタッチUIベースを作ってしまえば、あとは処理を差し替えるだけでいろんなガジェットに応用できます。
- 🌡️ 温湿度モニター:DHT22の値をリアルタイム表示して、タップで単位切替(℃/℉)
- 🔊 音量コントローラー:スライダーUIを実装してPWMで音量を制御
- 💡 スマートライト:カラーパレットで色を選択してLEDの色を変える
- ⏱️ タイマーガジェット:「+」「−」ボタンで分数を設定してカウントダウン
Button構造体の配列にメニュー項目を追加するだけで、どんどん画面を拡張できますよ 😊
まとめ
今回はArduinoとILI9341タッチパネルTFT液晶を使って、タッチUI付きメニューを実装する方法を解説しました。
ポイントをおさらいすると——
- ILI9341(表示)+ XPT2046(タッチ)のSPI接続が基本構成
- Adafruit ILI9341・GFX・XPT2046_Touchscreenの3ライブラリを使う
- タッチ座標は生値なのでmapで変換+キャリブレーションが必要
- Button構造体でボタンを管理すると追加・変更がラクになる
「スケッチ書いて基板に積むだけ」のシンプルさで、スマホのようなUIが作れるのがArduino電子工作の醍醐味ですよね。ぜひ手を動かして試してみてください!次はセンサーの値をリアルタイムでグラフ表示するUIにも挑戦してみましょう 🚀
こちらも読まれています
📡 Arduinoをもっと深く学ぼう!
Arduino・ラズパイ・ロボットプログラミングを体系的に学びたい方へ。おすすめのUdemyコースや電子部品もまとめています。
📚 関連商品・おすすめ書籍
※本記事にはアフィリエイトリンクが含まれます。





