My arduino nano esp32 cant seem to stop freezing my ILI9488 screen with touch - XPT2046

My arduino keeps on detecting a press, yet I cant seem to get it to stop randomly freezing my screen!

Here is the code I use.

#include <SPI.h>

#include <TFT_eSPI.h>




TFT_eSPI tft = TFT_eSPI();




// Drawing States

uint16_t currentColor = TFT_WHITE;

int brushRadius = 4; 




// UI Layout Constraints

int canvasWidth;

int canvasHeight;

int paletteHeight = 40;

int sliderWidth = 50;

int blockWidth; // Made global so loop() can see it




// Hardware IRQ Pin (Nano D6 = Legacy GPIO 9)

#define TOUCH_IRQ 9




void setup() {

  Serial.begin(115200);

  

  // Set the IRQ pin as an input with an internal pull-up resistor

  pinMode(TOUCH_IRQ, INPUT_PULLUP);




  tft.init();

  tft.setRotation(1); 

  

  canvasWidth = tft.width() - sliderWidth;

  canvasHeight = tft.height() - paletteHeight;

  blockWidth = tft.width() / 5; // Split equally among 5 palette options




  // --- TOUCH CALIBRATION ---

  tft.fillScreen(TFT_BLACK);

  tft.setCursor(20, tft.height() / 2 - 10, 4);

  tft.setTextColor(TFT_WHITE, TFT_BLACK);

  tft.println("Tap the arrows to calibrate!");

  

  uint16_t calData[5];

  tft.calibrateTouch(calData, TFT_MAGENTA, TFT_BLACK, 15);

  tft.setTouch(calData); // <--- CRITICAL FIX: Applies the calibration data!

  

  // --- START THE ART APP ---

  tft.fillScreen(TFT_BLACK);

  drawPalette();

  drawSlider();

}




void loop() {

  // Check if physical IRQ indicates a touch event

  if (digitalRead(TOUCH_IRQ) == LOW) {

    

    uint16_t x, y;

    // Threshold (600) forces the library to ignore phantom/noisy touches

    bool pressed = tft.getTouch(&x, &y, 600); 




    if (pressed) {

      // 1. TOUCHING THE PALETTE ZONE (Bottom Bar)

      if (y > canvasHeight) {

        int selection = x / blockWidth; 

        

        switch(selection) {

          case 0: currentColor = TFT_RED; break;

          case 1: currentColor = TFT_GREEN; break;

          case 2: currentColor = TFT_BLUE; break;

          case 3: currentColor = TFT_YELLOW; break;

          case 4: currentColor = TFT_BLACK; break; // Eraser

        }

        delay(150); // Debounce UI selection

      } 

      // 2. TOUCHING THE SLIDER ZONE (Right Bar)

      else if (x > canvasWidth) {

        if (y < canvasHeight) {

          brushRadius = map(y, 20, canvasHeight - 20, 20, 1);

          brushRadius = constrain(brushRadius, 1, 20); 

          

          drawSlider(); 

          delay(50);     

        }

      }

      // 3. TOUCHING THE CANVAS ZONE (Drawing)

      else {

        if ((x - brushRadius > 0) && (x + brushRadius < canvasWidth) && 

            (y - brushRadius > 0) && (y + brushRadius < canvasHeight)) {

          

          tft.fillCircle(x, y, brushRadius, currentColor);

        }

      }

      

      // ---> CRITICAL FIX <---

      // Give the SPI bus and TFT controller 2 to 5 milliseconds to breathe.

      // This prevents the screen from desyncing and freezing.

      delay(3); 

    }

  }

}




void drawPalette() {

  tft.fillRect(0,              canvasHeight, blockWidth, paletteHeight, TFT_RED);

  tft.fillRect(blockWidth,     canvasHeight, blockWidth, paletteHeight, TFT_GREEN);

  tft.fillRect(blockWidth * 2, canvasHeight, blockWidth, paletteHeight, TFT_BLUE);

  tft.fillRect(blockWidth * 3, canvasHeight, blockWidth, paletteHeight, TFT_YELLOW);

  

  // Eraser Block

  tft.fillRect(blockWidth * 4, canvasHeight, tft.width() - (blockWidth * 4), paletteHeight, TFT_BLACK);

  tft.drawRect(blockWidth * 4, canvasHeight, tft.width() - (blockWidth * 4), paletteHeight, TFT_WHITE);

  tft.setTextColor(TFT_WHITE, TFT_BLACK);

  tft.setCursor(blockWidth * 4 + 10, canvasHeight + 12, 2);

  tft.print("ERASER");

}




void drawSlider() {

  tft.fillRect(canvasWidth, 0, sliderWidth, canvasHeight, TFT_NAVY);

  tft.drawRect(canvasWidth, 0, sliderWidth, canvasHeight, TFT_WHITE);

  

  // Fixed mapping layout to reflect top-heavy size increments

  int indicatorY = map(brushRadius, 20, 1, 20, canvasHeight - 20);

  indicatorY = constrain(indicatorY, 20, canvasHeight - 20);

  

  // Preview circle for brush size

  tft.fillCircle(canvasWidth + (sliderWidth / 2), indicatorY, brushRadius > 15 ? 15 : brushRadius, TFT_WHITE);

  

  tft.setTextColor(TFT_WHITE, TFT_NAVY);

  tft.setCursor(canvasWidth + 20, 5, 2);

  tft.print("+");

  tft.setCursor(canvasWidth + 22, canvasHeight - 20, 2);

  tft.print("-");

}

// See SetupX_Template.h for all options available
#define USER_SETUP_ID 21

#define ILI9488_DRIVER

//#define TFT_INVERSION_OFF

#define TFT_MISO 47 // (leave TFT SDO disconnected if other SPI devices share MISO)
#define TFT_MOSI 38
#define TFT_SCLK 48
#define TFT_CS 21 // select control pin
#define TFT_DC 17 //ta Command control pin
#define TFT_RST 18 //t pin (could connect to RST pin)
#define TOUCH_CS 10 //(legacy for d7 nano, makes the touch screen for XPT2046 work...)

#define LOAD_GLCD   // Font 1. Original Adafruit 8 pixel font needs ~1820 bytes in FLASH
#define LOAD_FONT2  // Font 2. Small 16 pixel high font, needs ~3534 bytes in FLASH, 96 characters
#define LOAD_FONT4  // Font 4. Medium 26 pixel high font, needs ~5848 bytes in FLASH, 96 characters
#define LOAD_FONT6  // Font 6. Large 48 pixel font, needs ~2666 bytes in FLASH, only characters 1234567890:-.apm
#define LOAD_FONT7  // Font 7. 7 segment 48 pixel font, needs ~2438 bytes in FLASH, only characters 1234567890:.
#define LOAD_FONT8  // Font 8. Large 75 pixel font needs ~3256 bytes in FLASH, only characters 1234567890:-.
#define LOAD_GFXFF  // FreeFonts. Include access to the 48 Adafruit_GFX free fonts FF1 to FF48 and custom fonts

#define SMOOTH_FONT

// #define SPI_FREQUENCY  20000000
#define SPI_FREQUENCY  27000000
// #define SPI_FREQUENCY  40000000
// #define SPI_FREQUENCY  80000000

// Optional reduced SPI frequency for reading TFT
#define SPI_READ_FREQUENCY  16000000

#define SPI_TOUCH_FREQUENCY  2500000

And yes, I'm on a breadboard. would solder fix this?

Do you connect this or disconnect?

This is dissconnected, yes

The line of code tells me you had it connected.

I haveit imputted just in case the library crashes out. Physically its not in.

Okay.

Are you certain your screen is ILI9488? From the purchase? Circuit card label?

This "Instructable" shows wiring for the Arduino and ILI9488. He states in the text that he had a struggle to get the wiring correct, so maybe this might help... How to Control Arduino Using a ILI9488 3.5" Touchscreen and a Simple GUI Library : 5 Steps (with Pictures) - Instructables

Probably the wiring is telling the code that a touch is happening all the time, slowing the code until it freezes.