seeed tft 2.8 clear screen, used a display for can bus display

Hi all,

I have a TFT 2.8 working with an can bus shield from seeed as well to output realtime values from my ecu but when I clear it(Tft.fillScreen() it very inefficient, slow, any other ideas to speed this up so I dont see the frame rate?

#include <SPI.h>
#include <arduino.h>
//#include <Canbus.h>
//#include <defaults.h>
//#include <global.h>
//#include <stdint.h>
#include <mcp_can.h>
#include <mcp_can_dfs.h>
#include <SoftwareSerial.h>
#include <TFTv2.h>
//#include <PinChangeInt.h>

//SoftwareSerial sLCD =  SoftwareSerial(3, 6);

#define DOUBLE_CLICK_DELAY 100

#define NR_OF_CHANNELS (sizeof(channel)/sizeof(data_channel))

/* Define Joystick connection pins */
#define UP     A1
#define DOWN   A3
#define LEFT   A2
#define RIGHT  A5
#define CLICK  A4

//the cs pin of the version after v1.1 is default to D9
//v0.9b and v1.0 is default D10
const int SPI_CS_PIN = 9;
const int LED        = 8;
boolean ledON        = 1;

MCP_CAN CAN (SPI_CS_PIN);           //set CS Pin

enum {
  MIN,
  MAX,
  RUNTIME
};

struct data_channel {
  char *name;
  int multiplier;
  int divisor;
  int offset;
  int min_value;
  int max_value;
  int value;
};

int a,b,c,d,current;

int page_type = RUNTIME;

unsigned int last_click = 0;
int flip_request;

data_channel channel[] = {
// name, multiplier, divider, offset
    { "ECT", 1, 1, -50, 9999 },
    { "AFR", 1,1, 0  , 9999 },
    { "TPS", 1, 1, 0 , 9999 },
    { "MGP", 1, 1, -100, 9999 },
    { "IaT", 1, 1, -50, 9999 },
    { "Ign", 1, 1, 0, 9999 },
    { "Fup", 1, 1, 0, 9999 },
    { "Idc", 1, 1, 0, 9999 },

};

static FILE lcdout = {0};

static int lcd_putchar(char ch, FILE* stream)
{
  //sLCD.write(ch);
  //return 0;
}

void flip_page () {
  flip_request = 1;
  delay(250);
  Tft.fillScreen();
}

void setup() {
  Serial.begin(115200);
  Serial.println("ECU Reader");  /* For debug use */
  //sLCD.begin(9600);              /* Setup serial LCD and clear the screen */
  //clear_lcd();
  delay(10);

  pinMode(3, INPUT);
  digitalWrite(3,HIGH);
  attachInterrupt(1,flip_page,FALLING);
  /* setup the stream for the lcd to be able to use printf formating */
  fdev_setup_stream( &lcdout, lcd_putchar, NULL, _FDEV_SETUP_WRITE);
  //sLCD.write(COMMAND2);  /* set the display backlight to max */
  //sLCD.write(157);
  Serial.println("initializing can");
  while (CAN_OK != CAN.begin(CAN_500KBPS))              //Init can bus : Baudrate = CAN_500KBPS, Swapped for mcp_can begin
  
  TFT_BL_ON;
  Tft.TFTinit();
  
  //{
    //Tft.drawString("Can init fucked",0,30,3,RED);     //Swapped for TFT
    //delay(1000);
  //}
  Serial.println("Can init ok");
  //Tft.drawString("Can Init ok",0,10,2,GREEN);     //Swapped for TFT
  delay(1000);
  Tft.fillScreen();     //swapped for TFT 
  current = 0;

    //Initialize analog pins as inputs
  pinMode(UP,INPUT);
  pinMode(DOWN,INPUT);
  pinMode(LEFT,INPUT);
  pinMode(RIGHT,INPUT);
  pinMode(CLICK,INPUT);
  
  //Pull analog pins high to enable reading of joystick movements
  digitalWrite(UP, HIGH);
  digitalWrite(DOWN, HIGH);
  digitalWrite(LEFT, HIGH);
  digitalWrite(RIGHT, HIGH);
  digitalWrite(CLICK, HIGH);

  //pinMode(LED2_HIGH, OUTPUT);
  //pinMode(LED2_LOW, OUTPUT);
}

void read_channel()
{
  unsigned char len = 0;
  unsigned char buf[8];
  //for(int i = 0; i<len; i++)
  {
  if(CAN_MSGAVAIL == CAN.checkReceive())           //check if data is on the bus
    {
    CAN.readMsgBuf(&len, buf);          //  read data, len: data length, buf: data buf
            // organize data for more resolution in accuracy
        a = (buf[1] + buf[0]);
        b = (buf[3] + buf[2]);
        c = (buf[5] + buf[4]);
        d = (buf[7] + buf[6]);
        //if(ledON && i==0)
        /*{ Blink when messages are being recieved
          digitalWrite(LED, buf[i]);
          ledON = 0;
          delay(500);
        }
        else if((!(ledON)) && i==4)
        {
          digitalWrite(LED, buf[i]);
          ledON = 1;
        }  Blink when messages are being recieved */
    }
  }
  if(a*3 < NR_OF_CHANNELS ) process_value(a*3,b);
  if(a*3+1 < NR_OF_CHANNELS ) process_value(a*3+1,c);
  if(a*3+2 < NR_OF_CHANNELS ) process_value(a*3+2,d);
}
void process_value( int ch, int val )
{
  int value = val * channel[ch].multiplier / channel[ch].divisor + channel[ch].offset;
  channel[ch].value = value;
  if (value > channel[ch].max_value ) channel[ch].max_value = value;
  if (value < channel[ch].min_value ) channel[ch].min_value = value;
}

void display_page() {
  static int old_page;
  if(old_page!=current);
  old_page=current;
  int disp_values[4];
  for ( int i = 0; i < 4; i++ )
  {
    switch (page_type) {
      case MIN:
        disp_values[i] = channel[current+i].min_value;
        break;
      case MAX:
        disp_values[i] = channel[current+i].max_value;
        break;
      default:
        disp_values[i] = channel[current+i].value;
     }
    Tft.drawString(channel[current].name,0,10,5,GREEN);
    Tft.drawString(channel[current+1].name,0,90,5,RED);
    Tft.drawString(channel[current+2].name,0,180,5,YELLOW);
    Tft.drawString(channel[current+3].name,0,270,5,BLUE);
    Tft.drawNumber(disp_values[0],130,10,5,GREEN);
    Tft.drawNumber(disp_values[1],130,90,5,RED);
    Tft.drawNumber(disp_values[2],130,180,5,YELLOW);
    Tft.drawNumber(disp_values[3],130,270,5,BLUE);
  }
  Tft.fillScreen();
}

void loop() {
  for(int i=0;i<NR_OF_CHANNELS;i++ )  read_channel();
  if (millis()-500 > last_click  && flip_request )
  {
    current+=4;
    if (current > NR_OF_CHANNELS - 4) current=0;
    last_click = millis();
    flip_request = 0;
}
flip_request = 0;
display_page();
print_to_serial();

 {
  if (digitalRead(CLICK) == 0) 
  flip_page();}
}

void print_to_serial()
{
  Serial.print(millis());
  for( int i = 0; i < NR_OF_CHANNELS ; i++ ) {
    if(i) Serial.print(",");
    else Serial.print(":");
    Serial.print(channel[i].name);
    Serial.print("=");
    Serial.print(channel[i].value);
  }
  Serial.println();
}

//void clear_lcd(void){
  //sLCD.write(COMMAND);
  //sLCD.write(CLEAR);

Using delay() together with millis() is not a good idea. You should get rid of delay() altogether

Thanks for the reply,

I // the delay() out and this seems to have made no change, I am still able to see the frame rate. I am just stumped that there isn’t a more efficent way to up values on the screen without running Tft.fillScreen();?

here is the modified code

#include <SPI.h>
#include <arduino.h>
//#include <Canbus.h>
//#include <defaults.h>
//#include <global.h>
//#include <stdint.h>
#include <mcp_can.h>
#include <mcp_can_dfs.h>
#include <SoftwareSerial.h>
#include <TFTv2.h>
//#include <PinChangeInt.h>

//SoftwareSerial sLCD =  SoftwareSerial(3, 6);

#define COMMAND 0xFE
#define CLEAR   0x01
#define LINE0   0x80
#define LINE1   0xC0
#define COMMAND2 0x7C

//#define DOUBLE_CLICK_DELAY 100

#define NR_OF_CHANNELS (sizeof(channel)/sizeof(data_channel))

/* Define Joystick connection pins */
#define UP     A1
#define DOWN   A3
#define LEFT   A2
#define RIGHT  A5
#define CLICK  A4

//the cs pin of the version after v1.1 is default to D9
//v0.9b and v1.0 is default D10
const int SPI_CS_PIN = 9;
const int LED        = 8;
boolean ledON        = 1;

MCP_CAN CAN (SPI_CS_PIN);           //set CS Pin


enum {
  MIN,
  MAX,
  RUNTIME
};

struct data_channel {
  char *name;
  int multiplier;
  int divisor;
  int offset;
  int min_value;
  int max_value;
  int value;
};

int a,b,c,d,current;

int page_type = RUNTIME;

unsigned int last_click = 0;
int flip_request;

data_channel channel[] = {
// name, multiplier, divider, offset
    { "ECT", 1, 1, -50, 9999 },
    { "AFR", 1,1, 0  , 9999 },
    { "TPS", 1, 1, 0 , 9999 },
    { "MGP", 1, 1, -100, 9999 },
    { "IaT", 1, 1, -50, 9999 },
    { "Ign", 1, 1, 0, 9999 },
    { "Fup", 1, 1, 0, 9999 },
    { "Idc", 1, 1, 0, 9999 },

};

static FILE lcdout = {0};

static int lcd_putchar(char ch, FILE* stream)
{
  //sLCD.write(ch);
  //return 0;
}

void flip_page () {
  flip_request = 1;
  //delay(250);
  Tft.fillScreen();
}

void setup() {
  Serial.begin(115200);
  Serial.println("ECU Reader");  /* For debug use */
  //sLCD.begin(9600);              /* Setup serial LCD and clear the screen */
  //clear_lcd();
  //delay(10);

  pinMode(3, INPUT);
  digitalWrite(3,HIGH);
  attachInterrupt(1,flip_page,FALLING);
  /* setup the stream for the lcd to be able to use printf formating */
  fdev_setup_stream( &lcdout, lcd_putchar, NULL, _FDEV_SETUP_WRITE);
  //sLCD.write(COMMAND2);  /* set the display backlight to max */
  //sLCD.write(157);
  Serial.println("initializing can");
  while (CAN_OK != CAN.begin(CAN_500KBPS))              //Init can bus : Baudrate = CAN_500KBPS, Swapped for mcp_can begin
  
  TFT_BL_ON;
  Tft.TFTinit();
  
  //{
    //Tft.drawString("Can init fucked",0,30,3,RED);     //Swapped for TFT
    //delay(1000);
  //}
  Serial.println("Can init ok");
  //Tft.drawString("Can Init ok",0,10,2,GREEN);     //Swapped for TFT
  //delay(1000);
  Tft.fillScreen();     //swapped for TFT 
  current = 0;

    //Initialize analog pins as inputs
  pinMode(UP,INPUT);
  pinMode(DOWN,INPUT);
  pinMode(LEFT,INPUT);
  pinMode(RIGHT,INPUT);
  pinMode(CLICK,INPUT);
  
  //Pull analog pins high to enable reading of joystick movements
  digitalWrite(UP, HIGH);
  digitalWrite(DOWN, HIGH);
  digitalWrite(LEFT, HIGH);
  digitalWrite(RIGHT, HIGH);
  digitalWrite(CLICK, HIGH);

  //pinMode(LED2_HIGH, OUTPUT);
  //pinMode(LED2_LOW, OUTPUT);
}

void read_channel()
{
  unsigned char len = 0;
  unsigned char buf[8];
  //for(int i = 0; i<len; i++)
  {
  if(CAN_MSGAVAIL == CAN.checkReceive())           //check if data is on the bus
    {
    CAN.readMsgBuf(&len, buf);          //  read data, len: data length, buf: data buf
            // organize data for more resolution in accuracy
        a = (buf[1] + buf[0]);
        b = (buf[3] + buf[2]);
        c = (buf[5] + buf[4]);
        d = (buf[7] + buf[6]);
        //if(ledON && i==0)
        /*{ Blink when messages are being recieved
          digitalWrite(LED, buf[i]);
          ledON = 0;
          delay(500);
        }
        else if((!(ledON)) && i==4)
        {
          digitalWrite(LED, buf[i]);
          ledON = 1;
        }  Blink when messages are being recieved */
    }
  }
  if(a*3 < NR_OF_CHANNELS ) process_value(a*3,b);
  if(a*3+1 < NR_OF_CHANNELS ) process_value(a*3+1,c);
  if(a*3+2 < NR_OF_CHANNELS ) process_value(a*3+2,d);
}
void process_value( int ch, int val )
{
  int value = val * channel[ch].multiplier / channel[ch].divisor + channel[ch].offset;
  channel[ch].value = value;
  if (value > channel[ch].max_value ) channel[ch].max_value = value;
  if (value < channel[ch].min_value ) channel[ch].min_value = value;
}

void display_page() {
  static int old_page;
  if(old_page!=current);
  old_page=current;
  int disp_values[4];
  for ( int i = 0; i < 4; i++ )
  {
    switch (page_type) {
      case MIN:
        disp_values[i] = channel[current+i].min_value;
        break;
      case MAX:
        disp_values[i] = channel[current+i].max_value;
        break;
      default:
        disp_values[i] = channel[current+i].value;
     }
    Tft.drawString(channel[current].name,0,10,5,GREEN);
    Tft.drawString(channel[current+1].name,0,90,5,RED);
    Tft.drawString(channel[current+2].name,0,180,5,YELLOW);
    Tft.drawString(channel[current+3].name,0,270,5,BLUE);
    Tft.drawNumber(disp_values[0],130,10,5,GREEN);
    Tft.drawNumber(disp_values[1],130,90,5,RED);
    Tft.drawNumber(disp_values[2],130,180,5,YELLOW);
    Tft.drawNumber(disp_values[3],130,270,5,BLUE);
  }
  Tft.fillScreen();
}

void loop() {
  for(int i=0;i<NR_OF_CHANNELS;i++ )  read_channel();
  if (millis()-500 > last_click  && flip_request )
  {
    current+=4;
    if (current > NR_OF_CHANNELS - 4) current=0;
    last_click = millis();
    flip_request = 0;
 }
 flip_request = 0;
 display_page();
 print_to_serial();
 
 {
  if (digitalRead(CLICK) == 0) 
  flip_page();}
}

void print_to_serial()
{
  Serial.print(millis());
  for( int i = 0; i < NR_OF_CHANNELS ; i++ ) {
    if(i) Serial.print(",");
    else Serial.print(":");
    Serial.print(channel[i].name);
    Serial.print("=");
    Serial.print(channel[i].value);
  }
  Serial.println();
}

//void clear_lcd(void){
  //sLCD.write(COMMAND);
  //sLCD.write(CLEAR);