Arduino TFT Touch Screen Example: A Complete Guide for Beginners(English Version)
Arduino TFT Touch Screen Example: A Complete Guide for Beginners(English Version)
1. Introduction: The Value of Combining Arduino with TFT Touch Screens
In Arduino project development, visual interaction is key to enhancing user experience, and TFT touch screens provide a convenient solution for this. TFT (Thin-Film Transistor) touch screens integrate display and touch control functions, enabling graphic display, data visualization, and touch operations. They are widely used in smart control terminals, portable monitoring devices, creative interactive installations, and more. This article uses the most common ILI9341 TFT touch screen as an example to provide a complete Arduino practical guide, including hardware wiring, software configuration, code analysis, and troubleshooting, helping beginners quickly master the use of Arduino TFT touch screens.
2. Essential Materials List (Compatible with Mainstream Arduino Models)
1. Hardware Components
- Microcontroller Board: Arduino Uno/Nano/Mega (Uno is recommended for cost-effectiveness and rich documentation);
- TFT Touch Screen Module: ILI9341 driver chip (1.8-inch/2.4-inch, supports SPI communication, resolution 240×320);
- Connection Wires: Jumper wires (male-to-female, at least 10 pieces for signal transmission between the module and Arduino);
- Power Supply: 5V/2A DC power supply (external power is recommended if using external sensors to avoid insufficient USB power for Arduino);
- Auxiliary Tool: Breadboard (optional, for simplifying wiring and avoiding messy connections).
2. Software Tools
- Arduino IDE: Latest official version (download link: https://www.arduino.cc/en/software, supports code compilation and upload);
- Core Libraries: Adafruit_ILI9341 Library (for TFT display driver), Adafruit_GFX Library (basic graphics drawing library), Adafruit_TouchScreen Library (for touch function support).
3. Hardware Wiring Steps (Arduino Uno & ILI9341 Example)
ILI9341 Module Pin
|
Function Description
|
Arduino Uno Pin
|
VCC
|
Power Input
|
3.3V (Important! Do not connect to 5V to avoid burning the screen)
|
GND
|
Ground
|
GND
|
CS (Chip Select)
|
Chip Selection
|
D10
|
RESET
|
Reset
|
D9
|
DC (Data/Command)
|
Data/Command Switch
|
D8
|
SDI (MOSI)
|
Serial Data Input
|
D11
|
SCK
|
Serial Clock
|
D13
|
LED
|
Backlight Control (Optional)
|
D7 (High level to turn on, low level to turn off)
|
T_CLK
|
Touch Clock
|
D6
|
T_CS
|
Touch Chip Selection
|
D5
|
T_DIN
|
Touch Data Input
|
D4
|
T_DOUT
|
Touch Data Output
|
D3
|
T_IRQ
|
Touch Interrupt (Optional)
|
D2
|
Wiring Notes
- Power Supply Must Be 3.3V: Most ILI9341 modules use 3.3V power; connecting to 5V will directly burn the driver chip;
- Accurate Pin Alignment: SCK and MOSI pins for SPI communication are Arduino hardware SPI pins (D11-D13 for Uno) and cannot be replaced randomly;
- Backlight Control (Optional): If backlight adjustment is not needed, connect the LED pin directly to 3.3V (always on) or GND (always off).
4. Software Preparation: Library Installation & Environment Configuration
1. Install Adafruit_GFX Library
- Open Arduino IDE, click 「Sketch」→「Include Library」→「Manage Libraries」;
- Enter "Adafruit GFX Library" in the search box, find the library, and click 「Install」;
- Wait for installation to complete (if dependent libraries are prompted, select "Install All").
2. Install Adafruit_ILI9341 Library
- Similarly, search for "Adafruit ILI9341" in the Library Manager and install the latest version;
- This library depends on the Adafruit_GFX Library, so ensure the former is installed first.
3. Install Adafruit_TouchScreen Library
- Search for "Adafruit TouchScreen" and install it to parse touch coordinate data.
4. Verify the Environment
5. Practical Examples: 4 Core Function Code Analysis
Example 1: Basic TFT Display Test (Verify Display Function)
// Include core libraries#include <Adafruit_GFX.h>#include <Adafruit_ILI9341.h>// Define pins (match hardware wiring)#define TFT_CS 10#define TFT_RST 9#define TFT_DC 8#define TFT_MOSI 11#define TFT_SCK 13// Create TFT screen objectAdafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCK, TFT_RST);void setup() { Serial.begin(9600); // Initialize serial port (for debugging) tft.begin(); // Initialize TFT screen // Set screen rotation (0-3 for different orientations, adjust as needed) tft.setRotation(3); // Clear screen (black background) tft.fillScreen(ILI9341_BLACK); // Display title (red text, font size 2) tft.setTextColor(ILI9341_RED); tft.setTextSize(2); tft.setCursor(50, 20); // Set text position (x=50, y=20) tft.println("Arduino TFT Test"); // Draw a line (blue, from (20,50) to (220,50)) tft.drawLine(20, 50, 220, 50, ILI9341_BLUE); // Draw a rectangle (green, top-left (40,70), bottom-right (200,130), hollow) tft.drawRect(40, 70, 160, 60, ILI9341_GREEN); // Draw a filled circle (yellow, center (120,200), radius 50) tft.fillCircle(120, 200, 50, ILI9341_YELLOW); // Print debug information to serial port Serial.println("TFT display test completed!");}void loop() { // No loop operation in this example; display runs once}
Code Analysis
- tft.begin(): Initializes the TFT screen, must be called in setup();
- tft.setRotation(3): Adjusts screen orientation (0 for default portrait, 3 for landscape, suitable for most scenarios);
- ILI9341_XXX: Predefined color constants, such as ILI9341_RED (red) and ILI9341_BLACK (black);
- setTextSize(n): Sets text size (n ranges from 1-7; larger values mean bigger text, which may be truncated if exceeding the screen).
Example 2: Touch Coordinate Reading (Get Touch Position)
#include <Adafruit_GFX.h>#include <Adafruit_ILI9341.h>#include <Adafruit_TouchScreen.h>// TFT pin definitions (same as Example 1)#define TFT_CS 10#define TFT_RST 9#define TFT_DC 8#define TFT_MOSI 11#define TFT_SCK 13// Touch pin definitions (match hardware wiring)#define TS_CLK 6#define TS_CS 5#define TS_DIN 4#define TS_DOUT 3#define TS_IRQ 2// Create TFT and touch objectsAdafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCK, TFT_RST);Adafruit_TouchScreen ts = Adafruit_TouchScreen(TS_CS, TS_DIN, TS_DOUT, TS_CLK, TS_IRQ);// Define screen resolution (240×320 for ILI9341)#define TFT_WIDTH 240#define TFT_HEIGHT 320void setup() { Serial.begin(9600); tft.begin(); tft.setRotation(3); tft.fillScreen(ILI9341_BLACK); // Display prompt text tft.setTextColor(ILI9341_WHITE); tft.setTextSize(2); tft.setCursor(20, 20); tft.println("Touch Screen Test"); tft.setTextSize(1); tft.setCursor(20, 50); tft.println("Touch the screen to see coordinates:");}void loop() { // Read touch status TSPoint p = ts.getPoint(); // Get touch point data // Check if there is a touch (TS_IRQ pin is low when touched) pinMode(TS_IRQ, INPUT); if (digitalRead(TS_IRQ) == LOW) { // Calibrate coordinates (X/Y of touch module may be reversed, adjust if needed) int x = map(p.y, 200, 900, 0, TFT_WIDTH); // Map X coordinate (adjust parameters based on actual touch range) int y = map(p.x, 200, 900, 0, TFT_HEIGHT); // Map Y coordinate // Constrain coordinates within screen range (avoid exceeding display area) x = constrain(x, 0, TFT_WIDTH - 1); y = constrain(y, 0, TFT_HEIGHT - 1); // Display coordinates on screen (clear previous coordinate text first) tft.fillRect(20, 80, 200, 30, ILI9341_BLACK); // Black rectangle covers old text tft.setTextColor(ILI9341_GREEN); tft.setCursor(20, 80); tft.print("X: "); tft.print(x); tft.print(" | Y: "); tft.print(y); // Print coordinates to serial port (for debugging) Serial.print("Touch Coordinates: X="); Serial.print(x); Serial.print(", Y="); Serial.println(y); delay(100); // Delay to avoid excessive data refresh }}
Key Notes
- ts.getPoint(): Gets raw touch data (p.x, p.y, p.z; z is pressure value, can be ignored);
- map() function: Maps raw coordinates of the touch module (usually 200-900) to screen resolution (0-239/0-319). If coordinates are reversed, swap the second and third parameters of map() (e.g., map(p.y, 900, 200, 0, TFT_WIDTH));
- constrain() function: Limits coordinates within the screen range to prevent text from exceeding the display area.
Example 3: Touch Drawing (Simple Drawing Board)
#include <Adafruit_GFX.h>#include <Adafruit_ILI9341.h>#include <Adafruit_TouchScreen.h>// Pin definitions (same as Example 2)#define TFT_CS 10#define TFT_RST 9#define TFT_DC 8#define TFT_MOSI 11#define TFT_SCK 13#define TS_CLK 6#define TS_CS 5#define TS_DIN 4#define TS_DOUT 3#define TS_IRQ 2Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCK, TFT_RST);Adafruit_TouchScreen ts = Adafruit_TouchScreen(TS_CS, TS_DIN, TS_DOUT, TS_CLK, TS_IRQ);#define TFT_WIDTH 240#define TFT_HEIGHT 320// Define variables: last touch coordinates, current colorint lastX = -1, lastY = -1;uint16_t currentColor = ILI9341_RED; // Initial color: redvoid setup() { Serial.begin(9600); tft.begin(); tft.setRotation(3); tft.fillScreen(ILI9341_BLACK); // Display operation prompts tft.setTextColor(ILI9341_WHITE); tft.setTextSize(1); tft.setCursor(10, 10); tft.println("Draw Board: Touch to draw"); tft.setCursor(10, 25); tft.println("Double-tap top-right (X>200,Y<50) to change color");}void loop() { TSPoint p = ts.getPoint(); pinMode(TS_IRQ, INPUT); if (digitalRead(TS_IRQ) == LOW) { // Calibrate coordinates int x = map(p.y, 200, 900, 0, TFT_WIDTH); int y = map(p.x, 200, 900, 0, TFT_HEIGHT); x = constrain(x, 0, TFT_WIDTH - 1); y = constrain(y, 0, TFT_HEIGHT - 1); // Double-tap top-right corner to switch color (X>200, Y<50) if (x > 200 && y < 50) { changeColor(); delay(300); // Delay to avoid false triggers } // Draw lines (connect two points if last coordinates are valid) else if (lastX != -1 && lastY != -1) { tft.drawLine(lastX, lastY, x, y, currentColor); } // Update last coordinates lastX = x; lastY = y; } else { // Reset last coordinates when no touch lastX = -1; lastY = -1; } delay(20);}// Color switching functionvoid changeColor() { switch(currentColor) { case ILI9341_RED: currentColor = ILI9341_GREEN; break; case ILI9341_GREEN: currentColor = ILI9341_BLUE; break; case ILI9341_BLUE: currentColor = ILI9341_YELLOW; break; case ILI9341_YELLOW: currentColor = ILI9341_RED; break; } // Display current color prompt tft.fillRect(10, 40, 220, 20, ILI9341_BLACK); // Clear old prompt tft.setTextColor(currentColor); tft.setCursor(10, 40); tft.print("Current Color: "); if (currentColor == ILI9341_RED) tft.print("Red"); else if (currentColor == ILI9341_GREEN) tft.print("Green"); else if (currentColor == ILI9341_BLUE) tft.print("Blue"); else if (currentColor == ILI9341_YELLOW) tft.print("Yellow");}
Feature Highlights
- Continuous Drawing: Records the last touch coordinates to draw continuous lines when the touch moves;
- Color Switching: Double-tap the top-right corner of the screen (X>200, Y<50) to cycle through red, green, blue, and yellow;
- Operation Prompts: Displays function instructions at the top of the screen for user convenience.
Example 4: Touch-Controlled LED (Interactive Control Practice)
#include <Adafruit_GFX.h>#include <Adafruit_ILI9341.h>#include <Adafruit_TouchScreen.h>// Pin definitions#define TFT_CS 10#define TFT_RST 9#define TFT_DC 8#define TFT_MOSI 11#define TFT_SCK 13#define TS_CLK 6#define TS_CS 5#define TS_DIN 4#define TS_DOUT 3#define TS_IRQ 2#define LED_PIN 13 // Onboard LED pinAdafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCK, TFT_RST);Adafruit_TouchScreen ts = Adafruit_TouchScreen(TS_CS, TS_DIN, TS_DOUT, TS_CLK, TS_IRQ);#define TFT_WIDTH 240#define TFT_HEIGHT 320// Define button parameters (Position: X=80, Y=120; Size: 80px wide, 40px high)#define BUTTON_X 80#define BUTTON_Y 120#define BUTTON_W 80#define BUTTON_H 40bool ledState = false; // LED state (false=off, true=on)void setup() { Serial.begin(9600); pinMode(LED_PIN, OUTPUT); // Set LED pin as output mode digitalWrite(LED_PIN, LOW); // Initial LED state: off tft.begin(); tft.setRotation(3); tft.fillScreen(ILI9341_BLACK); // Draw button and title drawButton(); tft.setTextColor(ILI9341_WHITE); tft.setTextSize(2); tft.setCursor(50, 80); tft.println("LED Controller");}void loop() { TSPoint p = ts.getPoint(); pinMode(TS_IRQ, INPUT); if (digitalRead(TS_IRQ) == LOW) { // Calibrate coordinates int x = map(p.y, 200, 900, 0, TFT_WIDTH); int y = map(p.x, 200, 900, 0, TFT_HEIGHT); x = constrain(x, 0, TFT_WIDTH - 1); y = constrain(y, 0, TFT_HEIGHT - 1); // Check if the button area is touched (X between BUTTON_X ~ BUTTON_X+BUTTON_W, same for Y) if (x >= BUTTON_X && x <= BUTTON_X + BUTTON_W && y >= BUTTON_Y && y <= BUTTON_Y + BUTTON_H) { ledState = !ledState; // Toggle LED state digitalWrite(LED_PIN, ledState); // Update LED hardware state drawButton(); // Refresh button display (sync state) delay(300); // Delay to avoid false triggers } }}// Draw button function (change button color based on LED state)void drawButton() { if (ledState) { // When LED is on: green filled button, white text tft.fillRect(BUTTON_X, BUTTON_Y, BUTTON_W, BUTTON_H, ILI9341_GREEN); tft.setTextColor(ILI9341_WHITE); } else { // When LED is off: gray filled button, black text tft.fillRect(BUTTON_X, BUTTON_Y, BUTTON_W, BUTTON_H, ILI9341_GRAY); tft.setTextColor(ILI9341_BLACK); } // Center text on the button tft.setTextSize(1); tft.setCursor(BUTTON_X + 20, BUTTON_Y + 12); // Adjust text position to center tft.print(ledState ? "ON" : "OFF");}
Practical Significance
- Linked Control: Demonstrates the interaction logic between TFT touch and external hardware (LED), which can be extended to relays, motors, sensors, etc.;
- State Synchronization: Button color is synchronized with LED state in real time to enhance user interaction experience;
- Area Detection: Judges touch position through coordinate range, which is the basis for implementing multi-button and menu interaction.
6. Common Issues & Solutions
1. Screen Not Lighting Up
- Cause 1: Power Issue: Not connected to 3.3V or poor contact;
- Solution: Check if the VCC pin is connected to Arduino's 3.3V, ensure GND is reliably grounded, and use a multimeter to measure if the module's power supply voltage is 3.3V.
- Cause 2: Incorrect Reset Pin Connection: TFT_RST pin is not connected or connected incorrectly;
- Solution: Confirm the TFT_RST pin is connected to Arduino's D9 (consistent with code definition). You can temporarily connect TFT_RST to 3.3V for testing (reconnect as defined after normal operation).
- Cause 3: Library or Code Error: Libraries not installed or pin definitions do not match wiring;
- Solution: Reinstall the Adafruit_ILI9341 Library and verify that the #define pins in the code match the hardware wiring.
2. Unresponsive Touch
- Cause 1: Incorrect Touch Pin Wiring: Touch pins such as T_CLK and T_CS are not connected as defined;
- Solution: Recheck touch-related pins (TS_CLK, TS_CS, TS_DIN, TS_DOUT, TS_IRQ) against the wiring table in this article.
- Cause 2: Touch Module Not Initialized: Adafruit_TouchScreen object not created or ts.getPoint() not called;
- Solution: Ensure the code includes the statement Adafruit_TouchScreen ts = ... and calls ts.getPoint() in loop() to read touch data.
- Cause 3: TS_IRQ Pin Not Handled: Not detecting IRQ pin level to judge touch state;
- Solution: The code must use digitalRead(TS_IRQ) == LOW to judge if there is a touch (IRQ is low when touched).
3. Touch Coordinate Offset
- Cause: Incorrect Mapping Parameters: The raw coordinate range (e.g., 200-900) in the map() function does not match the actual touch module;
- Solution: In the code of Example 2, the serial port outputs raw touch data (p.x, p.y). Touch the four corners of the screen, record the minimum and maximum values of the raw coordinates, and replace the second and third parameters of the map() function (e.g., if the raw X range is 150-950, use map(p.y, 150, 950, 0, TFT_WIDTH)).
4. Abnormal Text/Graphics Display (Exceeding Screen, Blur)
- Cause 1: Incorrect Screen Rotation: Improper parameter setting for tft.setRotation();
- Solution: Try modifying the parameter of setRotation() (0-3) until the display orientation matches the touch orientation.
- Cause 2: Excessively Large Text Size: setTextSize() parameter exceeds the screen's capacity;
- Solution: Reduce the text size (1-3 is recommended) or adjust the text position (setCursor()) to avoid exceeding the screen.
7. Summary & Extension Suggestions
- Data Visualization: Combine temperature-humidity sensors (DHT11), photoresistors, etc., to display sensor data in real time on the TFT screen;
- Multi-Page Interaction: Implement menu switching and page navigation (triggered by touching different areas);
- Storage & Reading: Use an SD card module to display images and text files from the SD card on the TFT screen;
- Advanced Graphics: Use the drawBitmap() function of the Adafruit_GFX Library to display custom icons or images (images need to be converted to array format).