使用 ESP32-S3 與 2.8吋 ILI9341 觸控螢幕製作互動小遊戲
想學習 ESP32-S3 圖形介面開發嗎?本篇教學將帶您使用 ESP32-S3 搭配 2.8 吋 ILI9341 TFT 觸控螢幕,打造一款經典的「打地鼠遊戲(Whack-a-Mole)」。
透過本教學,您將學會:
- ESP32-S3 SPI TFT 螢幕驅動
- ILI9341 顯示器設定
- XPT2046 觸控控制器應用
- TFT_eSPI 函式庫使用技巧
- 觸控座標校正
- 遊戲介面設計
- 觸控事件判斷
- Arduino IDE 開發流程
本次使用硬體
ESP32-S3 N16R8 開發板
特色:
- 雙核心 Xtensa LX7
- WiFi + Bluetooth
- 16MB Flash
- 8MB PSRAM
- 支援 Arduino IDE
- 適合 GUI 與 IoT 專案
2.8吋 ILI9341 TFT 觸控螢幕
規格:
- 解析度:240×320
- 驅動 IC:ILI9341
- 觸控 IC:XPT2046
- SPI 介面
- 支援 MicroSD
專案成果展示
本專案完成後可實現:
✅ 隨機地鼠出現
✅ 觸控擊打得分
✅ 30秒倒數計時
✅ 遊戲結束畫面
✅ 最終分數統計
Arduino IDE 環境配置與程式庫安裝
Step1 安裝 Arduino IDE
建議版本:
- Arduino IDE :1.8.19
- ESP32 Core :2.0.13
Step2 安裝函式庫
在開始編寫程式之前,我們需要安裝專門處理觸控螢幕的第三方程式庫。
建議版本:
- TFT_eSPI :2.4.79
- XPT2046_Touchscreen:1.4
TFT_eSPI :
開啟您的 Arduino IDE 開發環境。
點選左側的「程式庫管理員」圖示(或至選單:工具 > 管理程式庫)。
在搜尋欄輸入 TFT_eSPI。
找到對應的程式庫後,選擇2.4.79版本,點選 [安裝]。
XPT2046_Touchscreen:
開啟您的 Arduino IDE 開發環境。
點選左側的「程式庫管理員」圖示(或至選單:工具 > 管理程式庫)。
在搜尋欄輸入 XPT2046_Touchscreen。
找到對應的程式庫後,選擇1.4版本,點選 [安裝]。
ESP32-S3 與 ILI9341 接線圖
TFT 顯示器接線:
TFT模組 | ESP32-S3 |
|---|---|
VCC | 3V3 |
GND | GND |
LCD_CS | GPIO10 |
LCD_RST | GPIO14 |
LCD_RS(DC) | GPIO9 |
SDI(MOSI) | GPIO11 |
SCK | GPIO12 |
SDO(MISO) | GPIO13 |
LED | 3V3 |
XPT2046 觸控接線(獨立 SPI):
TOUCH | ESP32-S3 |
|---|---|
T_CS | GPIO16 |
T_CLK | GPIO6 |
T_DIN | GPIO4 |
T_DO | GPIO5 |
T_IRQ | 不接 |
TFT_eSPI 設定
找到:
Documents/Arduino/libraries/TFT_eSPI/User_Setup.h
修改:User_Setup.h
#define ILI9341_DRIVER
#define TFT_MISO 13
#define TFT_MOSI 11
#define TFT_SCLK 12
#define TFT_CS 10
#define TFT_DC 9
#define TFT_RST 14
#define SPI_FREQUENCY 40000000
#define SPI_READ_FREQUENCY 20000000
觸控校正程式
#include <SPI.h>
#include <XPT2046_Touchscreen.h>
#include <TFT_eSPI.h>
TFT_eSPI tft = TFT_eSPI();
// Touch SPI
SPIClass touchSPI(FSPI);
#define TOUCH_SCLK 6
#define TOUCH_MISO 5
#define TOUCH_MOSI 4
#define TOUCH_CS 16
XPT2046_Touchscreen ts(TOUCH_CS);
void waitTouchRelease()
{
while(ts.touched())
{
delay(10);
}
}
void getCalibrationPoint(
const char* text,
int px,
int py,
uint16_t color,
int &rawX,
int &rawY
)
{
tft.fillScreen(TFT_BLACK);
tft.setTextColor(TFT_WHITE);
tft.setTextSize(2);
tft.drawString(text, 20, 20);
tft.fillCircle(px, py, 10, color);
while(!ts.touched())
{
delay(10);
}
TS_Point p = ts.getPoint();
rawX = p.x;
rawY = p.y;
Serial.printf(
"%s : X=%d Y=%d Z=%d\n",
text,
p.x,
p.y,
p.z
);
waitTouchRelease();
delay(500);
}
void setup()
{
Serial.begin(115200);
tft.init();
tft.setRotation(1);
touchSPI.begin(
TOUCH_SCLK,
TOUCH_MISO,
TOUCH_MOSI,
TOUCH_CS
);
ts.begin(touchSPI);
int x1,y1;
int x2,y2;
int x3,y3;
int x4,y4;
getCalibrationPoint(
"Touch TOP LEFT",
20,
20,
TFT_RED,
x1,
y1
);
getCalibrationPoint(
"Touch TOP RIGHT",
300,
20,
TFT_GREEN,
x2,
y2
);
getCalibrationPoint(
"Touch BOTTOM LEFT",
20,
220,
TFT_BLUE,
x3,
y3
);
getCalibrationPoint(
"Touch BOTTOM RIGHT",
300,
220,
TFT_YELLOW,
x4,
y4
);
tft.fillScreen(TFT_BLACK);
Serial.println();
Serial.println("===== Calibration Result =====");
Serial.printf("TOP LEFT : X=%d Y=%d\n", x1, y1);
Serial.printf("TOP RIGHT : X=%d Y=%d\n", x2, y2);
Serial.printf("BOTTOM LEFT : X=%d Y=%d\n", x3, y3);
Serial.printf("BOTTOM RIGHT : X=%d Y=%d\n", x4, y4);
Serial.println("==============================");
tft.drawString("Calibration Done", 50, 100);
}
void loop()
{
}
點擊四角:
TOP LEFT
TOP RIGHT
BOTTOM LEFT
BOTTOM RIGHT
觸控校正數值
實測校正結果:
#define TS_MINX 608
#define TS_MAXX 3714
#define TS_MINY 544
#define TS_MAXY 3545
轉換為螢幕座標:
int tx = map(
p.x,
TS_MAXX,
TS_MINX,
0,
320
);
int ty = map(
p.y,
TS_MAXY,
TS_MINY,
0,
240
);
打地鼠遊戲核心功能
程式載點:Whack A Mole Code
洞穴繪製
tft.fillCircle(x, y, 35, TFT_DARKGREY);
地鼠繪製
tft.fillCircle(x, y, 28, TFT_BROWN);
擊中判斷
int dx = tx - holes[moleIndex].x;
int dy = ty - holes[moleIndex].y;
if ((dx * dx + dy * dy) < 900)
{
score++;
}
倒數計時
int remain =
30 - ((millis() - gameStart) / 1000);
遊戲結束
if ((millis() - gameStart) >= 30000)
{
showGameOver();
}
常見問題 FAQ
ILI9341 螢幕沒有顯示?
請確認:
- TFT_CS 腳位正確
- TFT_DC 腳位正確
- TFT_eSPI 設定檔已修改
- SPI 頻率未設過高
XPT2046 觸控沒反應?
請確認:
- T_CS 是否正確
- 是否執行校正程式
- Touch SPI 是否獨立設定
為什麼 ESP32-S3 與 XPT2046 要分開 SPI?
原因是部分 ILI9341 模組共用 SPI 容易造成:
- 螢幕閃爍
- 觸控失效
- 座標飄移
採用獨立 SPI 可提高穩定度。
結語
透過本教學,您已成功使用 ESP32-S3 搭配 ILI9341 觸控螢幕完成一個互動式打地鼠遊戲。不僅學會 TFT 圖形介面設計,也掌握了 XPT2046 觸控應用技巧,未來可延伸至智慧家居控制面板、IoT 顯示器、教育互動設備、AI 人機介面等各種專案。
更多 ESP32、Arduino、樹莓派與電子模組教學,歡迎持續關注:
** 米羅科技 Mirotek**

