ILI9488_T3 Display load flicker

I am graphing 4 lines of data with 6 horizontal limit lines. I will be adding text later. the write cycle is slow. any way to do a one time write?
it also has a heave flicker.



#include <Adafruit_GFX.h>
int randNumber;
#include <SPI.h>
#include <ILI9488_t3.h>

#define TFT_RST 23
#define TFT_DC 20
#define TFT_CS 21
int X1;
int X0;
int X2;
int X3;
int X4;
int X5;
int X6;
int X7;
int i;
ILI9488_t3 tft = ILI9488_t3(&SPI, TFT_CS, TFT_DC, TFT_RST);
#include "Fonts/FreeSansOblique12pt7b.h"
//int slope=200;
int CanDrData[481];
int CanBotData[481];
int CanSideData[481];
int CanRadData[481];

int LEDa=35;
boolean LEDa_state=1;
boolean FastTSlowT =1;
int buz0=0;
int buz1=1;

long secD = 0;
int minutes=0;
float seconds=0.0;

int PWMVal=900;//x100
int PWMValPR;

float DriverTmpFL=300.0;
// int DriverTmpINT=300;
float SideTmpFL = 0.0;
// int SideTmpINT =0;
float BottomTempFL=0.0;
// int BottomTempINT= 0.0;
float AirInTempFL =0.0;
// int AirInTempINT= 0.0;
float AirOutTempFL =0.0;
// int AirOutTempINT= 0.0;


float Ther1 =0.0;
float Ther2 =0.0;
float Ther3 =0.0;
float Ther4 =0.0;
//float Ther5 =0.0;

#include <Adafruit_MAX31865.h>
Adafruit_MAX31865 thermo1 = Adafruit_MAX31865(10);// Use software SPI: CS, DI, DO, CLK
Adafruit_MAX31865 thermo2 = Adafruit_MAX31865(9);// Use software SPI: CS, DI, DO, CLK
Adafruit_MAX31865 thermo3 = Adafruit_MAX31865(8);// Use software SPI: CS, DI, DO, CLK
Adafruit_MAX31865 thermo4 = Adafruit_MAX31865(6);// 6 Use software SPI: CS, DI, DO, CLK
//Adafruit_MAX31865 thermo5 = Adafruit_MAX31865(7);// 7 Use software SPI: CS, DI, DO, CLK
#define RREF 430.0
#define RNOMINAL 100.0



void setup()
{
tft.begin();
tft.setRotation(1);
tft.fillScreen(ILI9488_WHITE);
delay (500);
tft.fillScreen(ILI9488_BLACK);
delay (500);
tft.fillScreen(ILI9488_RED);
delay (500);
tft.fillScreen(ILI9488_GREEN);
delay (500);
tft.fillScreen(ILI9488_BLUE);
delay (500);
tft.fillScreen(ILI9488_BLACK);
delay (500);
int i;
for (i=0;i<481;i=i+1)
{CanDrData=319;
CanBotData=319;
CanSideData=319;
CanRadData=319;
}

analogWriteFrequency(4, 30000);
analogWriteResolution(10);

pinMode(LEDa, OUTPUT);
pinMode(buz0, OUTPUT);
pinMode(buz1, OUTPUT);
Serial.begin(38400);
SPI.begin();
thermo1.begin(MAX31865_2WIRE); // set to 2WIRE or 4WIRE as necessary
thermo2.begin(MAX31865_2WIRE);
thermo3.begin(MAX31865_2WIRE); // set to 2WIRE or 4WIRE as necessary
thermo4.begin(MAX31865_2WIRE);
// thermo5.begin(MAX31865_2WIRE);

digitalWrite(LEDa, LOW);
digitalWrite(buz0, LOW);
digitalWrite(buz1, LOW);
delay (500);
digitalWrite(buz0, HIGH);
digitalWrite(buz1, HIGH);
digitalWrite(LEDa, HIGH);


}

void loop()
{

GetTemp();
GetDisplay();
while(millis()-secD<500){}
secD=millis();

delay (1);

seconds=seconds+.5;
if(seconds>59){seconds=0;minutes=minutes+1; }

if (FastTSlowT==0){
if(seconds==5||seconds==35)
{
if(Ther2<-1){PWMVal=PWMVal-10;}
if(Ther2<0){PWMVal=PWMVal-10;}
if(Ther2>3){PWMVal=PWMVal+10;}
if(Ther2>2){PWMVal=PWMVal+10;}
}
if(PWMVal>900){PWMVal=900;}
if(PWMVal<1){PWMVal=20;}
}

digitalWrite(LEDa, LEDa_state);
LEDa_state=!LEDa_state;
analogWrite(33,PWMVal );//PotVal
}


void GetDisplay(){
tft.fillScreen(ILI9488_BLACK);
for (i=0;i<481;i=i+1) //move graph
{X0=CanDrData[i-1];
X1=CanDrData;
X2=CanBotData[i-1];
X3=CanBotData;
X4=CanSideData[i-1];
X5=CanSideData;
X6=CanRadData[i-1];
X7=CanRadData;
tft.drawLine(i-1, X0, i, X1, ILI9488_WHITE);
tft.drawLine(i-1, X2, i, X3, ILI9488_RED); // ILI9488_BLUE
tft.drawLine(i-1, X4, i, X5, ILI9488_BLUE);//ILI9488_RED
tft.drawLine(i-1, X6, i, X7, ILI9488_GREEN);
}
tft.drawLine(0, 46, 480, 46, ILI9488_YELLOW); //20
tft.drawLine(0, 130, 480, 130, ILI9488_YELLOW); //10
tft.drawLine(0, 212, 480, 212, ILI9488_YELLOW); //-1
tft.drawLine(0, 213, 480, 213, ILI9488_YELLOW); //0
tft.drawLine(0, 214, 480, 214, ILI9488_YELLOW); //-1
tft.drawLine(0, 296, 480, 296, ILI9488_YELLOW); //-10 0, 296, 480, 296

CanDrData[480]=380-((DriverTmpFL+20)*8.333);//
CanBotData[480]=380-((BottomTempFL+20)*8.333); //
CanSideData[480]=380-((SideTmpFL+20)*8.333); //
CanRadData[480]=(380-((AirInTempFL+20)*8.333))+250; //offset doen
for (i=0;i<481;i=i+1)
{
CanDrData[i-1]=CanDrData;
CanBotData[i-1]=CanBotData;
CanSideData[i-1]=CanSideData;
CanRadData[i-1]=CanRadData;
}

}


void GetTemp(){

Ther1=(thermo1.temperature(RNOMINAL, RREF));
DriverTmpFL=Ther1;

Ther2=(thermo2.temperature(RNOMINAL, RREF));
BottomTempFL=Ther2;
if(BottomTempFL<2&&FastTSlowT==1){FastTSlowT=0;PWMVal=450;}// set T0

Ther3=(thermo3.temperature(RNOMINAL, RREF));
SideTmpFL=Ther3;
if(SideTmpFL<2&&FastTSlowT==1){FastTSlowT=0;PWMVal=450;}

Ther4=(thermo4.temperature(RNOMINAL, RREF));
AirInTempFL=Ther4;
// AirOutTempFL=Ther5;
PWMValPR=PWMVal/10;

Serial.print("SCTESC V3.2");
Serial.print(" time: "); Serial.print(minutes);
Serial.print(" : ) ");Serial.print(seconds);

Serial.print(" Drv ");Serial.print(Ther1);
Serial.print(" Bot "); Serial.print(Ther2);
Serial.print(" sid "); Serial.print(Ther3);
Serial.print(" Rai "); Serial.print(Ther4);
Serial.print(" PWM ");Serial.print(PWMValPR);
if (FastTSlowT==1){Serial.print(" Fast Mode "); }else {Serial.print(" Slow Mode "); }
Serial.println();

}


/*

Color definitions
#define ILI9488_BLACK
#define ILI9488_NAVY
#define ILI9488_DARKGREEN
#define ILI9488_DARKCYAN
#define ILI9488_MAROON
#define ILI9488_PURPLE
#define ILI9488_OLIVE
#define ILI9488_LIGHTGREY
#define ILI9488_DARKGREY
#define ILI9488_BLUE
#define ILI9488_GREEN
#define ILI9488_CYAN
#define ILI9488_RED
#define ILI9488_MAGENTA
#define ILI9488_YELLOW
#define ILI9488_WHITE
#define ILI9488_ORANGE
#define ILI9488_GREENYELLOW
#define ILI9488_PINK
*/
 
Code placed in a " </> " code block from the toolbar is easier to read and maintains indenting.

the GetDisplay() blanks the whole screen to black every 500 ms - then fully redraws the limit lines and data lines - that explains both the time it takes and the appearance of the flicker.

- if the screen isn't blanked then limit lines won't need to redraw if not written over
> keep and compare prior values.
- if the data values have not changed, they don't need to be drawn
then draw BLACK the old value bar and then the new value bar using the old and new data
(or, if the data bars only reduce or grow on the ends just BLACK reduced or COLOR draw the grown area)
> update old data to the new values for the next pass.
== if done minimally this can be done many times per second.
 
As mentioned it would help to see pictures of the display to see what it is doing...
Couple of different things:
Quick and dirty way:

a) Use a frame buffer.
Maybe at the in setup add:
Code:
tft.useFrameBuffer(true);
after your last output in getDisplay() add a call:
Code:
tft.updateScreen()

b) like a) except use tft.updateScreenAsync() instead of tft.updateScreen(), this will use
DMA to output and not hold up the rest of the code... If it still takes longer to output than the rest, you can add earlier in the getDisplay() a call
to tft.waitUpdateAsyncComplete() - which does as it sounds, it will hold up until the previous call to updateScreenAsync completes.

c) Some of the stuff that @defragster mentioned. Avoid using fillScreen, it blanks everything and you redraw... you get flicker. If possible split
out the things that don't change, do the outputs logically in setup.

Then you need to do smart updates, and there are many ways to do that... Like: if the previous data is scrolled to the left, you might get away
with readRect/writeRect of the areas. ...

Note also in your code you have issues with indexes... For example:
Code:
  for (i = 0; i < 481; i = i + 1)  //move graph
  {
    X0 = CanDrData[i - 1];
    X1 = CanDrData;
    X2 = CanBotData[i - 1];
...
So first time through this loop i=0, so X0= CanDrData[-1];
Most likely garbage, or last element from previous array in memory.

Ditto with your drawLine calls:
Code:
tft.drawLine(i - 1, X0, i, X1, ILI9488_WHITE);
Luckily the clipping code will handle the x of -1
 
As mentioned it would help to see pictures of the display to see what it is doing...
Couple of different things:
Quick and dirty way:

a) Use a frame buffer.
Maybe at the in setup add:
Code:
tft.useFrameBuffer(true);
after your last output in getDisplay() add a call:
Code:
tft.updateScreen()

b) like a) except use tft.updateScreenAsync() instead of tft.updateScreen(), this will use
DMA to output and not hold up the rest of the code... If it still takes longer to output than the rest, you can add earlier in the getDisplay() a call
to tft.waitUpdateAsyncComplete() - which does as it sounds, it will hold up until the previous call to updateScreenAsync completes.

c) Some of the stuff that @defragster mentioned. Avoid using fillScreen, it blanks everything and you redraw... you get flicker. If possible split
out the things that don't change, do the outputs logically in setup.

Then you need to do smart updates, and there are many ways to do that... Like: if the previous data is scrolled to the left, you might get away
with readRect/writeRect of the areas. ...

Note also in your code you have issues with indexes... For example:
Code:
  for (i = 0; i < 481; i = i + 1)  //move graph
  {
    X0 = CanDrData[i - 1];
    X1 = CanDrData;
    X2 = CanBotData[i - 1];
...
So first time through this loop i=0, so X0= CanDrData[-1];
Most likely garbage, or last element from previous array in memory.

Ditto with your drawLine calls:
Code:
tft.drawLine(i - 1, X0, i, X1, ILI9488_WHITE);
Luckily the clipping code will handle the x of -1
works great! thanks
 
Back
Top