Well, I'd say line 14 of your posted code is at fault.
Here is a way to update a display that might be of use to you.
void fDoTheDisplayThing( void * parameter )
{
tft.init( 240, 320 ); // Init ST7789 320x240
tft.setRotation( 3 );
tft.setTextSize( 3 );
tft.fillScreen( ST77XX_BLACK );
tft.setTextWrap( false );
struct stu_eData px_eData;
const int brightness = 250;
ledcWrite( 4, brightness ); //backlight set
const int MaxString = 20;
String oldTempString = "";
String oldHumidityString = "";
String oldAQIString = "";
String oldRainfall = "";
String oldWindDirection = "";
String oldAirPressure = "";
String oldRMO = "";
String oldPM2 = "";
//String oldPower = "";
String oldC02 = "";
oldHumidityString.reserve( MaxString );
oldWindDirection.reserve( MaxString );
oldAirPressure.reserve( MaxString );
oldTempString.reserve( MaxString );
oldAQIString.reserve( MaxString );
oldRainfall.reserve( MaxString );
//oldPower.reserve( MaxString );
oldRMO.reserve( MaxString );
oldPM2.reserve( MaxString );
oldC02.reserve( MaxString );
bool Tick = true;
const int numOfColors = 40;
/* https://chrishewett.com/blog/true-rgb565-colour-picker/#:~:text=A%20true%20RGB565%20colour%20picker%2021st%20Oct%202017,in%205%20bits%20and%20green%20in%206%20bits. */
int colors[numOfColors] = { ST77XX_BLACK, ST77XX_RED, ST77XX_WHITE, ST77XX_BLUE, ST77XX_GREEN, ST77XX_CYAN, ST77XX_MAGENTA, ST77XX_YELLOW, 0xd55b, 0xee09,
0x2e15, 0xcb43, 0x6bad, 0x126f, 0x1264, 0xe264, 0xe7e4, 0x87e4, 0x87fe, 0x876a,
0xe304, 0x1cc4, 0xf4c4, 0xf4da, 0xcf66, 0xa879, 0x7f28, 0x4f37, 0xfa97, 0x6195,
0X8162, 0xc962, 0x517b, 0x325b, 0xea5b, 0x179b, 0xff80, 0xf960, 0x416d, 0x7bd1
};
int colorCounter = 1;
for (;;)
{
if ( xQueueReceive(xQ_eData, &px_eData, portMAX_DELAY) == pdTRUE )
{
tft.setCursor( 0, 0 );
tft.setTextColor( colors[0] );
tft.print( oldTempString );
tft.setCursor( 0, 0 );
tft.setTextColor( colors[colorCounter] );
oldTempString = "";
if ( Tick )
{
oldTempString.concat( "iTemp " + String(px_eData.Temperature) + "F" );
} else {
oldTempString.concat( "Wind Chill " + String(px_eData.WindChill) + "F" );
}
tft.println( oldTempString );
tft.setCursor( 0, 30 );
tft.setTextColor( colors[0] );
tft.print( oldHumidityString );
tft.setCursor( 0, 30 );
tft.setTextColor( colors[colorCounter] );
oldHumidityString = "";
if ( Tick )
{
oldHumidityString.concat( "iHum " + String(px_eData.Humidity) + "%" );
} else {
if ( (px_eData.SunRiseHr < 10) & (px_eData.SunRiseMin < 10) )
{
oldHumidityString.concat( "sRise 0" + String(px_eData.SunRiseHr) + "0" + String(px_eData.SunRiseMin) );
}
if ( (px_eData.SunRiseHr >= 10) & (px_eData.SunRiseMin < 10) )
{
oldHumidityString.concat( "sRise " + String(px_eData.SunRiseHr) + "0" + String(px_eData.SunRiseMin) );
}
if ( (px_eData.SunRiseHr < 10) & (px_eData.SunRiseMin >= 10) )
{
oldHumidityString.concat( "sRise 0" + String(px_eData.SunRiseHr) + String(px_eData.SunRiseMin) );
}
if ( (px_eData.SunRiseHr >= 10) & (px_eData.SunRiseMin >= 10) )
{
oldHumidityString.concat( "sRise " + String(px_eData.SunRiseHr) + String(px_eData.SunRiseMin) );
}
}
tft.println( oldHumidityString );
tft.setCursor( 0, 60 );
tft.setTextColor( colors[0] );
tft.print( oldAirPressure );
tft.setCursor( 0, 60 );
tft.setTextColor( colors[colorCounter] );
oldAirPressure = "";
if ( Tick )
{
//oldAirPressure.concat( "Pres " + String(px_eData.Pressure) + "mmHg" );
oldAirPressure.concat( "Dew Pt. " + String(px_eData.DewPoint) + "F" );
} else {
if ( px_eData.SunSetMin < 10 )
{
oldAirPressure.concat( "sSet " + String(px_eData.SunSetHr) + "0" + String(px_eData.SunSetMin) );
}
if ( px_eData.SunRiseMin >= 10 )
{
oldAirPressure.concat( "sSet " + String(px_eData.SunSetHr) + String(px_eData.SunSetMin) );
}
}
tft.println( oldAirPressure );
tft.setCursor( 0, 90 );
tft.setTextColor( colors[0] );
tft.print( oldAQIString );
tft.setCursor( 0, 90 );
tft.setTextColor( colors[colorCounter] );
oldAQIString = "";
oldAQIString.concat( "iAQI " + String(px_eData.IAQ) + "%" );
tft.println( oldAQIString );
tft.setCursor( 0, 120 );
tft.setTextColor( colors[0] );
tft.print( oldRMO );
tft.setCursor( 0, 120 );
tft.setTextColor( colors[colorCounter] );
oldRMO = "";
//if ( Tick )
//{
oldRMO.concat( "iRM0 " + String(px_eData.RM0) + "%" );
//} else {
// oldRMO.concat( "iCO2 " + String(CO2) + "ppm" );
//}
tft.println( oldRMO );
tft.setCursor( 0, 150 );
tft.setTextColor( colors[0] );
tft.print( oldPM2 );
tft.setCursor( 0, 150 );
tft.setTextColor( colors[colorCounter] );
oldPM2 = "";
oldPM2.concat( "PM2 " + String(px_eData.PM2) + "ug/m3" );
tft.println( oldPM2 );
tft.setCursor( 0, 180 );
tft.setTextColor( colors[0] );
//tft.print( oldPower );
tft.print( oldC02 );
tft.setCursor( 0, 180 );
tft.setTextColor( colors[colorCounter] );
//oldPower = "";
oldC02 = "";
//oldPower.concat( String(px_eData.WSV) + " Volts" );
oldC02.concat( "iCO2 " + String(x_eData.CO2) + "ppm" );
//oldPower.concat( String(px_eData.WSV) + "V " + String(int(px_eData.WSC * 1000.0f)) + "mA " + String((int(px_eData.WSP * 1000.0f))) + "mW" );
//tft.println( oldPower );
tft.println( oldC02 );
colorCounter++;
if ( colorCounter > (numOfColors - 1) )
{
colorCounter = 1;
}
Tick = !Tick;
//log_i( " high watermark % d", uxTaskGetStackHighWaterMark( NULL ) );
} //if ( xQueueReceive(xQ_eData, &px_eData, portMAX_DELAY) == pdTRUE )
} //for (;;)
vTaskDelete( NULL );
} //void fDoTheDisplayTHing( void * parameter )
I store the previous value in variable. For an update.
tft.setTextColor( colors[0] );
tft.print( oldTempString );
I turn text color to black, write the old string to the location, which clears the display info when it becomes the background color, then set the text color to the color in use, then set the new text, saving it into the previous string variable.