아두이노 ILI9341 ILI9488 ST7789 TFT LCD 터치 디스플레이 SPI 인터페이스

이 튜토리얼은 Arduino에서 SPI TFT 디스플레이를 사용하는 방법을 안내합니다. 자세히 다음을 배울 것입니다:

이 튜토리얼은 터치 및 비터치 SPI TFT LCD 디스플레이를 모두 다룹니다. ILI9341, ILI9488, 또는 ST7789 컨트롤러 칩이 탑재된 1.3, 1.54, 2.2, 2.4, 2.8, 3.2, 3.5인치 패널에서 작동합니다.

아두이노 tft spi 디스플레이

팁 — 더 간단하고 빠른 대안: Arduino Uno를 사용하는 경우 대신 TFT 터치 쉴드를 고려해 보세요. Uno 헤더에 직접 꽂히므로 점퍼 와이어와 레벨 컨버터가 필요 없습니다. 8비트 병렬 인터페이스를 사용하여 SPI보다 픽셀 데이터를 훨씬 빠르게 전송합니다.

필요한 하드웨어

1×아두이노 우노 R3 쿠팡 | 아마존
1×USB 2.0 타입 A-to-B 케이블 (USB-A PC용) 쿠팡 | 아마존
1×USB 2.0 타입 C-to-B 케이블 (USB-C PC용) 아마존
1×SPI TFT display module 쿠팡 | 아마존
1×5V to 3.3V Level Converter 아마존
1×점퍼케이블 쿠팡 | 아마존
1×(추천) 아두이노 우노용 스크루 터미널 블록 쉴드 쿠팡 | 아마존
1×(추천) Sensors/Servo Expansion Shield for Arduino Uno 아마존
1×(추천) 아두이노 우노용 브레드보드 쉴드 쿠팡 | 아마존
1×(추천) 아두이노 우노용 케이스 쿠팡 | 아마존
1×(추천) 아두이노 우노용 프로토타이핑 베이스 플레이트 & 브레드보드 키트 아마존
공개: 이 포스팅 에 제공된 일부 링크는 아마존 제휴 링크입니다. 이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.

SPI TFT 디스플레이 개요

SPI TFT 디스플레이는 SPI(직렬 주변 인터페이스) 버스를 통해 제어되는 풀컬러 LCD 패널입니다. ILI9341, ILI9488, 또는 ST7789와 같은 전용 드라이버 칩을 사용하여 드로잉 명령을 받고 픽셀 데이터를 관리합니다.

주요 사항:

  • ILI9341 - 16비트 RGB565 색상, 최대 40MHz SPI.
  • ILI9488 - 18비트 RGB666 색상, 최대 24MHz SPI.
  • ST7789 - 16비트 RGB565 색상, 최대 40MHz SPI.

권장 사항: 디스플레이를 아직 구매하지 않은 경우 ST7789 드라이버를 권장합니다. 널리 구할 수 있고, 최대 40MHz SPI 속도로 실행되며, 새 프로젝트에 가장 간단한 선택입니다.

핀아웃

대부분의 SPI TFT LCD 디스플레이에는 다음 핀이 있습니다:

디스플레이 핀:

기능
VCC 전원 공급
GND 그라운드
CS 칩 선택 — SPI 버스에서 디스플레이를 선택하기 위해 LOW로 당김
DC / RS 데이터/명령 선택 — 픽셀 데이터는 HIGH, 명령은 LOW
RST 하드웨어 리셋 — 선택 사항; 사용하지 않으면 3.3V에 연결
MOSI / SDI / SDA SPI 데이터 입력(MCU → 디스플레이)
SCK / CLK SPI 클록
MISO / SDO SPI 데이터 출력(디스플레이 → MCU) — 디스플레이 전용 사용 시 선택 사항
LED / BL / BLK 백라이트 전원 — 3.3V 또는 밝기 조절을 위한 PWM 핀에 연결

SD 카드 핀(애플리케이션에서 SD 카드에 접근해야 하는 경우):

기능
SD_CS / TF_CS SD 카드 칩 선택
MOSI / SDI MOSI — MCU에서 SD 카드로 데이터
SCK / CLK SCK — SPI 클록
MISO / SDO MISO — SD 카드에서 MCU로 데이터

터치를 지원하는 TFT 디스플레이의 경우 추가 터치 핀이 있습니다(애플리케이션에서 터치 기능을 사용하고 디스플레이가 지원하는 경우):

기능
T_CS 터치 컨트롤러 칩 선택
T_CLK SCK — SPI 클록
T_DIN MOSI — MCU에서 터치 컨트롤러로 데이터
T_DO MISO — 터치 컨트롤러에서 MCU로 데이터
T_IRQ 터치 인터럽트 — 선택 사항; 화면이 터치될 때 신호를 보냄

참고: 일부 비터치 디스플레이 모듈도 T_CS, T_CLK, T_DIN, T_DO, T_IRQ 핀을 노출합니다. 이러한 보드에서는 작동하지 않습니다 — 터치 컨트롤러 IC가 실장되어 있지 않습니다. 제조 변형을 줄이기 위해 터치 지원 버전과 동일한 레이아웃을 재사용하는 PCB이기 때문에 나타납니다.

tft spi 디스플레이 핀아웃

배선도

⚠ 중요 — 전압 불일치: Arduino Uno는 5V 보드입니다. GPIO 핀은 5V 로직을 출력하지만 SPI TFT 디스플레이는 3.3V에서 작동합니다. Uno에서 디스플레이로 신호선(MOSI, SCK, CS, DC, RST, 터치 사용 시 T_CS)을 직접 연결하면 디스플레이가 손상됩니다. Uno와 디스플레이 사이의 모든 MCU 구동 신호선에 5V to 3.3V 레벨 컨버터를 사용해야 합니다. MISO 라인(디스플레이 → MCU)은 레벨 컨버터가 필요 없습니다. 비터치 배선에는 단일 4채널 모듈로 충분합니다. 터치가 있는 배선에는 총 6채널이 필요하므로(T_CS 추가) 4채널 모듈 두 개 또는 8채널 모듈 하나를 사용합니다. TFT VCC를 Uno의 3.3V 핀에 연결합니다.

터치 없는 경우

디스플레이:

TFT 핀 Arduino Uno 핀 설명
VCC 3.3V 또는 5V 전원 공급
GND GND 그라운드
CS D10 칩 선택
DC / RS D9 데이터/명령 선택
RST D8 리셋(선택 사항)
MOSI / SDI D11 하드웨어 SPI MOSI
SCK D13 하드웨어 SPI 클록
MISO / SDO D12 하드웨어 SPI MISO(선택 사항)
LED / BL 3.3V 백라이트 전원

SD 카드(애플리케이션에서 SD 카드에 접근해야 하는 경우):

SD 핀 Arduino Uno 핀 설명
SD_CS / TF_CS 사용 가능한 GPIO SD 카드 칩 선택
MOSI / SDI D11 디스플레이 MOSI(D11)와 공유
SCK / CLK D13 디스플레이 SCK(D13)와 공유
MISO / SDO D12 디스플레이 MISO(D12)와 공유
터치 없는 아두이노 tft spi 디스플레이 배선도

이 이미지는 Fritzing을 사용하여 만들어졌습니다. 이미지를 확대하려면 클릭하세요.

터치가 있는 경우

디스플레이:

TFT 핀 Arduino Uno 핀 설명
VCC 3.3V 또는 5V 전원 공급
GND GND 그라운드
CS D10 칩 선택
DC / RS D9 데이터/명령 선택
RST D8 리셋(선택 사항)
MOSI / SDI D11 하드웨어 SPI MOSI
SCK D13 하드웨어 SPI 클록
MISO / SDO D12 하드웨어 SPI MISO(선택 사항)
LED / BL 3.3V 백라이트 전원

터치 컨트롤러(애플리케이션에서 터치 기능을 사용하고 디스플레이가 지원하는 경우):

터치 핀 Arduino Uno 핀 설명
T_CS 사용 가능한 GPIO 터치 칩 선택
T_IRQ 사용 가능한 GPIO 터치 인터럽트(선택 사항)
T_DIN D11 디스플레이 MOSI(D11)와 공유
T_CLK D13 디스플레이 SCK(D13)와 공유
T_DO D12 디스플레이 MISO(D12)와 공유
터치가 있는 아두이노 tft spi 디스플레이 배선도

이 이미지는 Fritzing을 사용하여 만들어졌습니다. 이미지를 확대하려면 클릭하세요.

MCU에 두 개 이상의 하드웨어 SPI 인터페이스가 있는 경우 각 주변 장치(디스플레이, SD 카드, 터치 컨트롤러)를 전용 SPI 버스에 할당할 수 있습니다. MCU에 하드웨어 SPI 인터페이스가 하나만 있는 경우 세 가지 주변 장치 모두 동일한 세 개의 데이터 라인(MOSI, SCK, MISO)을 공유합니다. 각 주변 장치에는 고유한 CS 핀이 있으므로 한 번에 하나만 활성화됩니다. DIYables_TFT_SPI 라이브러리는 단일 API를 통해 디스플레이와 XPT2046 터치 컨트롤러를 모두 관리합니다.

라이브러리 설치 방법

  1. USB 케이블을 사용하여 Arduino를 컴퓨터에 연결합니다.
  2. Arduino IDE에서 올바른 보드와 포트가 선택되었는지 확인합니다.
  3. 왼쪽 사이드바에서 Libraries 아이콘을 클릭합니다.
  4. 검색창에 "DIYables_TFT_SPI"를 입력하고 DIYables에서 게시한 라이브러리를 찾습니다.
  5. Install을 클릭하여 라이브러리를 추가합니다. 메시지가 표시되면 Adafruit GFX Library 의존성도 설치합니다.
  • Search for DIYables TFT SPI created by DIYables.io and click the Install button.
Newbiely | Arduino IDE 2.3.8
──
File
Edit
Sketch
Tools
Help
Arduino Uno
Library Manager
Type:
All
Topic:
All
DIYables TFT SPI by DIYables.io
Works with both touch and non-touch versions of the same SPI TFT modules. Supports ILI9341 (240x320, 16-bit RGB565), ILI9488 (320x480, 18-bit RGB666), and ST7789 (240x320, 16-bit RGB565) displays over SPI. Includes built-in driver for XPT2046 / HR2046 / ADS7843 SPI touch controllers and 4-wire resistive touch panels - no separate touch library required. Use the display-only API for non-touch panels, or add initTouchSPI() to enable touch on modules that include a touch controller. Extends Adafruit GFX for full graphics support. Works with any Arduino-compatible board that has SPI. More info
1.0.1
INSTALL
Newbiely.ino
···
1 void setup() {
Output
Serial Monitor
Ln 1, Col 1
Arduino Uno on COM15
1

최소 스케치 구조

DIYables_TFT_SPI 라이브러리를 사용하는 모든 스케치는 다음 기본 구조를 공유합니다:

#include <DIYables_TFT_SPI.h> #define TFT_CS_PIN 10 #define TFT_DC_PIN 9 #define TFT_RST_PIN 8 // Uncomment the line that matches your driver chip: // DIYables_ILI9341_SPI TFT_display(240, 320, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); // DIYables_ILI9488_SPI TFT_display(320, 480, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); DIYables_ST7789_SPI TFT_display(240, 320, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); void setup() { TFT_display.begin(); TFT_display.setRotation(1); } void loop() { // drawing code here }

생성자에 패널의 물리적 픽셀 크기를 전달합니다. 동일한 드라이버 칩을 가진 모듈도 다양한 크기로 제공됩니다.

도형 그리기

DrawShapes 예제는 Adafruit GFX 그리기 기본 요소를 시연합니다: 원, 삼각형, 사각형, 둥근 사각형, 선.

/* * 이 아두이노 코드는 newbiely.kr 에서 개발되었습니다 * 이 아두이노 코드는 어떠한 제한 없이 공개 사용을 위해 제공됩니다. * 상세한 지침 및 연결도에 대해서는 다음을 방문하세요: * https://newbiely.kr/tutorials/arduino/arduino-tft-lcd-touch-display-spi */ /* Created by DIYables This example code is in the public domain Product page: https://diyables.io */ // ============================================= // Single include brings in the base class plus all driver classes. // ============================================= #include <DIYables_TFT_SPI.h> // ============================================= // Wiring (Arduino Uno / Nano) // --------------------------------------------- // TFT module Arduino Uno / Nano // ------------ --------------------------------- // VCC -> 5V // GND -> GND // CS -> D10 (TFT_CS_PIN) // RESET -> D8 (TFT_RST_PIN) // DC / RS -> D9 (TFT_DC_PIN) // SDI / MOSI -> D11 (hardware SPI MOSI) // SCK -> D13 (hardware SPI SCK) // LED -> 3.3V (or any GPIO via initBacklight) // SDO / MISO -> D12 (only needed when reading from display) // ============================================= // ============================================= // SPI pin definitions (adjust for your board) // ============================================= #define TFT_CS_PIN 10 #define TFT_DC_PIN 9 #define TFT_RST_PIN 8 // Panel resolution in native (portrait) orientation - change to match your module #define TFT_WIDTH 240 #define TFT_HEIGHT 320 // MOSI and SCK use default hardware SPI pins // ============================================= // Create display object (uncomment matching driver) // ============================================= // DIYables_ILI9341_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); // DIYables_ILI9488_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); DIYables_ST7789_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); #define BLACK DIYables_TFT_SPI::colorRGB(0, 0, 0) #define BLUE DIYables_TFT_SPI::colorRGB(0, 0, 255) #define RED DIYables_TFT_SPI::colorRGB(255, 0, 0) #define GREEN DIYables_TFT_SPI::colorRGB(0, 255, 0) #define ORANGE DIYables_TFT_SPI::colorRGB(255, 165, 0) #define PINK DIYables_TFT_SPI::colorRGB(255, 192, 203) #define VIOLET DIYables_TFT_SPI::colorRGB(148, 0, 211) #define TURQUOISE DIYables_TFT_SPI::colorRGB(64, 224, 208) #define WHITE DIYables_TFT_SPI::colorRGB(255, 255, 255) // Helper to draw a filled diamond void fillDiamond(int cx, int cy, int h, int v, uint16_t color) { int x0 = cx, y0 = cy - v; int x1 = cx + h, y1 = cy; int x2 = cx, y2 = cy + v; int x3 = cx - h, y3 = cy; TFT_display.fillTriangle(x0, y0, x1, y1, x2, y2, color); TFT_display.fillTriangle(x0, y0, x2, y2, x3, y3, color); } void setup() { TFT_display.begin(); TFT_display.setRotation(1); // Landscape } void loop() { TFT_display.fillScreen(WHITE); uint16_t w = TFT_display.width(); uint16_t h = TFT_display.height(); // Scale positions relative to screen size with better spacing int col1 = w / 8; int col2 = w * 3 / 8; int col3 = w * 5 / 8; int col4 = w * 7 / 8; int row1 = h / 4; int row2 = h / 2; int row3 = h * 3 / 4; // Outlined circle TFT_display.drawCircle(col1, row1, 30, RED); // Filled circle TFT_display.fillCircle(col2, row1, 30, RED); // Outlined triangle TFT_display.drawTriangle(col3 - 30, row1 + 25, col3 + 30, row1 + 25, col3, row1 - 25, BLUE); // Filled triangle TFT_display.fillTriangle(col4 - 30, row1 + 25, col4 + 30, row1 + 25, col4, row1 - 25, GREEN); // Outlined rectangle TFT_display.drawRect(col1 - 35, row2 - 20, 70, 40, ORANGE); // Filled rectangle TFT_display.fillRect(col2 - 35, row2 - 20, 70, 40, TURQUOISE); // Outlined round rectangle TFT_display.drawRoundRect(col3 - 35, row2 - 20, 70, 40, 10, VIOLET); // Filled round rectangle TFT_display.fillRoundRect(col4 - 35, row2 - 20, 70, 40, 10, PINK); // Outlined diamond (centered between col1 and col2) int diamond1_x = (col1 + col2) / 2; TFT_display.drawLine(diamond1_x, row3 - 30, diamond1_x + 25, row3, GREEN); TFT_display.drawLine(diamond1_x + 25, row3, diamond1_x, row3 + 30, GREEN); TFT_display.drawLine(diamond1_x, row3 + 30, diamond1_x - 25, row3, GREEN); TFT_display.drawLine(diamond1_x - 25, row3, diamond1_x, row3 - 30, GREEN); // Filled diamond (centered between col3 and col4) int diamond2_x = (col3 + col4) / 2; fillDiamond(diamond2_x, row3, 25, 30, BLUE); delay(10000); }

실행 방법

  • 배선도에 표시된 대로 TFT 모듈을 Arduino에 연결합니다.
  • USB 케이블을 연결합니다.
  • Arduino IDE에서 코드를 붙여넣고, 올바른 보드와 포트를 선택하고, Upload를 누릅니다.
  • 디스플레이에 컬러 도형의 격자가 표시되며 몇 초마다 새로 고쳐집니다.

메서드 빠른 레퍼런스

메서드 설명 사용 예
begin() 디스플레이 컨트롤러를 초기화합니다. setup()에서 한 번 호출합니다. TFT_display.begin();
setRotation(r) 좌표계를 회전합니다. 0=세로, 1=가로. TFT_display.setRotation(1);
fillScreen(color) 화면을 단색으로 지웁니다. TFT_display.fillScreen(WHITE);
colorRGB(r,g,b) 8비트 구성 요소에서 16비트 RGB565 색상을 만듭니다. colorRGB(0, 128, 255)
fillCircle(x,y,r,color) 채워진 원을 그립니다. TFT_display.fillCircle(80, 80, 40, RED);
fillRect(x,y,w,h,color) 채워진 사각형을 그립니다. TFT_display.fillRect(10, 10, 60, 40, BLUE);
drawRoundRect(x,y,w,h,r,color) 둥근 사각형 외곽선을 그립니다. TFT_display.drawRoundRect(5,5,100,50,10,GREEN);

텍스트와 숫자 표시

ShowTextAndNumber 예제는 다양한 크기, 색상, 위치에서 문자열과 숫자를 출력하는 방법을 보여줍니다.

/* * 이 아두이노 코드는 newbiely.kr 에서 개발되었습니다 * 이 아두이노 코드는 어떠한 제한 없이 공개 사용을 위해 제공됩니다. * 상세한 지침 및 연결도에 대해서는 다음을 방문하세요: * https://newbiely.kr/tutorials/arduino/arduino-tft-lcd-touch-display-spi */ /* Created by DIYables This example code is in the public domain Product page: https://diyables.io */ // ============================================= // Single include brings in the base class plus all driver classes. // ============================================= #include <DIYables_TFT_SPI.h> // ============================================= // Wiring (Arduino Uno / Nano) // --------------------------------------------- // TFT module Arduino Uno / Nano // ------------ --------------------------------- // VCC -> 5V // GND -> GND // CS -> D10 (TFT_CS_PIN) // RESET -> D8 (TFT_RST_PIN) // DC / RS -> D9 (TFT_DC_PIN) // SDI / MOSI -> D11 (hardware SPI MOSI) // SCK -> D13 (hardware SPI SCK) // LED -> 3.3V (or any GPIO via initBacklight) // SDO / MISO -> D12 (only needed when reading from display) // ============================================= // ============================================= // SPI pin definitions (adjust for your board) // ============================================= #define TFT_CS_PIN 10 #define TFT_DC_PIN 9 #define TFT_RST_PIN 8 // Panel resolution in native (portrait) orientation - change to match your module #define TFT_WIDTH 240 #define TFT_HEIGHT 320 // ============================================= // Create display object (uncomment matching driver) // ============================================= // DIYables_ILI9341_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); // DIYables_ILI9488_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); DIYables_ST7789_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); #define MAGENTA DIYables_TFT_SPI::colorRGB(255, 0, 255) #define WHITE DIYables_TFT_SPI::colorRGB(255, 255, 255) void setup() { Serial.begin(9600); Serial.println(F("TFT SPI Display - Show text and numbers")); TFT_display.begin(); TFT_display.setRotation(1); // Landscape TFT_display.fillScreen(WHITE); // Set text color and size TFT_display.setTextColor(MAGENTA); TFT_display.setTextSize(3); // Sample values float temperature = 23.5; float humidity = 78.6; // Display temperature TFT_display.setCursor(20, 20); TFT_display.print("Temperature: "); TFT_display.print(temperature, 1); TFT_display.print(char(247)); TFT_display.println("C"); // Display humidity TFT_display.setCursor(20, 60); TFT_display.print("Humidity: "); TFT_display.print(humidity, 1); TFT_display.print("%"); } void loop() { }

실행 방법

  • 위와 같이 배선하고 업로드합니다.
  • 디스플레이에 여러 줄의 텍스트와 숫자 값이 출력됩니다.

메서드 빠른 레퍼런스

메서드 설명 사용 예
setTextColor(color) 텍스트 전경 색상을 설정합니다. TFT_display.setTextColor(BLACK);
setTextSize(size) 텍스트를 스케일합니다. 크기 1은 6x8픽셀입니다. TFT_display.setTextSize(2);
setCursor(x, y) 텍스트 커서를 배치합니다. TFT_display.setCursor(10, 30);
print(value) 커서 위치에 문자열이나 숫자를 출력합니다. TFT_display.print("Temp: ");
println(value) 출력 후 다음 줄로 이동합니다. TFT_display.println(25.4);

이미지 그리기

DrawImage 예제는 프로그램 메모리에 저장된 전체 색상 RGB565 비트맵 이미지를 표시합니다. 이미지 데이터는 PROGMEM으로 표시된 const uint16_t 배열로 bitmap.h에 선언됩니다. 컴파일 전에 bitmap.h를 스케치 폴더에 복사합니다.

/* * 이 아두이노 코드는 newbiely.kr 에서 개발되었습니다 * 이 아두이노 코드는 어떠한 제한 없이 공개 사용을 위해 제공됩니다. * 상세한 지침 및 연결도에 대해서는 다음을 방문하세요: * https://newbiely.kr/tutorials/arduino/arduino-tft-lcd-touch-display-spi */ /* Created by DIYables This example code is in the public domain Product page: https://diyables.io */ // ============================================= // Single include brings in the base class plus all driver classes. // ============================================= #include <DIYables_TFT_SPI.h> #include "bitmap.h" // ============================================= // Wiring (Arduino Uno / Nano) // --------------------------------------------- // TFT module Arduino Uno / Nano // ------------ --------------------------------- // VCC -> 5V // GND -> GND // CS -> D10 (TFT_CS_PIN) // RESET -> D8 (TFT_RST_PIN) // DC / RS -> D9 (TFT_DC_PIN) // SDI / MOSI -> D11 (hardware SPI MOSI) // SCK -> D13 (hardware SPI SCK) // LED -> 3.3V (or any GPIO via initBacklight) // SDO / MISO -> D12 (only needed when reading from display) // ============================================= // ============================================= // SPI pin definitions (adjust for your board) // ============================================= #define TFT_CS_PIN 10 #define TFT_DC_PIN 9 #define TFT_RST_PIN 8 // Panel resolution in native (portrait) orientation - change to match your module #define TFT_WIDTH 240 #define TFT_HEIGHT 320 // ============================================= // Create display object (uncomment matching driver) // ============================================= // DIYables_ILI9341_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); // DIYables_ILI9488_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); DIYables_ST7789_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); #define WHITE DIYables_TFT_SPI::colorRGB(255, 255, 255) int img_width = 120; int img_height = 53; void setup() { Serial.begin(9600); Serial.println(F("TFT SPI Display - Draw Image")); TFT_display.begin(); uint16_t SCREEN_WIDTH = TFT_display.width(); uint16_t SCREEN_HEIGHT = TFT_display.height(); int x = (SCREEN_WIDTH - img_width) / 2; int y = (SCREEN_HEIGHT - img_height) / 2; TFT_display.fillScreen(WHITE); TFT_display.drawRGBBitmap(x, y, myBitmap, img_width, img_height); } void loop() { delay(2000); TFT_display.invertDisplay(true); delay(2000); TFT_display.invertDisplay(false); }

실행 방법

  • Bitmap.h를 스케치 파일과 동일한 폴더에 넣습니다.
  • 배선도에 표시된 대로 TFT 모듈을 Arduino에 연결합니다.
  • USB 케이블을 연결합니다.
  • Arduino IDE에서 코드를 붙여넣고, 보드와 포트를 확인하고, Upload를 누릅니다.
  • 디스플레이에 프로그램 메모리에서 불러온 비트맵 이미지가 표시됩니다.

메서드 빠른 레퍼런스

메서드 설명 사용 예
drawRGBBitmap(x,y,bitmap,w,h) 픽셀 (x, y)부터 시작하여 RGB565 PROGMEM 비트맵을 그립니다. TFT_display.drawRGBBitmap(0, 0, myImage, 240, 320);
fillScreen(color) 이미지 그리기 전에 화면을 지웁니다. TFT_display.fillScreen(BLACK);

SD 카드 이미지 그리기

DrawImageSDcard 예제는 마이크로 SD 카드에서 원시 RGB565 바이너리 이미지 파일을 읽고 픽셀 데이터를 작은 청크로 직접 디스플레이에 전송합니다.

SD 카드 모듈을 디스플레이와 동일한 SPI 버스에 연결합니다. MOSI(D11), SCK(D13), MISO(D12)를 공유합니다. SD 모듈에 별도의 CS 핀을 할당합니다.

/* * 이 아두이노 코드는 newbiely.kr 에서 개발되었습니다 * 이 아두이노 코드는 어떠한 제한 없이 공개 사용을 위해 제공됩니다. * 상세한 지침 및 연결도에 대해서는 다음을 방문하세요: * https://newbiely.kr/tutorials/arduino/arduino-tft-lcd-touch-display-spi */ /* Created by DIYables This example code is in the public domain Product page: https://diyables.io */ // ============================================= // Single include brings in the base class plus all driver classes. // ============================================= #include <DIYables_TFT_SPI.h> #include <SD.h> // ============================================= // Wiring (Arduino Uno / Nano) // --------------------------------------------- // TFT + SD module Arduino Uno / Nano // ----------------------- --------------------------------- // VCC -> 5V // GND -> GND // TFT CS -> D10 (TFT_CS_PIN) // TFT RESET -> D8 (TFT_RST_PIN) // TFT DC / RS -> D9 (TFT_DC_PIN) // SD CS -> D4 (SD_CS) // SDI / MOSI (shared) -> D11 (hardware SPI MOSI) // SDO / MISO (shared) -> D12 (hardware SPI MISO) // SCK (shared) -> D13 (hardware SPI SCK) // LED -> 3.3V (or any GPIO via initBacklight) // ============================================= // ============================================= // SPI pin definitions (adjust for your board) // ============================================= #define TFT_CS_PIN 10 #define TFT_DC_PIN 9 #define TFT_RST_PIN 8 // Panel resolution in native (portrait) orientation - change to match your module #define TFT_WIDTH 240 #define TFT_HEIGHT 320 #define SD_CS 4 // SD card chip select (must differ from TFT_CS_PIN) // ============================================= // Create display object (uncomment matching driver) // ============================================= // DIYables_ILI9341_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); // DIYables_ILI9488_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); DIYables_ST7789_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); #define WHITE DIYables_TFT_SPI::colorRGB(255, 255, 255) #define BUFFPIXEL 20 File bmpFile; uint16_t SCREEN_WIDTH; uint16_t SCREEN_HEIGHT; // Helper functions to read BMP file header uint16_t read16(File &f) { uint16_t result; result = f.read(); result |= (f.read() << 8); return result; } uint32_t read32(File &f) { uint32_t result; result = f.read(); result |= ((uint32_t)f.read() << 8); result |= ((uint32_t)f.read() << 16); result |= ((uint32_t)f.read() << 24); return result; } int32_t readS32(File &f) { int32_t result; result = f.read(); result |= ((uint32_t)f.read() << 8); result |= ((uint32_t)f.read() << 16); result |= ((uint32_t)f.read() << 24); return result; } bool getBMPDimensions(const char *filename, uint32_t &w, uint32_t &h) { File f = SD.open(filename); if (!f) return false; if (read16(f) != 0x4D42) { f.close(); return false; } read32(f); // file size read32(f); // reserved read32(f); // image offset read32(f); // DIB header size w = read32(f); int32_t sh = readS32(f); h = (sh < 0) ? -sh : sh; f.close(); return true; } void drawBMP(const char *filename, int x, int y) { bmpFile = SD.open(filename); if (!bmpFile) { Serial.println("File not found"); return; } if (read16(bmpFile) != 0x4D42) { Serial.println("Not a BMP file"); bmpFile.close(); return; } uint32_t fileSize = read32(bmpFile); read32(bmpFile); // Reserved uint32_t imageOffset = read32(bmpFile); uint32_t dibHeaderSize = read32(bmpFile); uint32_t bmpWidth = read32(bmpFile); int32_t bmpHeight = readS32(bmpFile); bool topDown = false; if (bmpHeight < 0) { bmpHeight = -bmpHeight; topDown = true; } if (read16(bmpFile) != 1) { Serial.println("Invalid BMP file"); bmpFile.close(); return; } uint16_t depth = read16(bmpFile); if (depth != 24) { Serial.println("Only 24-bit BMP is supported"); bmpFile.close(); return; } if (read32(bmpFile) != 0) { Serial.println("Unsupported BMP compression"); bmpFile.close(); return; } bmpFile.seek(imageOffset); uint8_t sdbuffer[3 * BUFFPIXEL]; uint16_t color; uint32_t rowSize = (bmpWidth * 3 + 3) & ~3; if (x >= SCREEN_WIDTH || y >= SCREEN_HEIGHT) return; uint32_t maxRow = min((uint32_t)bmpHeight, (uint32_t)(SCREEN_HEIGHT - y)); uint32_t maxCol = min(bmpWidth, (uint32_t)(SCREEN_WIDTH - x)); for (uint32_t row = 0; row < maxRow; row++) { int32_t rowPos = topDown ? row : bmpHeight - 1 - row; uint32_t filePosition = imageOffset + rowPos * rowSize; bmpFile.seek(filePosition); for (uint32_t col = 0; col < maxCol; col += BUFFPIXEL) { uint32_t pixelsToRead = min((uint32_t)BUFFPIXEL, maxCol - col); bmpFile.read(sdbuffer, 3 * pixelsToRead); for (uint32_t i = 0; i < pixelsToRead; i++) { uint8_t b = sdbuffer[i * 3]; uint8_t g = sdbuffer[i * 3 + 1]; uint8_t r = sdbuffer[i * 3 + 2]; color = DIYables_TFT_SPI::colorRGB(r, g, b); if ((x + col + i) < SCREEN_WIDTH && (y + row) < SCREEN_HEIGHT) { TFT_display.drawPixel(x + col + i, y + row, color); } } } } bmpFile.close(); Serial.println("BMP drawn"); } void setup() { Serial.begin(9600); if (!SD.begin(SD_CS)) { Serial.println("SD card initialization failed!"); return; } Serial.println("SD card initialized."); TFT_display.begin(); TFT_display.setRotation(1); // Landscape SCREEN_WIDTH = TFT_display.width(); SCREEN_HEIGHT = TFT_display.height(); TFT_display.fillScreen(WHITE); uint32_t imgWidth, imgHeight; if (getBMPDimensions("diyables.bmp", imgWidth, imgHeight)) { int x = (SCREEN_WIDTH - imgWidth) / 2; int y = (SCREEN_HEIGHT - imgHeight) / 2; drawBMP("diyables.bmp", x, y); } else { Serial.println("Failed to get BMP dimensions"); } } void loop() { }

실행 방법

  • SD 모듈을 Arduino에 연결합니다. SPI 버스(D11/D13/D12)를 디스플레이와 공유하고 SD CS를 선택한 핀에 연결합니다.
  • SD 카드의 루트에 원시 RGB565 바이너리 이미지 파일을 복사합니다.
  • USB 케이블을 연결합니다.
  • Arduino IDE에서 코드를 붙여넣고, 보드와 포트를 확인하고, Upload를 누릅니다.

메서드 빠른 레퍼런스

메서드 설명 사용 예
startWrite() 직접 SPI 트랜잭션을 시작합니다. TFT_display.startWrite();
setAddrWindow(x0,y0,x1,y1) 쓸 직사각형 픽셀 영역을 정의합니다. TFT_display.setAddrWindow(0, 0, 239, 319);
pushColors(buf, len) RGB565 픽셀 값의 버퍼를 디스플레이로 전송합니다. TFT_display.pushColors(buf, 512);
endWrite() SPI 트랜잭션을 종료합니다. TFT_display.endWrite();

외부 폰트 사용

UseExternalFont 예제는 사용자 정의 Adafruit GFX 호환 폰트를 사용하여 화면 텍스트를 렌더링합니다.

/* * 이 아두이노 코드는 newbiely.kr 에서 개발되었습니다 * 이 아두이노 코드는 어떠한 제한 없이 공개 사용을 위해 제공됩니다. * 상세한 지침 및 연결도에 대해서는 다음을 방문하세요: * https://newbiely.kr/tutorials/arduino/arduino-tft-lcd-touch-display-spi */ /* Created by DIYables This example code is in the public domain Product page: https://diyables.io */ // ============================================= // Single include brings in the base class plus all driver classes. // ============================================= #include <DIYables_TFT_SPI.h> #include <Fonts/FreeSansBold12pt7b.h> // ============================================= // Wiring (Arduino Uno / Nano) // --------------------------------------------- // TFT module Arduino Uno / Nano // ------------ --------------------------------- // VCC -> 5V // GND -> GND // CS -> D10 (TFT_CS_PIN) // RESET -> D8 (TFT_RST_PIN) // DC / RS -> D9 (TFT_DC_PIN) // SDI / MOSI -> D11 (hardware SPI MOSI) // SCK -> D13 (hardware SPI SCK) // LED -> 3.3V (or any GPIO via initBacklight) // SDO / MISO -> D12 (only needed when reading from display) // ============================================= // ============================================= // SPI pin definitions (adjust for your board) // ============================================= #define TFT_CS_PIN 10 #define TFT_DC_PIN 9 #define TFT_RST_PIN 8 // Panel resolution in native (portrait) orientation - change to match your module #define TFT_WIDTH 240 #define TFT_HEIGHT 320 // ============================================= // Create display object (uncomment matching driver) // ============================================= // DIYables_ILI9341_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); // DIYables_ILI9488_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); DIYables_ST7789_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); #define MAGENTA DIYables_TFT_SPI::colorRGB(255, 0, 255) #define WHITE DIYables_TFT_SPI::colorRGB(255, 255, 255) void setup() { Serial.begin(9600); Serial.println(F("TFT SPI Display - Use external font")); TFT_display.begin(); TFT_display.setFont(&FreeSansBold12pt7b); TFT_display.setRotation(1); // Landscape TFT_display.fillScreen(WHITE); TFT_display.setTextColor(MAGENTA); TFT_display.setTextSize(1); float temperature = 23.5; float humidity = 78.6; TFT_display.setCursor(20, 30); TFT_display.print("Temperature: "); TFT_display.print(temperature, 1); TFT_display.print(char(247)); TFT_display.println("C"); TFT_display.setCursor(20, 70); TFT_display.print("Humidity: "); TFT_display.print(humidity, 1); TFT_display.print("%"); } void loop() { }

실행 방법

  • 배선도에 표시된 대로 TFT 모듈을 Arduino에 연결합니다.
  • USB 케이블을 연결합니다.
  • Arduino IDE에서 코드를 붙여넣고, 보드와 포트를 확인하고, Upload를 누릅니다.

메서드 빠른 레퍼런스

메서드 설명 사용 예
setFont(&FontName) 사용자 정의 GFX 호환 폰트를 활성화합니다. NULL을 전달하면 내장 5×7 폰트로 복원됩니다. TFT_display.setFont(&FreeSans12pt7b);
setCursor(x, y) 텍스트 커서를 지정된 위치로 이동합니다. TFT_display.setCursor(10, 40);
setTextColor(color) 텍스트 전경 색상을 설정합니다. TFT_display.setTextColor(WHITE);
print(text) 현재 커서 위치에 문자열을 출력합니다. TFT_display.print("Hello!");

터치 포인트 가져오기

TouchGetPoint 예제는 XPT2046 터치 컨트롤러에서 원시 ADC 좌표를 읽어 시리얼 모니터에 출력합니다.

배선: T_CLK→D13, T_DIN→D11, T_DO→D12(디스플레이와 SPI 버스 공유). T_CS→D7, T_IRQ→D6.

/* * 이 아두이노 코드는 newbiely.kr 에서 개발되었습니다 * 이 아두이노 코드는 어떠한 제한 없이 공개 사용을 위해 제공됩니다. * 상세한 지침 및 연결도에 대해서는 다음을 방문하세요: * https://newbiely.kr/tutorials/arduino/arduino-tft-lcd-touch-display-spi */ /* Touch Get Point Example ----------------------- This example demonstrates how to read and display touch coordinates using a DIYables SPI TFT display with a 4-wire resistive touch panel. When you touch the screen, the sketch prints the mapped (screen) X and Y coordinates to the Serial Monitor and draws a red dot at the touched location. NOTE: Run the TouchCalibration example first and paste the calibration values into setTouchCalibration() below if the touch coordinates are inaccurate. Created by DIYables This example code is in the public domain Product page: https://diyables.io */ // ============================================= // Single include brings in the base class plus all driver classes. // ============================================= #include <DIYables_TFT_SPI.h> // ============================================= // Wiring (Arduino Uno / Nano) // ============================================= // TFT pins (always required) // TFT module Arduino Uno / Nano // ------------ --------------------------------- // VCC -> 5V // GND -> GND // CS -> D10 (TFT_CS_PIN) // RESET -> D8 (TFT_RST_PIN) // DC / RS -> D9 (TFT_DC_PIN) // SDI / MOSI -> D11 (hardware SPI MOSI) // SCK -> D13 (hardware SPI SCK) // SDO / MISO -> D12 (only needed when reading from display) // LED -> 3.3V (or any GPIO via initBacklight) // // XPT2046 / HR2046 / ADS7843 SPI touch controller // (modules with pins: T_CS, T_CLK, T_DIN, T_DO, T_IRQ) // Touch pin Arduino Uno / Nano // ------------ --------------------------------- // T_CS -> D7 (TOUCH_CS_PIN) // T_IRQ -> D2 (TOUCH_IRQ_PIN, optional - use -1 to skip) // T_CLK -> D13 (shared with display SCK) // T_DIN -> D11 (shared with display MOSI) // T_DO -> D12 (shared with display MISO) // ============================================= // ============================================= // SPI pin definitions (adjust for your board) // ============================================= #define TFT_CS_PIN 10 #define TFT_DC_PIN 9 #define TFT_RST_PIN 8 // Panel resolution in native (portrait) orientation - change to match your module #define TFT_WIDTH 240 #define TFT_HEIGHT 320 // MOSI and SCK use default hardware SPI pins // ============================================= // Touch pin definitions (XPT2046 / HR2046 SPI touch controller) // ============================================= #define TOUCH_CS_PIN 7 // T_CS (any GPIO) #define TOUCH_IRQ_PIN -1 // T_IRQ (any GPIO, or -1 if not connected) // ============================================= // ============================================= // Calibration values. // Run the TouchCalibration example and update these if touch is inaccurate. // Typical raw ranges: // - XPT2046 / HR2046 : ~200..3900 (default below) // - 4-wire resistive : ~100..900 // ============================================= #define TOUCH_LEFT_X 300 #define TOUCH_RIGHT_X 3700 #define TOUCH_TOP_Y 300 #define TOUCH_BOT_Y 3700 // ============================================= // Create display object (uncomment matching driver) // ============================================= // DIYables_ILI9341_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); // DIYables_ILI9488_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); DIYables_ST7789_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); #define RED DIYables_TFT_SPI::colorRGB(255, 0, 0) #define WHITE DIYables_TFT_SPI::colorRGB(255, 255, 255) void setup() { Serial.begin(9600); TFT_display.begin(); TFT_display.setRotation(0); TFT_display.fillScreen(WHITE); TFT_display.initTouchSPI(TOUCH_CS_PIN, TOUCH_IRQ_PIN); // If touch X is mirrored on your board, uncomment: //TFT_display.setTouchInvertX(true); // If touch Y is mirrored on your board, uncomment: //TFT_display.setTouchInvertY(false); TFT_display.setTouchCalibration(TOUCH_LEFT_X, TOUCH_RIGHT_X, TOUCH_TOP_Y, TOUCH_BOT_Y); Serial.println("Touch the screen to see coordinates."); } void loop() { int x, y; if (TFT_display.getTouch(x, y)) { Serial.print("Touch at: "); Serial.print(x); Serial.print(", "); Serial.println(y); TFT_display.fillCircle(x, y, 4, RED); delay(200); } }

실행 방법

  • XPT2046 컨트롤러를 Arduino에 연결하고 디스플레이와 SPI 버스를 공유합니다.
  • USB 케이블을 연결합니다.
  • 코드를 붙여넣고, 보드와 포트를 확인하고, Upload를 누릅니다.
  • 시리얼 모니터를 9600 보드레이트로 엽니다.

메서드 빠른 레퍼런스

메서드 설명 사용 예
initTouchSPI(cs, irq) 공유 SPI 버스에서 XPT2046을 초기화합니다. TFT_display.initTouchSPI(7, 6);
readTouchRaw(x, y, z) 보정 없이 원시 ADC 터치 값을 반환합니다. TFT_display.readTouchRaw(x, y, z);

터치 그리기

TouchDraw 예제는 간단한 손가락 그리기 애플리케이션을 만듭니다.

/* * 이 아두이노 코드는 newbiely.kr 에서 개발되었습니다 * 이 아두이노 코드는 어떠한 제한 없이 공개 사용을 위해 제공됩니다. * 상세한 지침 및 연결도에 대해서는 다음을 방문하세요: * https://newbiely.kr/tutorials/arduino/arduino-tft-lcd-touch-display-spi */ /* Touch Draw Lines Example ------------------------- Draws lines on the screen following the pen. - Touch and drag on the screen to draw. - Lift the pen to stop drawing. - Touch again to start a new line from the last point. NOTE: Run the TouchCalibration example and update setTouchCalibration() below if the touch coordinates are inaccurate. Created by DIYables This example code is in the public domain Product page: https://diyables.io */ // ============================================= // Single include brings in the base class plus all driver classes. // ============================================= #include <DIYables_TFT_SPI.h> // ============================================= // Wiring (Arduino Uno / Nano) // ============================================= // TFT pins (always required) // TFT module Arduino Uno / Nano // ------------ --------------------------------- // VCC -> 5V // GND -> GND // CS -> D10 (TFT_CS_PIN) // RESET -> D8 (TFT_RST_PIN) // DC / RS -> D9 (TFT_DC_PIN) // SDI / MOSI -> D11 (hardware SPI MOSI) // SCK -> D13 (hardware SPI SCK) // SDO / MISO -> D12 (only needed when reading from display) // LED -> 3.3V (or any GPIO via initBacklight) // // XPT2046 / HR2046 / ADS7843 SPI touch controller // (modules with pins: T_CS, T_CLK, T_DIN, T_DO, T_IRQ) // Touch pin Arduino Uno / Nano // ------------ --------------------------------- // T_CS -> D7 (TOUCH_CS_PIN) // T_IRQ -> D2 (TOUCH_IRQ_PIN, optional - use -1 to skip) // T_CLK -> D13 (shared with display SCK) // T_DIN -> D11 (shared with display MOSI) // T_DO -> D12 (shared with display MISO) // ============================================= // ============================================= // SPI pin definitions (adjust for your board) // ============================================= #define TFT_CS_PIN 10 #define TFT_DC_PIN 9 #define TFT_RST_PIN 8 // Panel resolution in native (portrait) orientation - change to match your module #define TFT_WIDTH 240 #define TFT_HEIGHT 320 // ============================================= // Touch pin definitions (XPT2046 / HR2046 SPI touch controller) // ============================================= #define TOUCH_CS_PIN 7 // T_CS (any GPIO) #define TOUCH_IRQ_PIN -1 // T_IRQ (any GPIO, or -1 if not connected) // ============================================= // ============================================= // Calibration values. // Run the TouchCalibration example and update these if touch is inaccurate. // Typical raw ranges: // - XPT2046 / HR2046 : ~200..3900 (default below) // - 4-wire resistive : ~100..900 // ============================================= #define TOUCH_LEFT_X 300 #define TOUCH_RIGHT_X 3700 #define TOUCH_TOP_Y 300 #define TOUCH_BOT_Y 3700 // ============================================= // Create display object (uncomment matching driver) // ============================================= // DIYables_ILI9341_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); // DIYables_ILI9488_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); DIYables_ST7789_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); #define RED DIYables_TFT_SPI::colorRGB(255, 0, 0) #define WHITE DIYables_TFT_SPI::colorRGB(255, 255, 255) #define PEN_RADIUS 3 void setup() { TFT_display.begin(); TFT_display.setRotation(0); TFT_display.fillScreen(WHITE); TFT_display.initTouchSPI(TOUCH_CS_PIN, TOUCH_IRQ_PIN); // If touch X is mirrored on your board, uncomment: //TFT_display.setTouchInvertX(true); // If touch Y is mirrored on your board, uncomment: //TFT_display.setTouchInvertY(false); TFT_display.setTouchCalibration(TOUCH_LEFT_X, TOUCH_RIGHT_X, TOUCH_TOP_Y, TOUCH_BOT_Y); } void loop() { int x, y; if (TFT_display.getTouch(x, y)) { TFT_display.fillCircle(x, y, PEN_RADIUS, RED); } }

실행 방법

  • XPT2046을 Arduino에 연결합니다.
  • USB 케이블을 연결합니다.
  • 코드를 붙여넣고, 보드와 포트를 확인하고, Upload를 누릅니다.
  • 디스플레이를 손가락으로 드래그하여 화면에 그립니다.

메서드 빠른 레퍼런스

메서드 설명 사용 예
initTouchSPI(cs, irq) 공유 SPI 버스에서 XPT2046을 설정합니다. TFT_display.initTouchSPI(7, 6);
setTouchCalibration(minX,maxX,minY,maxY) 원시 ADC 값을 화면 픽셀 좌표로 매핑합니다. TFT_display.setTouchCalibration(200, 3800, 300, 3700);
setTouchInvertX(invert) / setTouchInvertY(invert) 터치 축을 반전합니다. setTouchCalibration() 전에 호출합니다. TFT_display.setTouchInvertY(true);
getTouch(x, y) 보정된 터치 좌표를 가져옵니다. if (TFT_display.getTouch(x, y)) { ... }
fillCircle(x, y, r, color) 터치 지점에 작은 점을 그립니다. TFT_display.fillCircle(x, y, 3, RED);

터치 버튼

TouchButton 예제는 화면에 직사각형 버튼을 그리고 터치 좌표를 확인합니다.

/* * 이 아두이노 코드는 newbiely.kr 에서 개발되었습니다 * 이 아두이노 코드는 어떠한 제한 없이 공개 사용을 위해 제공됩니다. * 상세한 지침 및 연결도에 대해서는 다음을 방문하세요: * https://newbiely.kr/tutorials/arduino/arduino-tft-lcd-touch-display-spi */ /* Touch Button Press/Release Example ------------------------------------ This example shows how to detect press and release events on a rectangular button using a DIYables SPI TFT display with a 4-wire resistive touch panel. When you touch inside the button, it changes colour and shows "PRESSED". When you release, it returns to its original state. NOTE: Run the TouchCalibration example and update setTouchCalibration() below if the touch coordinates are inaccurate. Created by DIYables This example code is in the public domain Product page: https://diyables.io */ // ============================================= // Single include brings in the base class plus all driver classes. // ============================================= #include <DIYables_TFT_SPI.h> // ============================================= // Wiring (Arduino Uno / Nano) // ============================================= // TFT pins (always required) // TFT module Arduino Uno / Nano // ------------ --------------------------------- // VCC -> 5V // GND -> GND // CS -> D10 (TFT_CS_PIN) // RESET -> D8 (TFT_RST_PIN) // DC / RS -> D9 (TFT_DC_PIN) // SDI / MOSI -> D11 (hardware SPI MOSI) // SCK -> D13 (hardware SPI SCK) // SDO / MISO -> D12 (only needed when reading from display) // LED -> 3.3V (or any GPIO via initBacklight) // // XPT2046 / HR2046 / ADS7843 SPI touch controller // (modules with pins: T_CS, T_CLK, T_DIN, T_DO, T_IRQ) // Touch pin Arduino Uno / Nano // ------------ --------------------------------- // T_CS -> D7 (TOUCH_CS_PIN) // T_IRQ -> D2 (TOUCH_IRQ_PIN, optional - use -1 to skip) // T_CLK -> D13 (shared with display SCK) // T_DIN -> D11 (shared with display MOSI) // T_DO -> D12 (shared with display MISO) // ============================================= // ============================================= // SPI pin definitions (adjust for your board) // ============================================= #define TFT_CS_PIN 10 #define TFT_DC_PIN 9 #define TFT_RST_PIN 8 // Panel resolution in native (portrait) orientation - change to match your module #define TFT_WIDTH 240 #define TFT_HEIGHT 320 // ============================================= // Touch pin definitions (XPT2046 / HR2046 SPI touch controller) // ============================================= #define TOUCH_CS_PIN 7 // T_CS (any GPIO) #define TOUCH_IRQ_PIN -1 // T_IRQ (any GPIO, or -1 if not connected) // ============================================= // ============================================= // Calibration values. // Run the TouchCalibration example and update these if touch is inaccurate. // Typical raw ranges: // - XPT2046 / HR2046 : ~200..3900 (default below) // - 4-wire resistive : ~100..900 // ============================================= #define TOUCH_LEFT_X 300 #define TOUCH_RIGHT_X 3700 #define TOUCH_TOP_Y 300 #define TOUCH_BOT_Y 3700 // ============================================= // Create display object (uncomment matching driver) // ============================================= // DIYables_ILI9341_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); // DIYables_ILI9488_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); DIYables_ST7789_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); #define BLACK DIYables_TFT_SPI::colorRGB( 0, 0, 0) #define WHITE DIYables_TFT_SPI::colorRGB(255, 255, 255) #define GRAY DIYables_TFT_SPI::colorRGB(128, 128, 128) #define RED DIYables_TFT_SPI::colorRGB(255, 0, 0) #define BUTTON_X 30 #define BUTTON_Y 100 #define BUTTON_W 180 #define BUTTON_H 60 #define DEBOUNCE_DELAY 50 bool lastPressed = false; bool stablePressed = false; unsigned long lastDebounceTime = 0; void drawButton(bool pressed) { uint16_t bg = pressed ? GRAY : RED; TFT_display.fillRect(BUTTON_X, BUTTON_Y, BUTTON_W, BUTTON_H, bg); TFT_display.drawRect(BUTTON_X, BUTTON_Y, BUTTON_W, BUTTON_H, BLACK); TFT_display.setTextColor(WHITE, bg); TFT_display.setTextSize(3); TFT_display.setCursor(BUTTON_X + 10, BUTTON_Y + 16); TFT_display.print(pressed ? "PRESSED" : " PRESS "); } void setup() { Serial.begin(9600); TFT_display.begin(); TFT_display.setRotation(0); TFT_display.fillScreen(WHITE); TFT_display.initTouchSPI(TOUCH_CS_PIN, TOUCH_IRQ_PIN); // If touch X is mirrored on your board, uncomment: //TFT_display.setTouchInvertX(true); // If touch Y is mirrored on your board, uncomment: //TFT_display.setTouchInvertY(false); TFT_display.setTouchCalibration(TOUCH_LEFT_X, TOUCH_RIGHT_X, TOUCH_TOP_Y, TOUCH_BOT_Y); drawButton(false); } void loop() { int x, y; bool pressed = false; if (TFT_display.getTouch(x, y)) { if (x >= BUTTON_X && x < (BUTTON_X + BUTTON_W) && y >= BUTTON_Y && y < (BUTTON_Y + BUTTON_H)) { pressed = true; } } if (pressed != lastPressed) { lastDebounceTime = millis(); } lastPressed = pressed; if ((millis() - lastDebounceTime) > DEBOUNCE_DELAY) { if (pressed != stablePressed) { stablePressed = pressed; drawButton(stablePressed); Serial.println(stablePressed ? "Button PRESSED" : "Button RELEASED"); } } }

실행 방법

  • T_CS를 D7에 연결합니다. T_IRQ는 선택 사항입니다.
  • USB 케이블을 연결합니다.
  • 코드를 붙여넣고, 보드와 포트를 확인하고, Upload를 누릅니다.
  • 화면에 표시된 버튼을 탭합니다.

메서드 빠른 레퍼런스

메서드 설명 사용 예
initTouchSPI(cs, irq) XPT2046을 초기화합니다. TFT_display.initTouchSPI(7, -1);
setTouchCalibration(minX,maxX,minY,maxY) 보정을 적용합니다. TFT_display.setTouchCalibration(200, 3800, 300, 3700);
getTouch(x, y) 현재 보정된 터치 위치를 가져옵니다. if (TFT_display.getTouch(x, y)) { ... }
fillRect(x, y, w, h, color) 버튼 배경을 위한 단색 사각형을 그립니다. TFT_display.fillRect(10, 10, 120, 60, BLUE);

터치 보정

TouchCalibration 예제는 XPT2046 터치 패널의 원시 ADC 범위를 측정하는 방법을 안내합니다.

/* * 이 아두이노 코드는 newbiely.kr 에서 개발되었습니다 * 이 아두이노 코드는 어떠한 제한 없이 공개 사용을 위해 제공됩니다. * 상세한 지침 및 연결도에 대해서는 다음을 방문하세요: * https://newbiely.kr/tutorials/arduino/arduino-tft-lcd-touch-display-spi */ /* Touch Screen Calibration Example --------------------------------- This example measures the raw touch coordinates at all four screen corners and prints ready-to-use calibration values to the Serial Monitor. It uses readTouchRaw() directly — it does NOT rely on getTouch() or any existing calibration values, so it works even when touch is completely broken. INSTRUCTIONS: 1. Upload this sketch to your board. 2. Open the Serial Monitor (Ctrl+Shift+M) and set baud rate to 9600. 3. The screen shows a blinking red dot in each corner, numbered 1–4: 1 = Top-left 2 = Top-right 3 = Bottom-right 4 = Bottom-left 4. Press and HOLD firmly on the blinking dot. Keep holding until the Serial Monitor prints "Captured!" for that corner. 5. Release, then wait for the next dot to appear and repeat. 6. After all 4 corners, the Serial Monitor prints the calibration values and a ready-to-use setTouchCalibration() call. Copy it into your sketch. NOTE: While waiting, the Serial Monitor continuously prints the live raw Z/X/Y readings so you can confirm that touch is being detected. Created by DIYables This example code is in the public domain Product page: https://diyables.io */ // ============================================= // Single include brings in the base class plus all driver classes. // ============================================= #include <DIYables_TFT_SPI.h> // ============================================= // Wiring (Arduino Uno / Nano) // ============================================= // TFT pins (always required) // TFT module Arduino Uno / Nano // ------------ --------------------------------- // VCC -> 5V // GND -> GND // CS -> D10 (TFT_CS_PIN) // RESET -> D8 (TFT_RST_PIN) // DC / RS -> D9 (TFT_DC_PIN) // SDI / MOSI -> D11 (hardware SPI MOSI) // SCK -> D13 (hardware SPI SCK) // SDO / MISO -> D12 (only needed when reading from display) // LED -> 3.3V (or any GPIO via initBacklight) // // XPT2046 / HR2046 / ADS7843 SPI touch controller // (modules with pins: T_CS, T_CLK, T_DIN, T_DO, T_IRQ) // Touch pin Arduino Uno / Nano // ------------ --------------------------------- // T_CS -> D7 (TOUCH_CS_PIN) // T_IRQ -> D2 (TOUCH_IRQ_PIN, optional - use -1 to skip) // T_CLK -> D13 (shared with display SCK) // T_DIN -> D11 (shared with display MOSI) // T_DO -> D12 (shared with display MISO) // ============================================= // ============================================= // SPI pin definitions (adjust for your board) // ============================================= #define TFT_CS_PIN 10 #define TFT_DC_PIN 9 #define TFT_RST_PIN 8 // Panel resolution in native (portrait) orientation - change to match your module #define TFT_WIDTH 240 #define TFT_HEIGHT 320 // ============================================= // Touch pin definitions (XPT2046 / HR2046 SPI touch controller) // ============================================= #define TOUCH_CS_PIN 7 // T_CS (any GPIO) #define TOUCH_IRQ_PIN -1 // T_IRQ (any GPIO, or -1 if not connected) // ============================================= // ============================================= // Create display object (uncomment matching driver) // ============================================= // DIYables_ILI9341_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); // DIYables_ILI9488_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); DIYables_ST7789_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN); // Minimum pressure to count as a valid touch. #define TOUCH_Z_MIN 10 // How many consecutive valid samples required before a corner is accepted. #define SAMPLES_NEEDED 10 // Delay between samples (ms). #define SAMPLE_DELAY_MS 30 #define DOT_RADIUS 12 #define BLACK DIYables_TFT_SPI::colorRGB( 0, 0, 0) #define WHITE DIYables_TFT_SPI::colorRGB(255, 255, 255) #define RED DIYables_TFT_SPI::colorRGB(255, 0, 0) // Corner pixel positions — filled in setup() once display size is known. // Order: 0=top-left, 1=top-right, 2=bottom-right, 3=bottom-left int cx[4], cy[4]; // Captured averaged raw values per corner. int cap_x[4], cap_y[4]; // ----------------------------------------------------------------------- void drawDot(int corner, bool on) { uint16_t color = on ? RED : WHITE; TFT_display.fillCircle(cx[corner], cy[corner], DOT_RADIUS, color); TFT_display.setTextSize(2); TFT_display.setTextColor(BLACK, color); TFT_display.setCursor(cx[corner] - 6, cy[corner] - 8); TFT_display.print(corner + 1); } void captureCorner(int corner) { const char* names[] = { "Top-left", "Top-right", "Bottom-right", "Bottom-left" }; Serial.println(); Serial.print("Corner "); Serial.print(corner + 1); Serial.print(" ("); Serial.print(names[corner]); Serial.println(")"); Serial.println(" Press and HOLD firmly on the blinking dot."); Serial.println(" Keep holding until you see 'Captured!'"); unsigned long lastBlink = 0; unsigned long lastPrint = 0; bool dotOn = false; int goodSamples = 0; long sumX = 0, sumY = 0; while (true) { // Blink the dot if (millis() - lastBlink > 400) { lastBlink = millis(); dotOn = !dotOn; drawDot(corner, dotOn); } int raw_x, raw_y, z; TFT_display.readTouchRaw(raw_x, raw_y, z); // Print live readings every 500 ms if (millis() - lastPrint > 500) { lastPrint = millis(); Serial.print(" Z="); Serial.print(z); Serial.print(" X="); Serial.print(raw_x); Serial.print(" Y="); Serial.println(raw_y); } if (z >= TOUCH_Z_MIN) { sumX += raw_x; sumY += raw_y; goodSamples++; if (goodSamples >= SAMPLES_NEEDED) { cap_x[corner] = sumX / goodSamples; cap_y[corner] = sumY / goodSamples; Serial.print(" Captured! raw_x="); Serial.print(cap_x[corner]); Serial.print(" raw_y="); Serial.println(cap_y[corner]); drawDot(corner, false); delay(500); return; } } else { goodSamples = 0; sumX = 0; sumY = 0; } delay(SAMPLE_DELAY_MS); } } // ----------------------------------------------------------------------- void setup() { Serial.begin(9600); TFT_display.begin(); TFT_display.setRotation(0); // Always calibrate in rotation 0 TFT_display.fillScreen(WHITE); TFT_display.initTouchSPI(TOUCH_CS_PIN, TOUCH_IRQ_PIN); // If touch X is mirrored on your board, uncomment the line below // BEFORE calibrating (so the printed values match your panel): //TFT_display.setTouchInvertX(true); // If touch Y is mirrored on your board, uncomment: //TFT_display.setTouchInvertY(false); int w = TFT_display.width(); int h = TFT_display.height(); int m = DOT_RADIUS + 4; cx[0] = m; cy[0] = m; cx[1] = w - m; cy[1] = m; cx[2] = w - m; cy[2] = h - m; cx[3] = m; cy[3] = h - m; Serial.println("=== Touch Calibration ==="); for (int i = 0; i < 4; i++) { captureCorner(i); } // Derive calibration values from the four corners int min_x = (cap_x[0] + cap_x[3]) / 2; // left edge int max_x = (cap_x[1] + cap_x[2]) / 2; // right edge int min_y = (cap_y[0] + cap_y[1]) / 2; // top edge int max_y = (cap_y[2] + cap_y[3]) / 2; // bottom edge Serial.println(); Serial.println("=== Calibration Results ==="); Serial.print(" Left X (min_x): "); Serial.println(min_x); Serial.print(" Right X (max_x): "); Serial.println(max_x); Serial.print(" Top Y (min_y): "); Serial.println(min_y); Serial.print(" Bot Y (max_y): "); Serial.println(max_y); Serial.println(); Serial.println("Copy this line into your sketch:"); Serial.print(" TFT_display.setTouchCalibration("); Serial.print(min_x); Serial.print(", "); Serial.print(max_x); Serial.print(", "); Serial.print(min_y); Serial.print(", "); Serial.print(max_y); Serial.println(");"); TFT_display.fillScreen(WHITE); TFT_display.setTextColor(BLACK); TFT_display.setTextSize(2); TFT_display.setCursor(10, 10); TFT_display.println("Done! Check"); TFT_display.setCursor(10, 35); TFT_display.println("Serial Monitor"); } void loop() {}

실행 방법

  • XPT2046을 Arduino에 연결합니다.
  • USB 케이블을 연결합니다.
  • 코드를 붙여넣고, 보드와 포트를 확인하고, Upload를 누릅니다.
  • 시리얼 모니터를 9600 보드레이트로 엽니다. 화면의 각 모서리를 터치하라는 안내를 따릅니다.

메서드 빠른 레퍼런스

메서드 설명 사용 예
initTouchSPI(cs, irq) XPT2046 터치 컨트롤러를 초기화합니다. TFT_display.initTouchSPI(7, 6);
readTouchRaw(x, y, z) 보정 범위를 측정하기 위한 원시 ADC 값을 읽습니다. TFT_display.readTouchRaw(x, y, z);
setTouchCalibration(minX,maxX,minY,maxY) 보정 값을 저장합니다. TFT_display.setTouchCalibration(200, 3800, 300, 3700);
setTouchInvertX(invert) / setTouchInvertY(invert) 터치 축을 반전합니다. 보정 전에 호출합니다. TFT_display.setTouchInvertY(true);

사용자 정의 SPI

CustomSPI 예제는 디스플레이 생성자에 명시적 SPIClass 인스턴스를 제공하는 방법을 보여줍니다.

/* * 이 아두이노 코드는 newbiely.kr 에서 개발되었습니다 * 이 아두이노 코드는 어떠한 제한 없이 공개 사용을 위해 제공됩니다. * 상세한 지침 및 연결도에 대해서는 다음을 방문하세요: * https://newbiely.kr/tutorials/arduino/arduino-tft-lcd-touch-display-spi */ /* Created by DIYables This example code is in the public domain Product page: https://diyables.io This example demonstrates how to use a custom (non-default) SPI bus with the DIYables TFT SPI library. This is useful on boards that have multiple SPI interfaces, such as: - ESP32: HSPI / VSPI - Arduino Giga / Portenta: SPI1 - Raspberry Pi Pico: SPI1 */ // ============================================= // Single include brings in the base class plus all driver classes. // ============================================= #include <DIYables_TFT_SPI.h> // ============================================= // Wiring (Arduino Uno / Nano - default SPI bus) // --------------------------------------------- // NOTE: Uno / Nano have only ONE hardware SPI bus, so this example is // most useful on boards with multiple buses (ESP32, Giga, RP2040...). // On Uno / Nano, MY_SPI must remain &SPI and the wiring is the standard // hardware SPI mapping below. // // TFT module Arduino Uno / Nano // ------------ --------------------------------- // VCC -> 5V // GND -> GND // CS -> D10 (TFT_CS_PIN) // RESET -> D8 (TFT_RST_PIN) // DC / RS -> D9 (TFT_DC_PIN) // SDI / MOSI -> D11 (hardware SPI MOSI) // SCK -> D13 (hardware SPI SCK) // LED -> 3.3V (or any GPIO via initBacklight) // SDO / MISO -> D12 (only needed when reading from display) // ============================================= // ============================================= // SPI pin definitions (adjust for your board) // ============================================= #define TFT_CS_PIN 10 #define TFT_DC_PIN 9 #define TFT_RST_PIN 8 // Panel resolution in native (portrait) orientation - change to match your module #define TFT_WIDTH 240 #define TFT_HEIGHT 320 // ============================================= // Select alternate SPI bus (uncomment for your board) // ============================================= // --- ESP32: use HSPI --- // SPIClass hspi(HSPI); // #define MY_SPI &hspi // --- Arduino Giga / Portenta / RP2040: use SPI1 --- // #define MY_SPI &SPI1 // --- Default SPI (fallback) --- #define MY_SPI &SPI // ============================================= // Create display object with custom SPI bus // (uncomment matching driver) // ============================================= // DIYables_ILI9341_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN, MY_SPI); // DIYables_ILI9488_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN, MY_SPI); DIYables_ST7789_SPI TFT_display(TFT_WIDTH, TFT_HEIGHT, TFT_CS_PIN, TFT_DC_PIN, TFT_RST_PIN, MY_SPI); #define BLACK DIYables_TFT_SPI::colorRGB(0, 0, 0) #define WHITE DIYables_TFT_SPI::colorRGB(255, 255, 255) #define RED DIYables_TFT_SPI::colorRGB(255, 0, 0) #define GREEN DIYables_TFT_SPI::colorRGB(0, 255, 0) #define BLUE DIYables_TFT_SPI::colorRGB(0, 0, 255) void setup() { Serial.begin(9600); // For ESP32 HSPI: optionally remap pins before begin() // hspi.begin(14, 12, 13, -1); // SCK, MISO, MOSI, SS TFT_display.begin(); TFT_display.setRotation(1); // Landscape TFT_display.fillScreen(BLACK); uint16_t w = TFT_display.width(); uint16_t h = TFT_display.height(); // Draw a simple test pattern TFT_display.fillRect(0, 0, w / 3, h, RED); TFT_display.fillRect(w / 3, 0, w / 3, h, GREEN); TFT_display.fillRect(w * 2 / 3, 0, w / 3, h, BLUE); TFT_display.setTextColor(WHITE); TFT_display.setTextSize(2); TFT_display.setCursor(10, h / 2 - 10); TFT_display.print("Custom SPI bus OK"); } void loop() { // Nothing to do }

실행 방법

  • 배선도에 표시된 대로 TFT 디스플레이를 Arduino에 연결합니다.
  • USB 케이블을 연결합니다.
  • 코드를 붙여넣고, 보드와 포트를 확인하고, Upload를 누릅니다.

메서드 빠른 레퍼런스

메서드 설명 사용 예
DIYables_ILI9341_SPI(w,h,cs,dc,rst,spi) SPIClass 포인터를 받는 생성자 변형. DIYables_ILI9341_SPI tft(240, 320, 10, 9, 8, &SPI);
begin() 구성된 SPI 버스에서 디스플레이를 초기화합니다. TFT_display.begin();

문제 해결

  • 검은 화면 - CS, DC, MOSI, SCK가 모두 연결되어 있는지 확인합니다.
  • 잘못된 드라이버 - 생성자 라인 하나만 활성화되어야 합니다. 나머지는 주석 처리해야 합니다.
  • 이동되거나 잘린 이미지 - 생성자의 너비와 높이가 물리적 패널 크기와 일치해야 합니다.
  • 터치가 작동하지 않음 - TouchCalibration 예제를 실행하여 특정 패널에 맞는 보정 값을 얻습니다.

플랫폼 지원

이 라이브러리는 Arduino 표준 API(SPI, digitalWrite, millis)만 사용하며 모든 Arduino 호환 플랫폼에서 실행됩니다.