Arduino slow cycle time with tft display

Hi everyone, this is my first time using a high-resolution display with arduino. I bought a uno shield with a 480*320 pixel resolution. My program draws some bars on the screen to monitor some of my car info (note: at the moment the canbus interface is not implemented and the hardware not wired.). The problem is that the screen updates every 650-700ms because the drawing on the screen is really slow. For something like water and oil temperature this is ok, but for turbo and commonrail pressure it is not. Am i doing something wring is my code?
i tried replacing the LOG10 function with some if/elses and the cycle time is reduced from 669.4ms to 668.7ms so i think the real problem is the drawing on the screen. Is is possible to lower the resolution of the screen, so the drawing is faster? (if i setup half the horizontal and vertical resolution, the cycle time is 4 times faster, but the dipslay doesnt scale and i can only use 1/4 of the pixels.)


The Sketch uses 60% of program storage space. and 6% of dynamic memory, so i am pretty sure this is not slowing it down. Here it is the full code:

#include <LCDWIKI_GUI.h> //Core graphics library
#include <LCDWIKI_KBV.h> //Hardware-specific library
//#include "font.h"

//if the IC model is known or the modules is unreadable,you can use this constructed function
//LCDWIKI_KBV my_lcd(ILI9486,A3,A2,A1,A0,A4); //model,cs,cd,wr,rd,reset
//if the IC model is not known and the modules is readable,you can use this constructed function


//LCDWIKI_KBV my_lcd(160,240,A3,A2,A1,A0,A4);//width,height,cs,cd,wr,rd,reset
LCDWIKI_KBV my_lcd(320,480,A3,A2,A1,A0,A4);//width,height,cs,cd,wr,rd,reset

char *aspect_name[] = {"PORTRAIT", "LANDSCAPE", "PORTRAIT_REV", "LANDSCAPE_REV"};
char *color_name[] = {"OLIO","ACQUA" ,"TURBO","CR"};
int *data[] = {110,90,11};
uint16_t color_mask[] = {0xffe0, 0x07ff, 0x07e0, 0xFFFF };


void show_string(uint8_t *str,int16_t x,int16_t y,uint8_t csize,uint16_t fc, uint16_t bc,boolean mode)
{
    my_lcd.Set_Text_Mode(mode);
    my_lcd.Set_Text_Size(csize);
    my_lcd.Set_Text_colour(fc);
    my_lcd.Set_Text_Back_colour(bc);
    my_lcd.Print_String(str,x,y);
}

void setup()
{
  //Serial.begin(9600);
  my_lcd.Init_LCD();
  my_lcd.Fill_Screen(BLACK);
  my_lcd.Set_Rotation(2); // from 0 to 4
}
 
void loop()
{
  for(int i=0; i<100; i++){
    oil(i);
    water(i*11/10);
    turbo(i/10);
    cr(i*20);
  }
  for(int i=100; i>0; i--){
    oil(i);
    water(i*11/10);
    turbo(i/10);
    cr(i*20);
  }
}

void oil(int temp)
{
  int oilTemp = temp;
  int widthPercent = temp; //larchezza della barra
  char oilCharArray[4];
  snprintf(oilCharArray, sizeof(oilCharArray), "%d", oilTemp);

  int digit = (log10(temp)+1);

  showscreen(widthPercent, oilCharArray, digit, 0);
}

void water(int temp)
{
  int waterTemp = temp;
  char waterCharArray[4];
  int widthPercent = temp;
  snprintf(waterCharArray, sizeof(waterCharArray), "%d", waterTemp);

  int digit = (log10(temp)+1);

  showscreen(widthPercent, waterCharArray, digit, 1);
}

void cr(int pressure)
{
  int crpressure = pressure;
  char cr[4];
  int widthPercent = pressure;
  snprintf(cr, sizeof(cr), "%d", crpressure);

  int digit = (log10(pressure)+1);

  showscreen(widthPercent, cr, digit, 3);
}

void turbo(int temp)
{
  int turboBoost = temp;
  char turboCharArray[4];
  int widthPercent = temp*10;
  snprintf(turboCharArray, sizeof(turboCharArray), "%d", turboBoost);

  int digit = (log10(temp)+1);

  showscreen(widthPercent, turboCharArray, digit, 2);
  
  //Serial.println("x");
}


void showscreen(int widthPercent, char temperatura[],int digit, int i){
  
  int cnum = sizeof(color_mask)/sizeof(uint16_t);

  int rectangleWidth = (320*widthPercent/100);
  int blackWidth = (320 - rectangleWidth);
  int rectangleHeight = ((480/cnum)*i);
  int horizontalPositioning = 0;
  int verticalPositioning = ((480/cnum)*(i+1));


  my_lcd.Set_Draw_color(192, 192, 192); //192 finale
  my_lcd.Set_Draw_color(my_lcd.Get_Draw_color()&color_mask[i]);
  my_lcd.Fill_Rectangle(0,i*(480/cnum), rectangleWidth , (i+1)*(480/cnum)); //colored rectangle

  my_lcd.Set_Draw_color(0, 0, 0); //nero
  my_lcd.Set_Draw_color(my_lcd.Get_Draw_color()&color_mask[i]);
  my_lcd.Fill_Rectangle(rectangleWidth+1 ,i*(480/cnum), 320, (i+1)*(480/cnum)); //black rectangle

  
  show_string(color_name[i],((my_lcd.Get_Display_Width()/2)-25),((my_lcd.Get_Display_Height()/cnum)+64)/2+(my_lcd.Get_Display_Height()/cnum)*i,2,color_mask[i], BLACK,1);
  show_string(temperatura,  ((my_lcd.Get_Display_Width()/2)-(digit*21)),((my_lcd.Get_Display_Height()/cnum)-64)/2+(my_lcd.Get_Display_Height()/cnum)*i,8,color_mask[i], BLACK,1);
  }

The first rule to fast screen updates is to change only those fields that actually need changing. Your loop function appears to rewrite the entire screen, every loop cycle. The fewer pixels you change, the faster the updates.

Investigate how the Arduino actually communicates with the display. If it is by SPI, perhaps you can increase the SPI clock rate. I'm not familiar with that screen or library.

hi, yes. i do that because if i dont rewrite all the screen, the new numbers are written on top of the old ones, making a mess. I tried reading the library .cpp file but it does not seem to use the spi bus.
I think it uses the A0-A4 pins

Here it is the library, it is quite long:

// IMPORTANT: LIBRARY MUST BE SPECIFICALLY CONFIGURED FOR EITHER TFT SHIELD
// OR BREAKOUT BOARD USAGE.

// Lcdwiki GUI library
// MIT license

#if defined(__SAM3X8E__)
	#include <include/pio.h>
    #define PROGMEM
    #define pgm_read_byte(addr) (*(const unsigned char *)(addr))
    #define pgm_read_word(addr) (*(const unsigned short *)(addr))
#endif

#include "pins_arduino.h"
#include "wiring_private.h"
#include "LCDWIKI_KBV.h"
#include "lcd_registers.h"
#include "lcd_mode.h"
#if (CONFIG_USE_8BIT_BUS==1)
#include "mcu_8bit_magic.h"
#elif (CONFIG_USE_8BIT_BUS==0)
#include "mcu_16bit_magic.h"
#endif

#define TFTLCD_DELAY16  0xFFFF
#define TFTLCD_DELAY8   0x7F
#define MAX_REG_NUM     24

//static uint8_t have_reset;

//#define LEFT_SHIFT(x) (1<<x) //x value 0:mipi dcs rev1
                             //        1:auto readinc
                             //        2:read bgr
                             //        3:read low and high
                             //        4:read 24 bits
                             //        5:xsa and xea 16 bit
                             //        6:read no dummy
                             //        8:invert gs
                             //        9:invert ss
                             //       10:mv axis
                             //       11:invert rgb
                             //       12:rev screen
                             //       13:filp vert	
			                 //       14:flip horiz

//The mode,width and heigth of supported LCD modules
lcd_info current_lcd_info[] = 
						 { 
							 0x9325,240,320,			
							 0x9328,240,320,
							 0x9341,240,320,
							 0x9090,320,480,
							 0x7575,240,320,
							 0x9595,240,320,
							 0x9486,320,480,
							 0x7735,128,160,
							 0x9488,320,480,
							 0x9481,320,480,
							 0x7796,320,480,
						 };

// Constructor for breakout board (configurable LCD control lines).
// Can still use this w/shield, but parameters are ignored.
// if modules is unreadable or you don't know the width and height of modules,you can use this constructor.
LCDWIKI_KBV::LCDWIKI_KBV(uint16_t model,uint8_t cs, uint8_t cd, uint8_t wr, uint8_t rd, uint8_t reset)
{	
  #ifndef USE_ADAFRUIT_SHIELD_PIN
	  // Convert pin numbers to registers and bitmasks
	  _reset	 = reset;
  #ifdef __AVR__
		csPort	   = portOutputRegister(digitalPinToPort(cs));
		cdPort	   = portOutputRegister(digitalPinToPort(cd));
		wrPort	   = portOutputRegister(digitalPinToPort(wr));
		rdPort	   = portOutputRegister(digitalPinToPort(rd));
  #endif
  #if defined(__SAM3X8E__)
		csPort	   = digitalPinToPort(cs);
		cdPort	   = digitalPinToPort(cd);
		wrPort	   = digitalPinToPort(wr);
		rdPort	   = digitalPinToPort(rd);
  #endif
	  csPinSet	 = digitalPinToBitMask(cs);
	  cdPinSet	 = digitalPinToBitMask(cd);
	  wrPinSet	 = digitalPinToBitMask(wr);
	  rdPinSet	 = digitalPinToBitMask(rd);
	  csPinUnset = ~csPinSet;
	  cdPinUnset = ~cdPinSet;
	  wrPinUnset = ~wrPinSet;
	  rdPinUnset = ~rdPinSet;
  #ifdef __AVR__
		*csPort   |=  csPinSet; // Set all control bits to HIGH (idle)
		*cdPort   |=  cdPinSet; // Signals are ACTIVE LOW
		*wrPort   |=  wrPinSet;
		*rdPort   |=  rdPinSet;
  #endif
  #if defined(__SAM3X8E__)
		csPort->PIO_SODR  |=  csPinSet; // Set all control bits to HIGH (idle)
		cdPort->PIO_SODR  |=  cdPinSet; // Signals are ACTIVE LOW
		wrPort->PIO_SODR  |=  wrPinSet;
		rdPort->PIO_SODR  |=  rdPinSet;
  #endif
	  pinMode(cs, OUTPUT);	  // Enable outputs
	  pinMode(cd, OUTPUT);
	  pinMode(wr, OUTPUT);
	  pinMode(rd, OUTPUT);
	  if(reset) 
	  {
		 digitalWrite(reset, HIGH);
		 pinMode(reset, OUTPUT);
	  }
  #endif
  #ifdef USE_ADAFRUIT_SHIELD_PIN 
  	 CS_IDLE; // Set all control bits to idle state
 	 WR_IDLE;
  	 RD_IDLE;
  	 CD_DATA;
 	 digitalWrite(5, HIGH); // Reset line
 	 pinMode(A3, OUTPUT);   // Enable outputs
 	 pinMode(A2, OUTPUT);
 	 pinMode(A1, OUTPUT);
 	 pinMode(A0, OUTPUT);
  	 pinMode( 5, OUTPUT);
 #endif
 	rotation = 0;
 	lcd_model = current_lcd_info[model].lcd_id;
	WIDTH = current_lcd_info[model].lcd_wid;
	HEIGHT = current_lcd_info[model].lcd_heg;
/*
	switch(lcd_model)
	{
		case 0x7735:
			WIDTH = 128;
			HEIGHT = 160;
		    break;
		case 0x9325:
		case 0x9328:
		case 0x9341:
		case 0x7575:
		case 0x9595:
			WIDTH = 240;
			HEIGHT = 320;
		    break;
		case 0x9486:
			WIDTH = 320;
			HEIGHT = 480;
            break;
		default:
			WIDTH = 0;
			HEIGHT = 0;
			break;
	}
*/
    setWriteDir();
 	width = WIDTH;
	height = HEIGHT;		
}

// Constructor for breakout board (configurable LCD control lines).
// Can still use this w/shield, but parameters are ignored.
// if modules is readable or you know the width and height of modules,you can use this constructor.
LCDWIKI_KBV::LCDWIKI_KBV(int16_t wid,int16_t heg,uint8_t cs, uint8_t cd, uint8_t wr, uint8_t rd, uint8_t reset)
{	
  #ifndef USE_ADAFRUIT_SHIELD_PIN
	  // Convert pin numbers to registers and bitmasks
	  _reset	 = reset;
  #ifdef __AVR__
		csPort	   = portOutputRegister(digitalPinToPort(cs));
		cdPort	   = portOutputRegister(digitalPinToPort(cd));
		wrPort	   = portOutputRegister(digitalPinToPort(wr));
		rdPort	   = portOutputRegister(digitalPinToPort(rd));
  #endif
  #if defined(__SAM3X8E__)
		csPort	   = digitalPinToPort(cs);
		cdPort	   = digitalPinToPort(cd);
		wrPort	   = digitalPinToPort(wr);
		rdPort	   = digitalPinToPort(rd);
  #endif
	  csPinSet	 = digitalPinToBitMask(cs);
	  cdPinSet	 = digitalPinToBitMask(cd);
	  wrPinSet	 = digitalPinToBitMask(wr);
	  rdPinSet	 = digitalPinToBitMask(rd);
	  csPinUnset = ~csPinSet;
	  cdPinUnset = ~cdPinSet;
	  wrPinUnset = ~wrPinSet;
	  rdPinUnset = ~rdPinSet;
  #ifdef __AVR__
		*csPort   |=  csPinSet; // Set all control bits to HIGH (idle)
		*cdPort   |=  cdPinSet; // Signals are ACTIVE LOW
		*wrPort   |=  wrPinSet;
		*rdPort   |=  rdPinSet;
  #endif
  #if defined(__SAM3X8E__)
		csPort->PIO_SODR  |=  csPinSet; // Set all control bits to HIGH (idle)
		cdPort->PIO_SODR  |=  cdPinSet; // Signals are ACTIVE LOW
		wrPort->PIO_SODR  |=  wrPinSet;
		rdPort->PIO_SODR  |=  rdPinSet;
  #endif
	  pinMode(cs, OUTPUT);	  // Enable outputs
	  pinMode(cd, OUTPUT);
	  pinMode(wr, OUTPUT);
	  pinMode(rd, OUTPUT);
	  if(reset) 
	  {
		 digitalWrite(reset, HIGH);
		 pinMode(reset, OUTPUT);
	  }
  #endif
  #ifdef USE_ADAFRUIT_SHIELD_PIN 
  	 CS_IDLE; // Set all control bits to idle state
 	 WR_IDLE;
  	 RD_IDLE;
  	 CD_DATA;
 	 digitalWrite(5, HIGH); // Reset line
 	 pinMode(A3, OUTPUT);   // Enable outputs
 	 pinMode(A2, OUTPUT);
 	 pinMode(A1, OUTPUT);
 	 pinMode(A0, OUTPUT);
  	 pinMode( 5, OUTPUT);
 #endif
 	rotation = 0;
 	lcd_model = 0xFFFF;
    setWriteDir();
	WIDTH = wid;
	HEIGHT = heg;
 	width = WIDTH;
	height = HEIGHT;		
}

// Initialization lcd modules
void LCDWIKI_KBV::Init_LCD(void)
{
	reset();
	if(lcd_model == 0xFFFF)
	{
		lcd_model = Read_ID(); 
	}
//	uint16_t ID = Read_ID(); 
	start(lcd_model);
//	Set_Rotation(0);
}

// Initialization common to both shield & breakout configs
void LCDWIKI_KBV::reset(void)
{
//	have_reset = 1;
//    setWriteDir();
//Set all control bits to idle state
    CS_IDLE;
    RD_IDLE;
    WR_IDLE;

#ifdef USE_ADAFRUIT_SHIELD_PIN
  digitalWrite(5, LOW);
  delay(2);
  digitalWrite(5, HIGH);
//  delay(100);
  //digitalWrite(5, LOW);
 // delay(100);
#else
  if(_reset) 
  {
    digitalWrite(_reset, LOW);
    delay(2);
    digitalWrite(_reset, HIGH);
//	delay(100);
	//digitalWrite(_reset, LOW);
	//delay(100);
  }
#endif
  CS_ACTIVE;
  CD_COMMAND;
  write8(0x00);
  for(uint8_t i=0; i<3; i++)
  {
  	WR_STROBE; // Three extra 0x00s
  }
  CS_IDLE;
}

void LCDWIKI_KBV::Write_Cmd(uint16_t cmd)
{
	writeCmd16(cmd);
}

void LCDWIKI_KBV::Write_Data(uint16_t data)
{
	writeData16(data);
}

void LCDWIKI_KBV::Write_Cmd_Data(uint16_t cmd, uint16_t data)
{
	writeCmdData16(cmd,data);
}

//Write a command and N datas
void LCDWIKI_KBV::Push_Command(uint16_t cmd, uint8_t *block, int8_t N)
{
  	CS_ACTIVE;
    writeCmd16(cmd);
    while (N-- > 0) 
	{
        uint8_t u8 = *block++;
        writeData8(u8); 
		if(N && (lcd_driver == ID_7575))
		{
			cmd++;
			writeCmd16(cmd);
		}
    }
    CS_IDLE;
}

// Sets the LCD address window 
void LCDWIKI_KBV::Set_Addr_Window(int16_t x1, int16_t y1, int16_t x2, int16_t y2)
{
	CS_ACTIVE;
	if(lcd_driver == ID_932X) 
	{

	    // Values passed are in current (possibly rotated) coordinate
	    // system.  932X requires hardware-native coords regardless of
	    // MADCTL, so rotate inputs as needed.  The address counter is
	    // set to the top-left corner -- although fill operations can be
	    // done in any direction, the current screen rotation is applied
	    // because some users find it disconcerting when a fill does not
	    // occur top-to-bottom.
	    int x, y, t;
	    switch(rotation) 
		{
		     default:
			      x  = x1;
			      y  = y1;
			      break;
		     case 1:
			      t  = y1;
			      y1 = x1;
			      x1 = WIDTH  - 1 - y2;
			      y2 = x2;
			      x2 = WIDTH  - 1 - t;
			      x  = x2;
			      y  = y1;
		      	  break;
		     case 2:
			      t  = x1;
			      x1 = WIDTH  - 1 - x2;
			      x2 = WIDTH  - 1 - t;
			      t  = y1;
			      y1 = HEIGHT - 1 - y2;
			      y2 = HEIGHT - 1 - t;
			      x  = x2;
			      y  = y2;
			      break;
		     case 3:
			      t  = x1;
			      x1 = y1;
			      y1 = HEIGHT - 1 - x2;
			      x2 = y2;
			      y2 = HEIGHT - 1 - t;
			      x  = x1;
			      y  = y2;
			      break;
    	}
    writeCmdData16(ILI932X_HOR_START_AD, x1); // Set address window
    writeCmdData16(ILI932X_HOR_END_AD, x2);
    writeCmdData16(ILI932X_VER_START_AD, y1);
    writeCmdData16(ILI932X_VER_END_AD, y2);
    writeCmdData16(ILI932X_GRAM_HOR_AD, x ); // Set address counter to top left
    writeCmdData16(ILI932X_GRAM_VER_AD, y );
 	} 
	else if(lcd_driver == ID_7575)
	{
		writeCmdData8(HX8347G_COLADDRSTART_HI,x1>>8);
		writeCmdData8(HX8347G_COLADDRSTART_LO,x1);
		writeCmdData8(HX8347G_ROWADDRSTART_HI,y1>>8);
		writeCmdData8(HX8347G_ROWADDRSTART_LO,y1);
		writeCmdData8(HX8347G_COLADDREND_HI,x2>>8);
		writeCmdData8(HX8347G_COLADDREND_LO,x2);
		writeCmdData8(HX8347G_ROWADDREND_HI,y2>>8);
		writeCmdData8(HX8347G_ROWADDREND_LO,y2);
	}
	else
	{
		uint8_t x_buf[] = {x1>>8,x1&0xFF,x2>>8,x2&0xFF}; 
		uint8_t y_buf[] = {y1>>8,y1&0xFF,y2>>8,y2&0xFF}; 
	
		Push_Command(XC, x_buf, 4); //set x address
		Push_Command(YC, y_buf, 4); //set y address
	}
	CS_IDLE;		
}

// Unlike the 932X drivers that set the address window to the full screen
// by default (using the address counter for drawPixel operations), the
// 7575 needs the address window set on all graphics operations.  In order
// to save a few register writes on each pixel drawn, the lower-right
// corner of the address window is reset after most fill operations, so
// that drawPixel only needs to change the upper left each time.
void LCDWIKI_KBV::Set_LR(void)
{
	CS_ACTIVE;
	writeCmdData8(HX8347G_COLADDREND_HI,(width -1)>>8);
	writeCmdData8(HX8347G_COLADDREND_LO,width -1);
	writeCmdData8(HX8347G_ROWADDREND_HI,(height -1)>>8);
	writeCmdData8(HX8347G_ROWADDREND_LO,height -1);
	CS_IDLE;
}

//push color table for 16bits
void LCDWIKI_KBV::Push_Any_Color(uint16_t * block, int16_t n, bool first, uint8_t flags)
{
	uint16_t color;
    uint8_t h, l;
	bool isconst = flags & 1;
//	bool isbigend = (flags & 2) != 0;
    CS_ACTIVE;
    if (first) 
	{  
		if(lcd_driver == ID_932X)
		{
			writeCmd8(ILI932X_START_OSC);
			
		}
		writeCmd8(CC);		
    }
    while (n-- > 0) 
	{
        if (isconst) 
		{
			color = pgm_read_word(block++);		
        } 
		else 
		{
			color = (*block++);			

		}		
        writeData16(color);
    }
    CS_IDLE;
}

//push color table for 8bits
void LCDWIKI_KBV::Push_Any_Color(uint8_t * block, int16_t n, bool first, uint8_t flags)
{
	uint16_t color;
    uint8_t h, l;
	bool isconst = flags & 1;
	bool isbigend = (flags & 2) != 0;
    CS_ACTIVE;
    if (first) 
	{
		if(lcd_driver == ID_932X)
		{
			writeCmd8(ILI932X_START_OSC);
			
		}
		writeCmd8(CC);		
    }
    while (n-- > 0) 
	{
        if (isconst) 
		{
            h = pgm_read_byte(block++);
            l = pgm_read_byte(block++);
        } 
		else 
		{
		    h = (*block++);
            l = (*block++);
		}
        color = (isbigend) ? (h << 8 | l) :  (l << 8 | h);
        writeData16(color);
    }
    CS_IDLE;
}

//Pass 8-bit (each) R,G,B, get back 16-bit packed color
uint16_t LCDWIKI_KBV::Color_To_565(uint8_t r, uint8_t g, uint8_t b)
{
	return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | ((b & 0xF8) >> 3);
}

//read value from lcd register 
uint16_t LCDWIKI_KBV::Read_Reg(uint16_t reg, int8_t index)
{
	uint16_t ret,high;
    uint8_t low;
//  if (!have_reset)
 // {
 //     reset();
//  }
	CS_ACTIVE;
    writeCmd16(reg);
    setReadDir();
    delay(1); 
	do 
	{ 
	//ead8(high);
	//ead8(low);
	//et = (high << 8) | lowc
		read16(ret);  //read 16bits
	}while (--index >= 0);   
//    RD_IDLE;
    CS_IDLE;
    setWriteDir();
    return ret;
}

//read graph RAM data
int16_t LCDWIKI_KBV::Read_GRAM(int16_t x, int16_t y, uint16_t *block, int16_t w, int16_t h)
{
	uint16_t ret, dummy;
    int16_t n = w * h;
    uint8_t r, g, b, tmp;
    Set_Addr_Window(x, y, x + w - 1, y + h - 1);
    while (n > 0) 
	{
        CS_ACTIVE;
		writeCmd16(RC);
        setReadDir();
		if(lcd_driver == ID_932X)
		{
			while(n)
			{
				for(int i =0; i< 2; i++)
				{
					read8(r);
					read8(r);
					read8(r);
					read8(g);
				}
				*block++ = (r<<8 | g);
				n--;
			}
			Set_Addr_Window(0, 0, width - 1, height - 1);
		}
		else 
		{
			read8(r);
        	while (n) 
			{
				if(R24BIT == 1)
				{
        			read8(r);
         			read8(g);
        			read8(b);
            		ret = Color_To_565(r, g, b);
				}
				else if(R24BIT == 0)
				{
					read16(ret);
				}
            	*block++ = ret;
            	n--;
        	}
        }
//        RD_IDLE;
        CS_IDLE;
        setWriteDir();
    }
	return 0;
}

//read LCD controller chip ID 
uint16_t LCDWIKI_KBV::Read_ID(void)
{
	uint16_t ret;
	if ((Read_Reg(0x04,0) == 0x00)&&(Read_Reg(0x04,1) == 0x8000))
	{
		uint8_t buf[] = {0xFF, 0x83, 0x57};
		Push_Command(HX8357D_SETC, buf, sizeof(buf));
		ret = (Read_Reg(0xD0,0) << 16) | Read_Reg(0xD0,1);
		if((ret == 0x990000) || (ret == 0x900000))
		{
			return 0x9090;
		}
	}
	ret = Read_Reg(0xD3,1); //0x9341 0x9486
	if(ret == 0x9341)
	{
		return 0x9341;
	}
	else if(ret == 0x9486)
	{
		return 0x9486;
	}
	else if(ret == 0x9488)
	{
		return 0x9488;
	}
	else if(ret == 0x7796)
	{
		return 0x7796;
	}
	else
	{
		return Read_Reg(0, 0); //others
	}
}

//set x,y  coordinate and color to draw a pixel point 
void LCDWIKI_KBV::Draw_Pixe(int16_t x, int16_t y, uint16_t color)
{
	if((x < 0) || (y < 0) || (x > Get_Width()) || (y > Get_Height()))
	{
		return;
	}
	Set_Addr_Window(x, y, x, y);
	CS_ACTIVE;
	writeCmdData16(CC, color);
	CS_IDLE;
}

//fill area from x to x+w,y to y+h
void LCDWIKI_KBV::Fill_Rect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color)
{
	int16_t end;
	if (w < 0) 
	{
        w = -w;
        x -= w;
    }                           //+ve w
    end = x + w;
    if (x < 0)
    {
        x = 0;
    }
    if (end > Get_Width())
    {
        end = Get_Width();
    }
    w = end - x;
    if (h < 0) 
	{
        h = -h;
        y -= h;
    }                           //+ve h
    end = y + h;
    if (y < 0)
    {
        y = 0;
    }
    if (end > Get_Height())
    {
        end = Get_Height();
    }
    h = end - y;
    Set_Addr_Window(x, y, x + w - 1, y + h - 1);//set area
	CS_ACTIVE;
    if(lcd_driver == ID_932X)
	{
		writeCmd8(ILI932X_START_OSC);
			
	}
	writeCmd8(CC);	
	if (h > w) 
	{
        end = h;
        h = w;
        w = end;
    }
	while (h-- > 0) 
	{
		end = w;
		do 
		{
   			writeData16(color);//set color data
        } while (--end != 0);
	}
	if(lcd_driver == ID_932X)
	{
		Set_Addr_Window(0, 0, width - 1, height - 1);
	}
	else if(lcd_driver == ID_7575)
	{
		Set_LR();
	}
	CS_IDLE;
}

//Scroll display 
void LCDWIKI_KBV::Vert_Scroll(int16_t top, int16_t scrollines, int16_t offset)
{
    int16_t bfa = HEIGHT - top - scrollines; 
    int16_t vsp;
    int16_t sea = top;
    if (offset <= -scrollines || offset >= scrollines)
    {
		offset = 0; //valid scroll
    }
	vsp = top + offset; // vertical start position
    if (offset < 0)
    {
        vsp += scrollines;          //keep in unsigned range
    }
    sea = top + scrollines - 1;
	if(lcd_driver == ID_932X)
	{
		writeCmdData8(SC1, (1 << 1) | 0x1);        //!NDL, VLE, REV
        writeCmdData8(SC2, vsp);        //VL#
	}
	else
	{
  		uint8_t d[6];           // for multi-byte parameters
  		d[0] = top >> 8;        //TFA
  		d[1] = top;
  		d[2] = scrollines >> 8; //VSA
  		d[3] = scrollines;
  		d[4] = bfa >> 8;        //BFA
  		d[5] = bfa;
		Push_Command(SC1, d, 6);
		d[0] = vsp >> 8;        //VSP
  		d[1] = vsp;
		Push_Command(SC2, d, 2);
		if(lcd_driver == ID_7575)
		{
			d[0] = (offset != 0) ? 0x08:0;
			Push_Command(0x01, d, 1);
		}
		else if (offset == 0) 
		{
			Push_Command(0x13, NULL, 0);
		}
	}
}

//get lcd width
int16_t LCDWIKI_KBV::Get_Width(void) const
{
	return width;
}

//get lcd height
int16_t LCDWIKI_KBV::Get_Height(void) const
{
	return height;
}

//set clockwise rotation
void LCDWIKI_KBV::Set_Rotation(uint8_t r)
{
    rotation = r & 3;           // just perform the operation ourselves on the protected variables
    width = (rotation & 1) ? HEIGHT : WIDTH;
    height = (rotation & 1) ? WIDTH : HEIGHT;
	CS_ACTIVE;
	if(lcd_driver == ID_932X)
	{
		uint16_t val;
		switch(rotation) 
		{
			default: 
				val = 0x1030;  //0 degree 
				break;
		 	case 1 : 
				val = 0x1028;  //90 degree 
				break;
		 	case 2 : 
				val = 0x1000;  //180 degree 
				break;
		 	case 3 : 
				val = 0x1018;  //270 degree 
				break;
		}
		writeCmdData16(MD, val); 
	}
	else if(lcd_driver == ID_7735)
	{
		uint8_t val;
		switch(rotation)
		{
			case 0: 
				val = 0xD0; //0 degree 
				break;
		 	case 1: 
				val = 0xA0; //90 degree 
				break;
		 	case 2: 
				val = 0x00; //180 degree 
				break;
		 	case 3: 
				val = 0x60; //270 degree
				break;			
		}
		writeCmdData8(MD, val);
	}
	else if(lcd_driver == ID_9481)
	{
		uint8_t val;
		switch (rotation) 
		{
		   	case 0:
		     	val = 0x09; //0 degree PAO=0,CAO=0,P/CO=0,VO=0,RGBO=1,DO=0,HF=0,VF=1
		     	break;
		   	case 1:
		     	val = 0x2B; //90 degree PAO=0,CAO=0,P/CO=1,VO=0,RGBO=1,DO=0,HF=1,VF=1
		     	break;
		 	case 2:
		    	val = 0x0A; //180 degree PAO=0,CAO=0,P/CO=0,VO=0,RGBO=1,DO=0,HF=1,VF=0
		    	break;
		   	case 3:
		     	val = 0x28; //270 degree PAO=0,CAO=0,P/CO=1,VO=0,RGBO=1,DO=0,HF=0,VF=0
		     	break;
		 }
		 writeCmdData8(MD, val); 

	}
	else if(lcd_driver == ID_9486)
	{
		uint8_t val;
		switch (rotation) 
		{
		   	case 0:
		     	val = ILI9341_MADCTL_MX | ILI9341_MADCTL_BGR; //0 degree 
		     	break;
		   	case 1:
		     	val = ILI9341_MADCTL_MV | ILI9341_MADCTL_ML | ILI9341_MADCTL_BGR ; //90 degree 
		     	break;
		 	case 2:
		    	val = ILI9341_MADCTL_MY |ILI9341_MADCTL_BGR; //180 degree 
		    	break;
		   	case 3:
		     	val = ILI9341_MADCTL_MX | ILI9341_MADCTL_MY | ILI9341_MADCTL_MV | ILI9341_MADCTL_BGR; //270 degree
		     	break;
		 }
		 writeCmdData8(MD, val); 
	}
	else if(lcd_driver == ID_9488)
	{
		uint8_t val;
		switch (rotation) 
		{			
			case 0:
		     	val = ILI9341_MADCTL_MX | ILI9341_MADCTL_MY | ILI9341_MADCTL_BGR ; //0 degree 
		     	break;
		   	case 1:
		     	val = ILI9341_MADCTL_MV | ILI9341_MADCTL_MY | ILI9341_MADCTL_BGR ; //90 degree 
		     	break;
		 	case 2:
		    	val = ILI9341_MADCTL_ML | ILI9341_MADCTL_BGR; //180 degree 
		    	break;
		   	case 3:
		     	val = ILI9341_MADCTL_MX | ILI9341_MADCTL_ML | ILI9341_MADCTL_MV | ILI9341_MADCTL_BGR; //270 degree
		     	break;
		 }
		 writeCmdData8(MD, val); 
	}
	else
	{
		uint8_t val;
		switch (rotation) 
		{
		   	case 0:
		     	val = ILI9341_MADCTL_MX | ILI9341_MADCTL_BGR; //0 degree 
		     	break;
		   	case 1:
		     	val = ILI9341_MADCTL_MV | ILI9341_MADCTL_BGR; //90 degree 
		     	break;
		 	case 2:
		    	val = ILI9341_MADCTL_MY | ILI9341_MADCTL_ML |ILI9341_MADCTL_BGR; //180 degree 
		    	break;
		   	case 3:
		     	val = ILI9341_MADCTL_MX | ILI9341_MADCTL_MY| ILI9341_MADCTL_ML | ILI9341_MADCTL_MV | ILI9341_MADCTL_BGR; //270 degree
		     	break;
		 }
		 writeCmdData8(MD, val); 
	}
 	Set_Addr_Window(0, 0, width - 1, height - 1);
	Vert_Scroll(0, HEIGHT, 0);
	CS_IDLE;
}

//get current rotation
//0  :  0 degree 
//1  :  90 degree
//2  :  180 degree
//3  :  270 degree
uint8_t LCDWIKI_KBV::Get_Rotation(void) const
{
	return rotation;
}

//Anti color display 
void LCDWIKI_KBV::Invert_Display(boolean i)
{
	CS_ACTIVE;
	uint8_t val = VL^i;
	if(lcd_driver == ID_932X)
	{
		writeCmdData8(0x61, val);
	}
	else if(lcd_driver == ID_7575)
	{
		writeCmdData8(0x01, val ? 8 : 10);
	}
	else
	{
		writeCmd8(val ? 0x21 : 0x20);
	}
	CS_IDLE;
}

void LCDWIKI_KBV:: init_table8(const void *table, int16_t size)
{
	uint8_t i;
    uint8_t *p = (uint8_t *) table, dat[MAX_REG_NUM];            //R61526 has GAMMA[22] 
    while (size > 0) 
	{
        uint8_t cmd = pgm_read_byte(p++);
        uint8_t len = pgm_read_byte(p++);
        if (cmd == TFTLCD_DELAY8) 
		{
            delay(len);
            len = 0;
        } 
		else 
		{
            for (i = 0; i < len; i++)
            {
                dat[i] = pgm_read_byte(p++);
            }
			Push_Command(cmd,dat,len);
        }
        size -= len + 2;
    }
}

void LCDWIKI_KBV:: init_table16(const void *table, int16_t size)
{
    uint16_t *p = (uint16_t *) table;
    while (size > 0) 
	{
        uint16_t cmd = pgm_read_word(p++);
        uint16_t d = pgm_read_word(p++);
        if (cmd == TFTLCD_DELAY16)
        {
            delay(d);
        }
        else 
		{
			writeCmdData16(cmd, d);                      //static function
        }
        size -= 2 * sizeof(int16_t);
    }
}

void LCDWIKI_KBV::start(uint16_t ID)
{
	reset();
	delay(200);
	switch(ID)
	{
		case 0x9325:
		case 0x9328:
			lcd_driver = ID_932X;
			//WIDTH = 240,HEIGHT = 320;
			//width = WIDTH, height = HEIGHT;
			XC=0,YC=0,CC=ILI932X_RW_GRAM,RC=ILI932X_RW_GRAM,SC1=ILI932X_GATE_SCAN_CTRL2,SC2=ILI932X_GATE_SCAN_CTRL3,MD=0x0003,VL=1,R24BIT=0;
			static const uint16_t ILI932x_regValues[] PROGMEM = 
			{			
		  		ILI932X_START_OSC 	   , 0x0001, // Start oscillator
		  		TFTLCD_DELAY16			   , 50,	 // 50 millisecond delay
		  		ILI932X_DRIV_OUT_CTRL    , 0x0100,
		  		ILI932X_DRIV_WAV_CTRL    , 0x0700,
		  		ILI932X_ENTRY_MOD 	   , 0x1030,
		  		ILI932X_RESIZE_CTRL	   , 0x0000,
		  		ILI932X_DISP_CTRL2	   , 0x0202,
		  		ILI932X_DISP_CTRL3	   , 0x0000,
		  		ILI932X_DISP_CTRL4	   , 0x0000,
		  		ILI932X_RGB_DISP_IF_CTRL1, 0x0,
		  		ILI932X_FRM_MARKER_POS   , 0x0,
		  		ILI932X_RGB_DISP_IF_CTRL2, 0x0,
		  		ILI932X_POW_CTRL1 	   , 0x0000,
		  		ILI932X_POW_CTRL2 	   , 0x0007,
		  		ILI932X_POW_CTRL3 	   , 0x0000,
		  		ILI932X_POW_CTRL4 	   , 0x0000,
		  		TFTLCD_DELAY16			   , 200,
		  		ILI932X_POW_CTRL1 	   , 0x1690,
		  		ILI932X_POW_CTRL2 	   , 0x0227,
		  		TFTLCD_DELAY16			   , 50,
		  		ILI932X_POW_CTRL3 	   , 0x001A,
		  		TFTLCD_DELAY16			   , 50,
		  		ILI932X_POW_CTRL4 	   , 0x1800,
		  		ILI932X_POW_CTRL7 	   , 0x002A,
		  		TFTLCD_DELAY16			   , 50,
		  		ILI932X_GAMMA_CTRL1	   , 0x0000,
		  		ILI932X_GAMMA_CTRL2	   , 0x0000,
		  		ILI932X_GAMMA_CTRL3	   , 0x0000,
		  		ILI932X_GAMMA_CTRL4	   , 0x0206,
		  		ILI932X_GAMMA_CTRL5	   , 0x0808,
		  		ILI932X_GAMMA_CTRL6	   , 0x0007,
		  		ILI932X_GAMMA_CTRL7	   , 0x0201,
		  		ILI932X_GAMMA_CTRL8	   , 0x0000,
		  		ILI932X_GAMMA_CTRL9	   , 0x0000,
		 		ILI932X_GAMMA_CTRL10	   , 0x0000,
		  		ILI932X_GRAM_HOR_AD	   , 0x0000,
		  		ILI932X_GRAM_VER_AD	   , 0x0000,
		  		ILI932X_HOR_START_AD	   , 0x0000,
		  		ILI932X_HOR_END_AD	   , 0x00EF,
		  		ILI932X_VER_START_AD	   , 0X0000,
		  		ILI932X_VER_END_AD	   , 0x013F,
		  		ILI932X_GATE_SCAN_CTRL1  , 0xA700, // Driver Output Control (R60h)
		  		ILI932X_GATE_SCAN_CTRL2  , 0x0003, // Driver Output Control (R61h)
		  		ILI932X_GATE_SCAN_CTRL3  , 0x0000, // Driver Output Control (R62h)
		  		ILI932X_PANEL_IF_CTRL1   , 0X0010, // Panel Interface Control 1 (R90h)
		  		ILI932X_PANEL_IF_CTRL2   , 0X0000,
		  		ILI932X_PANEL_IF_CTRL3   , 0X0003,
		  		ILI932X_PANEL_IF_CTRL4   , 0X1100,
		  		ILI932X_PANEL_IF_CTRL5   , 0X0000,
		  		ILI932X_PANEL_IF_CTRL6   , 0X0000,
		  		ILI932X_DISP_CTRL1	   , 0x0133 // Main screen turn on		
			};
			init_table16(ILI932x_regValues, sizeof(ILI932x_regValues));
			break;
		case 0x9341:
			lcd_driver = ID_9341;
			//WIDTH = 240,HEIGHT = 320;
			//width = WIDTH, height = HEIGHT;
			XC=ILI9341_COLADDRSET,YC=ILI9341_PAGEADDRSET,CC=ILI9341_MEMORYWRITE,RC=HX8357_RAMRD,SC1=0x33,SC2=0x37,MD=ILI9341_MADCTL,VL=0,R24BIT=1;
			static const uint8_t ILI9341_regValues[] PROGMEM = 
			{        // BOE 2.4"
				ILI9341_SOFTRESET,0,                 //Soft Reset
				TFTLCD_DELAY8, 50, 
				ILI9341_DISPLAYOFF, 0,            //Display Off
            //	ILI9341_PIXELFORMAT, 1, 0x55,      //Pixel read=565, write=565.
            	ILI9341_INTERFACECONTROL, 3, 0x01, 0x01, 0x00,  //Interface Control needs EXTC=1 MV_EOR=0, TM=0, RIM=0
            	ILI9341_POWERCONTROLB, 3, 0x00, 0x81, 0x30,  //Power Control B [00 81 30]
            	ILI9341_POWERONSEQ, 4, 0x64, 0x03, 0x12, 0x81,    //Power On Seq [55 01 23 01]
            	ILI9341_DRIVERTIMINGA, 3, 0x85, 0x10, 0x78,  //Driver Timing A [04 11 7A]
            	ILI9341_POWERCONTROLA, 5, 0x39, 0x2C, 0x00, 0x34, 0x02,      //Power Control A [39 2C 00 34 02]
            	ILI9341_RUMPRATIO, 1, 0x20,      //Pump Ratio [10]
            	ILI9341_DRIVERTIMINGB, 2, 0x00, 0x00,        //Driver Timing B [66 00]
            	ILI9341_RGBSIGNAL, 1, 0x00,      //RGB Signal [00] 
            //	ILI9341_FRAMECONTROL, 2, 0x00, 0x1B,        //Frame Control [00 1B]
            	//            0xB6, 2, 0x0A, 0xA2, 0x27, //Display Function [0A 82 27 XX]    .kbv SS=1  
            	ILI9341_INVERSIONCONRTOL, 1, 0x00,      //Inversion Control [02] .kbv NLA=1, NLB=1, NLC=1
            	ILI9341_POWERCONTROL1, 1, 0x21,      //Power Control 1 [26]
            	ILI9341_POWERCONTROL2, 1, 0x11,      //Power Control 2 [00]
            	ILI9341_VCOMCONTROL1, 2, 0x3F, 0x3C,        //VCOM 1 [31 3C]
            	ILI9341_VCOMCONTROL2, 1, 0xB5,      //VCOM 2 [C0]
            	ILI9341_MEMCONTROL, 1, ILI9341_MADCTL_MY | ILI9341_MADCTL_BGR,
            	ILI9341_PIXELFORMAT, 1, 0x55,      //Pixel read=565, write=565.
            	ILI9341_FRAMECONTROL, 2, 0x00, 0x1B,        //Frame Control [00 1B]
            	ILI9341_MEMORYACCESS, 1, 0x48,      //Memory Access [00]
            	ILI9341_ENABLE3G, 1, 0x00,      //Enable 3G [02]
            	ILI9341_GAMMASET, 1, 0x01,      //Gamma Set [01]
            	ILI9341_UNDEFINE0, 15, 0x0f, 0x26, 0x24, 0x0b, 0x0e, 0x09, 0x54, 0xa8, 0x46, 0x0c, 0x17, 0x09, 0x0f, 0x07, 0x00,
            	ILI9341_UNDEFINE1, 15, 0x00, 0x19, 0x1b, 0x04, 0x10, 0x07, 0x2a, 0x47, 0x39, 0x03, 0x06, 0x06, 0x30, 0x38, 0x0f,
				ILI9341_ENTRYMODE, 1,0x07,
            	ILI9341_SLEEPOUT, 0,            //Sleep Out
            	TFTLCD_DELAY8, 150,
            	ILI9341_DISPLAYON, 0          //Display On
            };
			init_table8(ILI9341_regValues, sizeof(ILI9341_regValues));    
			break;
		case 0x9090:
			lcd_driver = ID_HX8357D;
			//WIDTH = 320,HEIGHT = 480;
			//width = WIDTH, height = HEIGHT;
			XC=ILI9341_COLADDRSET,YC=ILI9341_PAGEADDRSET,CC=HX8357_RAMWR,RC=HX8357_RAMRD,SC1=0x33,SC2=0x37,MD=HX8357_MADCTL,VL=1,R24BIT=1;
			static const uint8_t HX8357D_regValues[] PROGMEM = 
			{
  				HX8357_SWRESET, 0,
  				HX8357D_SETC, 3, 0xFF, 0x83, 0x57,
  				TFTLCD_DELAY8, 250,
				HX8357_SETRGB, 4, 0x00, 0x00, 0x06, 0x06,
				HX8357D_SETCOM, 1, 0x25,  // -1.52V
  				HX8357_SETOSC, 1, 0x68,  // Normal mode 70Hz, Idle mode 55 Hz
  				HX8357_SETPANEL, 1, 0x05,  // BGR, Gate direction swapped
  				HX8357_SETPWR1, 6, 0x00, 0x15, 0x1C, 0x1C, 0x83, 0xAA,
  				HX8357D_SETSTBA, 6, 0x50, 0x50, 0x01, 0x3C, 0x1E, 0x08,
  				// MEME GAMMA HERE
  				HX8357D_SETCYC, 7, 0x02, 0x40, 0x00, 0x2A, 0x2A, 0x0D, 0x78,
  				HX8357_COLMOD, 1, 0x55,
  				HX8357_MADCTL, 1, 0xC0,
  				HX8357_TEON, 1, 0x00,
  				HX8357_TEARLINE, 2, 0x00, 0x02,
  				HX8357_SLPOUT, 0,
  				TFTLCD_DELAY8, 150,
  				HX8357_DISPON, 0, 
  				TFTLCD_DELAY8, 50
			};
			init_table8(HX8357D_regValues, sizeof(HX8357D_regValues));
			break;
		case 0x7575:
		case 0x9595:
			lcd_driver = ID_7575;
			//WIDTH = 240,HEIGHT = 320;
			//width = WIDTH, height = HEIGHT;
			XC=0,YC=0,CC=0x22,RC=ILI932X_RW_GRAM,SC1=0x0E,SC2=0x14,MD=HX8347G_MEMACCESS,VL=1,R24BIT=1;
			static const uint8_t HX8347G_regValues[] PROGMEM = 
			{
				//  0xEA, 2, 0x00, 0x20,        //PTBA[15:0]
               //   0xEC, 2, 0x0C, 0xC4,   //
				  0x2E , 1 , 0x89,
        		  0x29 , 1 , 0x8F,
        		  0x2B , 1 , 0x02,
        		  0xE2 , 1 , 0x00,
        		  0xE4 , 1 , 0x01,
        		  0xE5 , 1 , 0x10,
        		  0xE6 , 1 , 0x01,
        		  0xE7 , 1 , 0x10,
        		  0xE8 , 1 , 0x70,   //0x70
        		  0xF2 , 1 , 0x00,   //0x00
        		  0xEA , 1 , 0x00,
        		  0xEB , 1 , 0x20,
        		  0xEC , 1 , 0x3C,
        		  0xED , 1 , 0xC8,
        		  0xE9 , 1 , 0x38, //0x38
        		  0xF1 , 1 , 0x01,

				 // 0x40, 13, 0x01, 0x00, 0x00, 0x10, 0x0E, 0x24, 0x04, 0x50, 0x02, 0x13, 0x19, 0x19, 0x16,  //
            	  //0x50, 14, 0x1B, 0x31, 0x2F, 0x3F, 0x3F, 0x3E, 0x2F, 0x7B, 0x09, 0x06, 0x06, 0x0C, 0x1D, 0xCC,  //
        
        		  // skip gamma, do later
        
        		  0x1B , 1 , 0x1A,  //0x1A
        		  0x1A , 1 , 0x01,  //0x01
        		  0x24 , 1 , 0x61,  //0x61
        		  0x25 , 1 , 0x5C,  //0x5C
        		  0x23 , 1 , 0x88,
        		  0x18 , 1 , 0x36,  //0x36
        		  0x19 , 1 , 0x01,
        		  0x1F , 1 , 0x88,
        		  TFTLCD_DELAY8 , 5   , // delay 5 ms
        		  0x1F , 1 , 0x80,
        		  TFTLCD_DELAY8   , 5   ,
        		  0x1F , 1 , 0x90,
        		  TFTLCD_DELAY8   , 5   ,
        		  0x1F , 1 , 0xD4,  //0xD4
        		  TFTLCD_DELAY8   , 5   ,
        		  0x17 , 1 , 0x05,
        
        		  0x36 , 1 , 0x00, //0x09
        		  0x28 , 1 , 0x38,
        		  TFTLCD_DELAY8   , 40  ,
        		  0x28 , 1 , 0x3C,  //0x3C
        		  0x02 , 1 , 0x00,
        		  0x03 , 1 , 0x00,
        		  0x04 , 1 , 0x00,
        		  0x05 , 1 , 0xEF,
        		  0x06 , 1 , 0x00,
        		  0x07 , 1 , 0x00,
        		  0x08 , 1 , 0x01,
        		  0x09 , 1 , 0x3F
			};
		    init_table8(HX8347G_regValues, sizeof(HX8347G_regValues));
			break;
		case 0x9486:
			lcd_driver = ID_9486;
			//WIDTH = 320,HEIGHT = 480;
			//width = WIDTH, height = HEIGHT;
			XC=ILI9341_COLADDRSET,YC=ILI9341_PAGEADDRSET,CC=ILI9341_MEMORYWRITE,RC=HX8357_RAMRD,SC1=0x33,SC2=0x37,MD=ILI9341_MADCTL,VL=0,R24BIT=0;
			static const uint8_t ILI9486_regValues[] PROGMEM = 
			{
				0xF1, 6, 0x36, 0x04, 0x00, 0x3C, 0x0F, 0x8F,
				0xF2, 9, 0x18, 0xA3, 0x12, 0x02, 0xB2, 0x12, 0xFF, 0x10, 0x00, 
				0xF8, 2, 0x21, 0x04,
				0xF9, 2, 0x00, 0x08,
				0x36, 1, 0x08, 
				0xB4, 1, 0x00,
				0xC1, 1, 0x41,
				0xC5, 4, 0x00, 0x91, 0x80, 0x00,
				0xE0, 15, 0x0F, 0x1F, 0x1C, 0x0C, 0x0F, 0x08, 0x48, 0x98, 0x37, 0x0A, 0x13, 0x04, 0x11, 0x0D, 0x00,
				0xE1, 15, 0x0F, 0x32, 0x2E, 0x0B, 0x0D, 0x05, 0x47, 0x75, 0x37, 0x06, 0x10 ,0x03, 0x24, 0x20, 0x00,				
				0x3A, 1, 0x55,
				0x11,0,
				0x36, 1, 0x28,
				TFTLCD_DELAY8, 120,
				0x29,0
/*
				0x01, 0,            //Soft Reset
            	TFTLCD_DELAY8, 150,  // .kbv will power up with ONLY reset, sleep out, display on
            	0x28, 0,            //Display Off
            	0x3A, 1, 0x55,      //Pixel read=565, write=565.
            	0xC0, 2, 0x0d, 0x0d,        //Power Control 1 [0E 0E]
            	0xC1, 2, 0x43, 0x00,        //Power Control 2 [43 00]
            	0xC2, 1, 0x00,      //Power Control 3 [33]
            	0xC5, 4, 0x00, 0x48, 0x00, 0x48,    //VCOM  Control 1 [00 40 00 40]
            	0xB4, 1, 0x00,      //Inversion Control [00]
            	0xB6, 3, 0x02, 0x02, 0x3B,  // Display Function Control [02 02 3B] 
            	0xE0, 15,0x0F, 0x24, 0x1C, 0x0A, 0x0F, 0x08, 0x43, 0x88, 0x32, 0x0F, 0x10, 0x06, 0x0F, 0x07, 0x00,
            	0xE1, 15,0x0F, 0x38, 0x30, 0x09, 0x0F, 0x0F, 0x4E, 0x77, 0x3C, 0x07, 0x10, 0x05, 0x23, 0x1B, 0x00,
            	0x11, 0,            //Sleep Out
            	TFTLCD_DELAY8, 150,
            	0x29, 0         //Display On
*/
			};
			init_table8(ILI9486_regValues, sizeof(ILI9486_regValues));
			break;
		case 0x9488:
			lcd_driver = ID_9488;
			//WIDTH = 320,HEIGHT = 480;
			//width = WIDTH, height = HEIGHT;
			XC=ILI9341_COLADDRSET,YC=ILI9341_PAGEADDRSET,CC=ILI9341_MEMORYWRITE,RC=HX8357_RAMRD,SC1=0x33,SC2=0x37,MD=ILI9341_MADCTL,VL=0,R24BIT=1;
			static const uint8_t ILI9488_regValues[] PROGMEM = 
			{
				0xF7, 4, 0xA9, 0x51, 0x2C, 0x82,
				0xC0, 2, 0x11, 0x09,
				0xC1, 1, 0x41,
				0xC5, 3, 0x00, 0x0A, 0x80,
				0xB1, 2, 0xB0, 0x11,
				0xB4, 1, 0x02,
				0xB6, 2, 0x02, 0x22,
				0xB7, 1, 0xC6,
				0xBE, 2, 0x00, 0x04,
				0xE9, 1, 0x00,
				0x36, 1, 0x08,
				0x3A, 1, 0x55,
				0xE0, 15, 0x00, 0x07, 0x10, 0x09, 0x17, 0x0B, 0x41, 0x89, 0x4B, 0x0A, 0x0C, 0x0E, 0x18, 0x1B, 0x0F,
				0xE1, 15, 0x00, 0x17, 0x1A, 0x04, 0x0E, 0x06, 0x2F, 0x45, 0x43, 0x02, 0x0A, 0x09, 0x32, 0x36, 0x0F,
				0x11, 0,
				TFTLCD_DELAY8, 120,
				0x29, 0
			};
			init_table8(ILI9488_regValues, sizeof(ILI9488_regValues));
			break;
		case 0x9481:
			lcd_driver = ID_9481;
			//WIDTH = 320,HEIGHT = 480;
			//width = WIDTH, height = HEIGHT;
			XC=ILI9341_COLADDRSET,YC=ILI9341_PAGEADDRSET,CC=ILI9341_MEMORYWRITE,RC=HX8357_RAMRD,SC1=0x33,SC2=0x37,MD=ILI9341_MADCTL,VL=0,R24BIT=0;
			static const uint8_t ILI9481_regValues[] PROGMEM = 
			{
				0x11, 0,
				TFTLCD_DELAY8, 20,
				0xD0, 3, 0x07, 0x42, 0x18,
				0xD1, 3, 0x00, 0x07, 0x10,
				0xD2, 2, 0x01, 0x02,
				0xC0, 5, 0x10, 0x3B, 0x00, 0x02, 0x11,
				0xC5, 1, 0x03,
				0xC8, 12, 0x00, 0x32, 0x36, 0x45, 0x06, 0x16, 0x37, 0x75, 0x77, 0x54, 0x0C, 0x00,
				0x36, 1, 0x0A,
				0x3A, 1, 0x55,
				0x2A, 4, 0x00, 0x00, 0x01, 0x3F,
				0x2B, 4, 0x00, 0x00, 0x01, 0xE0,
				TFTLCD_DELAY8, 120,
				0x29, 0
			};
			init_table8(ILI9481_regValues, sizeof(ILI9481_regValues));
			break;
		case 0x7735:
			lcd_driver = ID_7735;
			//WIDTH = 128,HEIGHT = 160;
			//width = WIDTH, height = HEIGHT;
			XC=ILI9341_COLADDRSET,YC=ILI9341_PAGEADDRSET,CC=ILI9341_MEMORYWRITE,RC=HX8357_RAMRD,SC1=0x33,SC2=0x37,MD=ILI9341_MADCTL,VL=0,R24BIT=0;
			static const uint8_t ST7735S_regValues[] PROGMEM = 
			{
				0x011, 0,            //Soft Reset
            	TFTLCD_DELAY8, 120,  // .kbv will power up with ONLY reset, sleep out, display on
            	0xB1, 3, 0x05, 0x3C, 0x3C,           //Display Off
            	0xB2, 3, 0x05, 0x3C, 0x3C,      //Pixel read=565, write=565.
            	0xB3, 6, 0x05, 0x3C, 0x3C, 0x05, 0x3C, 0x3C,        //Power Control 1 [0E 0E]
            	0xB4, 1, 0x03,         //Power Control 2 [43 00]
            	0xC0, 3, 0x28, 0x08, 0x04,      //Power Control 3 [33]
            	0xC1, 1, 0xC0,     //VCOM  Control 1 [00 40 00 40]
            	0xC2, 2, 0x0D, 0x00,      //Inversion Control [00]
            	0xC3, 2, 0x8D, 0x2A,   // Display Function Control [02 02 3B]
            	0xC4, 2, 0x8D, 0xEE,
            	0xC5, 1, 0x1A,
            	//0x36, 1, 0xC0,
            	0xE0, 16,0x03, 0x22, 0x07, 0x0A, 0x2E, 0x30, 0x25, 0x2A, 0x28, 0x26, 0x2E, 0x3A, 0x00, 0x01, 0x03, 0x13,
            	0xE1, 16,0x04, 0x16, 0x06, 0x0D, 0x2D, 0x26, 0x23, 0x27, 0x27, 0x25, 0x2D, 0x3B, 0x00, 0x01, 0x04, 0x13,
            	0x3A, 1, 0x05,            //Sleep Out
            	TFTLCD_DELAY8, 150,
            	0x29, 0         //Display On
			};
			init_table8(ST7735S_regValues, sizeof(ST7735S_regValues));
			break;
		case 0x7796:
			lcd_driver = ID_7796;
			//WIDTH = 128,HEIGHT = 160;
			//width = WIDTH, height = HEIGHT;
			XC=ILI9341_COLADDRSET,YC=ILI9341_PAGEADDRSET,CC=ILI9341_MEMORYWRITE,RC=HX8357_RAMRD,SC1=0x33,SC2=0x37,MD=ILI9341_MADCTL,VL=0,R24BIT=0;
			static const uint8_t ST7796S_regValues[] PROGMEM = 
			{
				0xF0, 1, 0xC3,           
            	0xF0, 1, 0x96, 
            	0x36, 1, 0x68, 
            	0x3A, 1, 0x05, 
            	0xB0, 1, 0x80,         
            	0xB6, 2, 0x20, 0x02,
            	0xB5, 4, 0x02, 0x03, 0x00, 0x04, 
            	0xB1, 2, 0x80, 0x10,      
            	0xB4, 1, 0x00, 
            	0xB7, 1, 0xC6, 
            	0xC5, 1, 0x24,
                0xE4, 1, 0x31,
                0xE8, 8, 0x40, 0x8A, 0x00, 0x00, 0x29, 0x19, 0xA5, 0x33,
                0xC2, 0,
                0xA7, 0,
            	0xE0, 14,0xF0, 0x09, 0x13, 0x12, 0x12, 0x2B, 0x3C, 0x44, 0x4B, 0x1B, 0x18, 0x17, 0x1D, 0x21,
            	0xE1, 14,0xF0, 0x09, 0x13, 0x0C, 0x0D, 0x27, 0x3B, 0x44, 0x4D, 0x0B, 0x17, 0x17, 0x1D, 0x21,
            	0x36, 1, 0xEC,
            	0xF0, 1, 0xC3, 
            	0xF0, 1, 0x69,
            	0x13, 0,
            	0x11, 0,
            	0x29, 0 
			};
			init_table8(ST7796S_regValues, sizeof(ST7796S_regValues));
			break;
		default:
			lcd_driver = ID_UNKNOWN;
			break;		
	}
	Set_Rotation(rotation); 
	Invert_Display(false);
}

Update:

the screen data is sent via 8 pins (not a0 to a4), as marked in the rear of the screen.
Can those pins be overclocked?

First, overwrite the area with background color, then rewrite the new data.

Can those pins be overclocked?

Check the display data sheet for the maximum clock rate. Most likely, the Arduino can't come near that, but of course that depends on whatever Arduino you have.

it is a simple arduino uno, the rev3. If i wire the display to an esp32, can that be faster? where can i find where is specified the maximun frequency a gpio pin can change state?

As ESP32 would be much faster, if the display library supports it, and there are options, specific to the ESP32, for outputting digital data faster than the standard digitalWrite() method.

The search phrase "esp32 fast digital write" will find useful tutorials.

Edit: check that the display works with 3.3V logic, required if you use a modern 3.3V processor like the ESP32.

As a last try, i tried changing library to drive the display. i found the MCUFRIEND_kbv library. I then rewritten my "Showscreen" method and the cycle time dropped down to 307.6mS. Hope this is helpful to someone

@Chris2002 - This is valid, but I would re-write the old data in the background color just before writing the new data in the foreground color.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.