This guide will help you build a touch-responsive drawing tool using an ESP32 and a 2.8" TFT touchscreen display. You'll learn how to set up the hardware, calibrate the touchscreen, and write the code to create a drawing application.
Parts Required:
- ESP32
- 2.8" TFT Touchscreen Display (or 2.4" with the ILI9341 driver)
- Male to Female Jumper Wires
- ESP32 Shield (optional but recommended for easier connections)
- Breadboard
Step 1: Setting Up the Hardware
-
Connect the TFT Display to the ESP32:
- MISO (T_DO): GPIO 12
- MOSI (T_DIN): GPIO 14
- SCLK (T_CLK): GPIO 25
- CS (T_CS): GPIO 21
- IRQ (T_IRQ): GPIO 17
- TFT_CS: GPIO 15
- TFT_DC: GPIO 2
- TFT_RST: GPIO 4 or to ESP32 RST (set to -1 in User_Setup.h if connected to ESP32 RST)
-
Use Breadboard and Jumper Wires:
- If using a breadboard, connect the ESP32 and TFT display with male to female jumper wires. Use an ESP32 shield (if available) for easier and more secure connections.
Step 2: Installing Libraries
-
TFT_eSPI Library:
- Install the TFT_eSPI library by Bodmer from the Arduino Library Manager or download it from its GitHub repository.
- This library requires configuration through the
User_Setup.h
file for your specific display and pin connections.
-
XPT2046_Touchscreen Library:
- Install the XPT2046_Touchscreen library by Paul Stoffregen from the Arduino Library Manager or download it from its GitHub repository.
Step 3: Configuring the User_Setup.h File
-
Download the User_Setup.h File:
- Download this
User_Setup.h
file
- Download this
-
Add User_Setup.h to the Arduino Library:
- Place the downloaded
User_Setup.h
file in the Arduino library folder. For example:
Documents > Arduino > libraries > TFT_eSPI > User_Setup.h
- Place the downloaded
Step 4: Calibrating the Touchscreen
-
Touchscreen Calibration:
- To ensure accurate touch detection, calibrate the touchscreen using raw touch values.
- Map the raw touch values to screen dimensions by adjusting the below values:
int x = map(p.x, 3900, 440, 0, SCREEN_WIDTH); int y = map(p.y, 3800, 440, 0, SCREEN_HEIGHT);
Step 5: Adding the Code
#include <TFT_eSPI.h> // Graphics and font library for ILI9341 driver chip #include <XPT2046_Touchscreen.h> // Touchscreen library for XPT2046 controller // Touchscreen pins #define XPT2046_IRQ 17 // T_IRQ #define XPT2046_MOSI 14 // T_DIN #define XPT2046_MISO 12 // T_OUT #define XPT2046_CLK 25 // T_CLK #define XPT2046_CS 21 // T_CS SPIClass touchscreenSPI = SPIClass(VSPI); XPT2046_Touchscreen touchscreen(XPT2046_CS, XPT2046_IRQ); #define SCREEN_WIDTH 320 #define SCREEN_HEIGHT 240 #define FONT_SIZE 2 #define CIRCLE_RADIUS 5 // Circle radius for drawing #define CLEAR_BUTTON_X 270 // X coordinate for the clear button #define CLEAR_BUTTON_Y 0 // Y coordinate for the clear button #define CLEAR_BUTTON_W 50 // Width of the clear button #define CLEAR_BUTTON_H 50 // Height of the clear button #define COLOR_BOX_SIZE 30 // Size of the color selection boxes #define NUM_COLORS 8 uint16_t colors[NUM_COLORS] = {TFT_RED, TFT_BLUE, TFT_GREEN, TFT_YELLOW, TFT_CYAN, TFT_MAGENTA, TFT_ORANGE, TFT_PURPLE}; uint16_t currentColor = TFT_GREEN; // Default drawing color TFT_eSPI tft = TFT_eSPI(); // Previous touch coordinates int lastX = -1, lastY = -1; void drawColorBoxes() { for (int i = 0; i < NUM_COLORS; i++) { tft.fillRect(i * COLOR_BOX_SIZE, 0, COLOR_BOX_SIZE, COLOR_BOX_SIZE, colors[i]); } } void setup() { Serial.begin(115200); // Start the SPI for the touchscreen and init the touchscreen touchscreenSPI.begin(XPT2046_CLK, XPT2046_MISO, XPT2046_MOSI, XPT2046_CS); touchscreen.begin(touchscreenSPI); touchscreen.setRotation(1); // Set the touchscreen rotation in landscape mode // Start the TFT display tft.init(); tft.setRotation(1); // Set the TFT display rotation in landscape mode // Clear the screen before writing to it tft.fillScreen(TFT_BLACK); tft.setTextColor(TFT_WHITE, TFT_BLACK); // Draw the clear button tft.fillRect(CLEAR_BUTTON_X, CLEAR_BUTTON_Y, CLEAR_BUTTON_W, CLEAR_BUTTON_H, TFT_RED); tft.setCursor(CLEAR_BUTTON_X + 10, CLEAR_BUTTON_Y + 15); tft.setTextColor(TFT_WHITE, TFT_RED); tft.setTextSize(1); tft.print("Clear"); // Draw the color selection boxes drawColorBoxes(); // Set X and Y coordinates for center of display int centerX = SCREEN_WIDTH / 2; int centerY = SCREEN_HEIGHT / 2; tft.setTextColor(TFT_WHITE, TFT_BLACK); tft.setTextSize(2); tft.drawCentreString("Touch Drawing App", centerX, centerY - 30, FONT_SIZE); tft.drawCentreString("Draw by touching!", centerX, centerY, FONT_SIZE); tft.drawCentreString("Tap red button to clear", centerX, centerY + 30, FONT_SIZE); } void loop() { // Checks if touchscreen was touched if (touchscreen.tirqTouched() && touchscreen.touched()) { // Get touchscreen points TS_Point p = touchscreen.getPoint(); // Calibrate touchscreen points to the correct width and height int x = map(p.x, 3900, 420, 0, SCREEN_WIDTH); int y = map(p.y, 3800, 440, 0, SCREEN_HEIGHT); int z = p.z; // Check if the clear button was pressed if (x >= CLEAR_BUTTON_X && x <= CLEAR_BUTTON_X + CLEAR_BUTTON_W && y >= CLEAR_BUTTON_Y && y <= CLEAR_BUTTON_Y + CLEAR_BUTTON_H) { // Clear the screen tft.fillScreen(TFT_BLACK); // Redraw the clear button tft.fillRect(CLEAR_BUTTON_X, CLEAR_BUTTON_Y, CLEAR_BUTTON_W, CLEAR_BUTTON_H, TFT_RED); tft.setCursor(CLEAR_BUTTON_X + 10, CLEAR_BUTTON_Y + 15); tft.setTextColor(TFT_WHITE, TFT_RED); tft.setTextSize(1); tft.print("Clear"); // Redraw the color selection boxes drawColorBoxes(); // Redraw the instructions int centerX = SCREEN_WIDTH / 2; int centerY = SCREEN_HEIGHT / 2; tft.setTextColor(TFT_WHITE, TFT_BLACK); tft.setTextSize(2); tft.drawCentreString("Touch Drawing App", centerX, centerY - 30, FONT_SIZE); tft.drawCentreString("Made by Zaitronics", centerX, centerY, FONT_SIZE); tft.drawCentreString("zaitronics.com.au", centerX, centerY + 30, FONT_SIZE); // Reset the last touch coordinates lastX = -1; lastY = -1; } else if (y < COLOR_BOX_SIZE) { // Check if a color box was pressed currentColor = colors[x / COLOR_BOX_SIZE]; } else { // Draw thicker circles for smoother drawing tft.fillCircle(x, y, CIRCLE_RADIUS, currentColor); // Update the last touch coordinates lastX = x; lastY = y; } // Print the touch coordinates to the Serial Monitor Serial.print("X = "); Serial.print(x); Serial.print(" | Y = "); Serial.print(y); Serial.print(" | Pressure = "); Serial.println(z); delay(10); // Reduced delay for faster updates } else { // Reset the last touch coordinates if the screen is not being touched lastX = -1; lastY = -1; } }
Libraries to Download:
- TFT_eSPI by Bodmer
- XPT2046_Touchscreen by Paul Stoffregen
By following these steps, you'll create a touch-responsive drawing tool using an ESP32 and a TFT touchscreen display. Enjoy your project and let your creativity flow!