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.hfile 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.hfile 
 - Download this 
 - 
Add User_Setup.h to the Arduino Library:
- Place the downloaded 
User_Setup.hfile 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!