For flicker prevention of TFT screen

I have used the following set. - Arduino UNO - TFT display (ST7735)

Screen, but I want to avoid flicker, do not know how. Although he is "Win32 API" of the experience, for Windows there is a mechanism called "double buffering". Or it can not be performed the same way as this in Arduino? I want you to tell me.

Thank you very much.

The arduino has not enough memory for double buffering, but flicker is caused by too many updates per second.

You can possibly reduce the flicker by updating only those parts that are actually changed.

So if your display shows e.g. "12.3 RPM" the RPM (rounds/minute) part is fixed so it does not need to be updated. If the new calculated value still is 12.3 you do not need to update it either.

in pseudo code you get constructs like

if (speed != lastspeed) { display(x,y, speed); lastspeed = speed; }

in fact the variable lastspeed reflects the value on the screen.

I have the same set and the same problems with it.

Is there a way to really change only the pixels of the screen that are actually changing? I.e. from "8" to "0" there are just a few pixels to be changed, but by writing the full "0" I see the flickering again.

The point is, that I update the screen every 500ms since I have to show dynamic analog values, and the flickering is very irritating. The displayed value has a length of max four digits, is it really not possible to put them into memory?

thank you for your support :)

micha_b: What robtillaart posted is perfectly usable for your use-case, but I would add slightly to it, as below:

if (speed != lastSpeed){

  display(x,y, lastSpeed, COLOUR_BACKGROUND);
  display(x,y, speed, COLOUR_FOREGROUND);
  lastspeed = speed;
}

Okio you're 100% right +1

Note: possibly a rectangle in background colours can be drawn faster than displaying chars (to be verified)

Thank you Rob and Okio,

I had the Idea of using a rectangle before, but I thought there has to be a more "elegant" solution. I will give it a try.

But anyway, I will try some other way too...

If I have to update a string, let's say "1234" into "1214", I will calculate the difference between both strings and will just change one digit. The flickering is mostly visible on constant digits....

Try this example:

#include <Adafruit_GFX.h>    
#include <Adafruit_ST7735.h> 
#include <SPI.h>

#define cs   10
#define dc   8
#define rst  9  

Adafruit_ST7735 tft = Adafruit_ST7735(cs, dc, rst);

char TX[50];

void setup() {
  tft.initR(INITR_BLACKTAB); 
  tft.fillScreen(ST7735_RED);
  tft.setRotation(3);   
}

void loop() {
  tft.setTextColor(ST7735_WHITE, ST7735_RED);
  int number = random(25555);
  int intPart = number/100; 
  int decimalPart = number - 100*intPart; 
  sprintf(TX,"%03d.%02d", intPart, decimalPart); //  XXX.XX
  tft.setTextSize(2);    
  tft.setCursor(50, 30);  
  tft.print(TX);   
  
  tft.setTextSize(3);    
  tft.setCursor(30, 65);  
  tft.print(TX);     
}

key: sprintf

micha_b: Thank you Rob and Okio,

I had the Idea of using a rectangle before, but I thought there has to be a more "elegant" solution. I will give it a try.

But anyway, I will try some other way too...

If I have to update a string, let's say "1234" into "1214", I will calculate the difference between both strings and will just change one digit. The flickering is mostly visible on constant digits....

That will work for a font in which every char/digit is equally wide... Still worth trying.

Still wasn’t happy with the previous attempt at eradicating flicker, so came up with the below and this has completely removed the flickering effect.
This does nothing more than draw a small rectangle from right edge of current/next text to the right edge of the previous text, but only when current print is shorter than previous. And as a bonus is faster.

	static int lat_x;


	.....

	y1 = y2;  // begin where previous line left off, remember top of rectangle
	tprintf("Lat:  %.6f", stats->pos.latitude);  // print something
	new_x = tft->getCursorX(); // record where this horizontal (column) ended
	tft->println("");   // go to next line so we can grab bottom of rectangle
	y2 = tft->getCursorY();
	if (new_x < lat_x)      // clear residual pixels
		tft->fillRect(new_x, y1, (lat_x-new_x)+1, (y2-y1)-1, COLOUR_BACKGROUND);
	lat_x = new_x; // set next location for next pass
	tft->setCursor(x, y2);  // x was clobbered, fix it for next line.

	.....

Super late but though i would post for anyone else. If you have 2 values one being the display value. So right before you switch the value set font, cursor, and make the color the background color and print that. Then update display value and set font, cursor, and desired font color. works great reduces flicker since it will only update upon a change.

if (intFdisp != intF) { tft.setFont(&FreeSmallFont); //Internal Tmp Sensors tft.setTextSize(2); tft.setCursor(55, 147); tft.setTextColor(BLACK); tft.print(intFdisp); tft.print("F"); tft.setCursor(55, 147); tft.setTextColor(RED); intFdisp = intF; tft.print(intFdisp); tft.print("F"); }

hopes this helps someone. having trouble doing this with my rtc time string. attempting to use string compare and have successfully used it in the past by the time thing is warping my brain :(

Damon

TFTLCDCyg:
Try this example:

#include <Adafruit_GFX.h>    

#include <Adafruit_ST7735.h>
#include <SPI.h>

#define cs   10
#define dc   8
#define rst  9

Adafruit_ST7735 tft = Adafruit_ST7735(cs, dc, rst);

char TX[50];

void setup() {
 tft.initR(INITR_BLACKTAB);
 tft.fillScreen(ST7735_RED);
 tft.setRotation(3);  
}

void loop() {
 tft.setTextColor(ST7735_WHITE, ST7735_RED);
 int number = random(25555);
 int intPart = number/100;
 int decimalPart = number - 100*intPart;
 sprintf(TX,"%03d.%02d", intPart, decimalPart); //  XXX.XX
 tft.setTextSize(2);    
 tft.setCursor(50, 30);  
 tft.print(TX);  
 
 tft.setTextSize(3);    
 tft.setCursor(30, 65);  
 tft.print(TX);    
}




key: sprintf

TFTLCDCyg:
Try this example:

#include <Adafruit_GFX.h>    

#include <Adafruit_ST7735.h>
#include <SPI.h>

#define cs   10
#define dc   8
#define rst  9

Adafruit_ST7735 tft = Adafruit_ST7735(cs, dc, rst);

char TX[50];

void setup() {
 tft.initR(INITR_BLACKTAB);
 tft.fillScreen(ST7735_RED);
 tft.setRotation(3);  
}

void loop() {
 tft.setTextColor(ST7735_WHITE, ST7735_RED);
 int number = random(25555);
 int intPart = number/100;
 int decimalPart = number - 100*intPart;
 sprintf(TX,"%03d.%02d", intPart, decimalPart); //  XXX.XX
 tft.setTextSize(2);    
 tft.setCursor(50, 30);  
 tft.print(TX);  
 
 tft.setTextSize(3);    
 tft.setCursor(30, 65);  
 tft.print(TX);    
}




key: sprintf

Thank you TFTLCDCyg,
Your Technic is perfect, I solved a stupid display flicker by you Technic, thank you so much.
Kea,