Eliminating Flicker on 320x480 TFT Display Refresh

Hello,

I have a question regarding eliminating the flicker caused when a tft screen is refreshed. In my case, the screen displays a clock, and flickers with each second. I have tried to solve this issue myself with a solution I found here on the Adafruit forums, but could do with some help understanding the solution, and getting it to work with my sketch as I have been having some issues with that.

This thread gave me the hint “you may need to set up a fixed-size string and fill it with spaces each time before sprintf()ing into it…but this is an in-memory operation and would go very quickly, vs. accessing the display.”, but I was not sure how to implement that. Adafruit customer service forums • View topic - Improving 1.8 TFT SPI Speed?

This thread seemed to solve the issue via the same method “i wrote a small “Format” function to pad the data with spaces. That way the total digit amount is the same, so painting the background black works in all cases.” Adafruit customer service forums • View topic - Adafruit 3.5" TFT 320x480 display / flicker issues

I attempted to implement that solution myself, but get the error: “cannot convert ‘char*’ to ‘double’ for argument ‘1’ to ‘String Format(double, int, int)’”. I am someone may be able to help me better understand how to modify the solution to function with my sketch below. The ‘String Format’ function below is the solution from the above link.

void loop () {   
  DateTime now = rtc.now();
  
  tft.setTextColor(GREY);
  tft.setTextSize(2);
  tft.fillRect(10, 15, 140, 19, BLACK);
  tft.setCursor(10, 15);
  tft.print(daysOfTheWeek[now.dayOfTheWeek()]);
  sprintf(dateBuffer,"  %02u/%02u/%04u  %02u:%02u:%02u ",now.day(),now.month(),now.year(),now.hour(),now.minute(),now.second());
  tft.fillRect(225, 15, 250, 19, BLACK);
  tft.setCursor(225, 15);
  tft.print(Format(dateBuffer));
          
  delay(1000);  
}

String Format(double val, int dec, int dig ) {
  int addpad = 0;
  char sbuf[26]; // your call on the size
  String condata = dtostrf(val, dec, dig, sbuf);
  int slen = condata.length();
  for (addpad = 1; addpad <= dec + dig - slen; addpad++){
    condata = " " + condata;
  }
  return (condata);
}

It looks like you're rendering directly to the screen.

There are two ways to eliminate flicker:

  1. Set up a double buffer - but with the Arduino you don't have enough memory to do this

  2. Render completed sections or overwrite the entire screen

What's causing the flicker in your program is putting the black filled rectangle down and then putting the text over it.

If you could just render updated text every frame and have it cover up the previous text, that would look better.

What they're suggesting is that you use spaces to overwrite the previous displayed string rather than rendering a rectangle which is presumably slower.

It depends entirely on how spaces are rendered. If putting a space over a character makes the character disappear on the screen then that is what they are talking about.

What I ended up doing was so simple that I'm almost ashamed to admit it. It was my inexperience that made me take so long to find the solution. Instead of drawing a rectangle over the previous text or using spaces to overwrite previously displayed string, specifying a background colour for the text (via "tft.setTextColor(foreground, background);") entirely eliminated the flicker. Now I need to figure out how to set that background colour to whatever the colour of the screen is, as I have the screen changing colour every so often.

Thank you for the advice.