Nâng caoESP32 DevKitC V4TFTCảm ứngXPT2046SPI
Bảng vẽ cảm ứng trên TFT
Chạm vào màn hình TFT để vẽ; chọn màu ở hàng trên cùng. Đọc cảm ứng điện trở XPT2046 và đổi giá trị thô sang toạ độ điểm ảnh.
Linh kiện
- ESP32 DevKitC V4
- Màn hình TFT 2.8" ILI9341 (240×320)
Thư viện
Adafruit ILI9341, XPT2046_Touchscreen — được cài sẵn khi bạn mở dự án.
Thử ngay khi mô phỏng chạy
- Nhấn và kéo chuột trên màn hình khi mô phỏng đang chạy.
- Chạm vào một ô màu ở hàng trên để đổi màu bút.
- Chạm ô cuối cùng (X) để xoá bảng.
main.cpp
// Bảng vẽ: TFT ILI9341 (CS 5, DC 2, RST 4) và cảm ứng XPT2046 (T_CS 21) chung bus SPI#include <Adafruit_GFX.h>#include <Adafruit_ILI9341.h>#include <SPI.h>#include <XPT2046_Touchscreen.h> Adafruit_ILI9341 tft(5, 2, 4);XPT2046_Touchscreen touch(21); // Giá trị thô ở hai mép màn hình: mỗi tấm cảm ứng một khác, phải hiệu chỉnh.const int RAW_MIN = 300;const int RAW_MAX = 3800; const uint16_t COLORS[] = {ILI9341_RED, ILI9341_YELLOW, ILI9341_GREEN, ILI9341_CYAN, ILI9341_WHITE};const int COLOR_COUNT = 5;const int BOX = 40; // 5 ô màu + 1 ô xoá = 240 điểm ảnhuint16_t pen = ILI9341_YELLOW; void drawPalette() { for (int i = 0; i < COLOR_COUNT; i++) tft.fillRect(i * BOX, 0, BOX, BOX, COLORS[i]); tft.fillRect(COLOR_COUNT * BOX, 0, BOX, BOX, ILI9341_DARKGREY); tft.setTextColor(ILI9341_WHITE); tft.setTextSize(3); tft.setCursor(COLOR_COUNT * BOX + 12, 9); tft.print("X");} void clearBoard() { tft.fillRect(0, BOX, 240, 320 - BOX, ILI9341_BLACK);} void setup() { Serial.begin(115200); tft.begin(); touch.begin(); touch.setRotation(0); tft.fillScreen(ILI9341_BLACK); drawPalette(); Serial.println("San sang ve");} void loop() { if (!touch.touched()) { delay(10); // không chạm: nghỉ một chút thay vì hỏi cảm ứng liên tục return; } TS_Point p = touch.getPoint(); int x = constrain(map(p.x, RAW_MIN, RAW_MAX, 0, 239), 0, 239); int y = constrain(map(p.y, RAW_MIN, RAW_MAX, 0, 319), 0, 319); if (y < BOX) { int box = x / BOX; if (box < COLOR_COUNT) { pen = COLORS[box]; Serial.printf("Mau %d\n", box + 1); } else { clearBoard(); Serial.println("Xoa bang"); } delay(150); } else { tft.fillCircle(x, max(y, BOX + 3), 3, pen); }}