3.5" TFT LCD Shield / screen resolution issue / MCUFRIEND_kbv.h

I purchased a shield with the description 3.5" TFT LCD Shield for Arduino Uno/Mega (ILI9481) recently from here 3.5" TFT LCD Shield for Arduino Uno/Mega (ILI9481) - Elektronik Display LCD Graphik - Boxtec Onlineshop.

It is described as having a resolution of 320x420.

I have used the library MCUFRIEND_kbv.h and it generally appears to work using a sketch based on a supplied example for printing text. The problem is only that the sketch reports a display resolution of 240x320 which differs from the advertised specification.

TFT LCD test
Using Adafruit 2.4" TFT Breakout Board Pinout
TFT size is 240x320
Found ILI9481 LCD driver

(ignore the Adafruit 2.4" TFT line)

The obvious conclusion is that there is an error in the specification from the supplier, but could there be another explanation ? 320x420 is anyway an unusual resolution and I am wondering if I can actually get up to 320x480 which the ILI9481 driver appears to support.

/*


   // mod fdm use <MCUFRIEND_kbv.h> library

   v0.01 initial
   v0.02 rotate screen attempt
   v0.03 change text to match telephone
   v0.04 fonts


   to do  - rassign reset.



*/



// IMPORTANT: Adafruit_TFTLCD LIBRARY MUST BE SPECIFICALLY
// CONFIGURED FOR EITHER THE TFT SHIELD OR THE BREAKOUT BOARD.
// SEE RELEVANT COMMENTS IN Adafruit_TFTLCD.h FOR SETUP.
//Technical support:goodtft@163.com

#include <Adafruit_GFX.h>    // Core graphics library  //fdm
//#include <Adafruit_TFTLCD.h> // Hardware-specific library  //fdm
#include <Fonts/FreeMonoBold18pt7b.h>
#include <Fonts/FreeMonoBold9pt7b.h>

// The control pins for the LCD can be assigned to any digital or
// analog pins...but we'll use the analog pins as this allows us to
// double up the pins with the touch screen (see the TFT paint example).
#define LCD_CS A3 // Chip Select goes to Analog 3
#define LCD_CD A2 // Command/Data goes to Analog 2
#define LCD_WR A1 // LCD Write goes to Analog 1
#define LCD_RD A0 // LCD Read goes to Analog 0

#define LCD_RESET A4 // Can alternately just connect to Arduino's reset pin

// When using the BREAKOUT BOARD only, use these 8 data lines to the LCD:
// For the Arduino Uno, Duemilanove, Diecimila, etc.:
//   D0 connects to digital pin 8  (Notice these are
//   D1 connects to digital pin 9   NOT in order!)
//   D2 connects to digital pin 2
//   D3 connects to digital pin 3
//   D4 connects to digital pin 4
//   D5 connects to digital pin 5
//   D6 connects to digital pin 6
//   D7 connects to digital pin 7
// For the Arduino Mega, use digital pins 22 through 29
// (on the 2-row header at the end of the board).

// Assign human-readable names to some common 16-bit color values:
#define  BLACK   0x0000
#define BLUE    0x001F
#define RED     0xF800
#define GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF

unsigned int colour[] = { GREEN, CYAN, MAGENTA, YELLOW, WHITE} ;
byte colours = sizeof ( colour )  / sizeof ( colour[0] )  ;
byte currentColour = 0 ;

unsigned int bg = BLACK ;


//fdm - use MCUFriend
#include <MCUFRIEND_kbv.h>
MCUFRIEND_kbv tft;
// Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);
// If using the shield, all control and data lines are fixed, and
// a simpler declaration can optionally be used:
// Adafruit_TFTLCD tft;  //(fdm)

void setup(void) {
  Serial.begin(9600);
  Serial.println(F("TFT LCD test"));

#ifdef USE_ADAFRUIT_SHIELD_PINOUT
  Serial.println(F("Using Adafruit 2.4\" TFT Arduino Shield Pinout"));
#else
  Serial.println(F("Using Adafruit 2.4\" TFT Breakout Board Pinout"));
#endif

  Serial.print("TFT size is "); Serial.print(tft.width()); Serial.print("x"); Serial.println(tft.height());

  tft.reset();

  uint16_t identifier = tft.readID();
  if (identifier == 0x0101)
    identifier = 0x9341;

  if (identifier == 0x9325) {
    Serial.println(F("Found ILI9325 LCD driver"));
  } else if (identifier == 0x4535) {
    Serial.println(F("Found LGDP4535 LCD driver"));
  } else if (identifier == 0x9328) {
    Serial.println(F("Found ILI9328 LCD driver"));
  } else if (identifier == 0x7575) {
    Serial.println(F("Found HX8347G LCD driver"));
  } else if (identifier == 0x9341) {
    Serial.println(F("Found ILI9341 LCD driver"));
  } else if (identifier == 0x8357) {
    Serial.println(F("Found HX8357D LCD driver"));
  } else if (identifier == 0x9481) {
    Serial.println(F("Found ILI9481 LCD driver"));
  }
  else {
    Serial.print(F("Unknown LCD driver chip: "));
    Serial.println(identifier, HEX);
    Serial.println(F("If using the Adafruit 2.4\" TFT Arduino shield, the line:"));
    Serial.println(F("  #define USE_ADAFRUIT_SHIELD_PINOUT"));
    Serial.println(F("should appear in the library header (Adafruit_TFT.h)."));
    Serial.println(F("If using the breakout board, it should NOT be #defined!"));
    Serial.println(F("Also if using the breakout, double-check that all wiring"));
    Serial.println(F("matches the tutorial."));
    return;
  }




  tft.begin(identifier);
 

}

void loop(void) {
  tft.fillScreen( bg );  // fdm
  unsigned long start = micros();
  
  tft.setRotation(1) ; // fdm
  tft.setCursor(0, 50);

 
  //tft.setFont();
  //tft.setTextColor( colour[currentColour] );    tft.setTextSize(1);
  //tft.println(".") ;
   tft.setFont(&FreeMonoBold18pt7b);
  tft.setTextColor( colour[currentColour] );    tft.setTextSize(2);
  tft.println("079") ;
  tft.println("123 4567");
  //tft.println("") ;
  tft.setFont(&FreeMonoBold9pt7b);
  tft.setTextColor(colour[currentColour]);    tft.setTextSize(2);
  tft.println("John Smith & Co.");
  tft.println("... but up to 50 ch") ;
  tft.setTextColor(colour[currentColour]);    tft.setTextSize(2);
  tft.println("22.06.2017 18:25");
  // tft.println();
  // tft.println();

  

  currentColour ++ ;
  if ( currentColour == colours )  {
    currentColour = 0 ;
   // if ( bg == BLACK ) bg = WHITE ;
    // else bg = BLACK ;

  }


  delay(1000); delay(1000); delay(1000); delay(1000); delay(1000);
}

And here is the output from the Read Registers utility:

Read Registers on MCUFRIEND UNO shield
controllers either read as single 16-bit
e.g. the ID is at readReg(0)
or as a sequence of 8-bit values
in special locations (first is dummy)

reg(0x0000) 00 00	ID: ILI9320, ILI9325, ILI9335, ...
reg(0x0004) 00 00 00 00	Manufacturer ID
reg(0x0009) 00 00 00 00 00	Status Register
reg(0x000A) 00 08	Get Power Mode
reg(0x000C) 00 66	Get Pixel Format
reg(0x0061) 00 00	RDID1 HX8347-G
reg(0x0062) 00 00	RDID2 HX8347-G
reg(0x0063) 00 00	RDID3 HX8347-G
reg(0x0064) 00 00	RDID1 HX8347-A
reg(0x0065) 00 00	RDID2 HX8347-A
reg(0x0066) 00 00	RDID3 HX8347-A
reg(0x0067) 00 00	RDID Himax HX8347-A
reg(0x0070) 00 00	Panel Himax HX8347-A
reg(0x00A1) 00 00 00 00 00	RD_DDB SSD1963
reg(0x00B0) 00 00	RGB Interface Signal Control
reg(0x00B4) 00 00	Inversion Control
reg(0x00B6) 00 00 00 00 00	Display Control
reg(0x00B7) 00 00	Entry Mode Set
reg(0x00BF) 00 02 04 94 81 FF	ILI9481, HX8357-B
reg(0x00C0) 00 10 3B 00 02 11 00 00 00	Panel Control
reg(0x00C8) 00 00 00 00 00 00 00 00 00 00 00 00 00	GAMMA
reg(0x00CC) 00 00	Panel Control
reg(0x00D0) 00 00 43	Power Control
reg(0x00D2) 00 01 22 00 00	NVM Read
reg(0x00D3) 00 01 22 00	ILI9341, ILI9488
reg(0x00D4) 00 01 22 00	Novatek ID
reg(0x00DA) 00 00	RDID1
reg(0x00DB) 00 00	RDID2
reg(0x00DC) 00 00	RDID3
reg(0x00E0) 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00	GAMMA-P
reg(0x00E1) 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00	GAMMA-N
reg(0x00EF) 00 00 00 00 00 00	ILI9327
reg(0x00F2) 00 00 33 00 00 00 00 00 00 00 00 00	Adjust Control 2
reg(0x00F6) 00 80 80 80	Interface Control

Your Blue display has a genuine ILI9481 and resolution 320x480.

It should work just fine with MCUFRIEND_kbv library. You can install this via the Library Manager. (current Release is v2.9.6)

These particular screens are liable to overheat. Feel the glass with your wrist. Warm is ok. Hot is bad.

The display might work for days with no problem. Or it might overheat within a few minutes.

If you have a question about one of the examples from the ZIP in your link, please explain which example, which library. (It looks as if they have hacked the Adafruit_TFTLCD libray.)

David.

Many thanks for looking. Maybe I didn’t express myself very clearly.
I hacked the example sketch “DisplayString.ino” in that zip file to use the MCUFRIEND_kbv library to get it to work (based on another example I found). I left the relics of the Adafruit_TFTLCD library (commented out) in post #1, together with the unusual location of the library include statement, which may have caused confusion.

It works. The problem is only the display resolution reported.

This code snippet reports a resolution of only 240x320. I expected a higher resolution.

#include <MCUFRIEND_kbv.h>
MCUFRIEND_kbv tft;
. . .
Serial.print("TFT size is "); Serial.print(tft.width()); Serial.print("x"); Serial.println(tft.height());

Post a more representative snippet. i.e. the readID() , begin(ID) sequence.

Surely my examples all work with 320x480. I have never tried their hacked Adafruit_TFTLCD library.

David.

OK. I cleaned out all the Adafruit library relics and loaded a fresh version of the original Adafruit_GFX_Library . There are no hacked library bits around anymore.
I trimmed the example script I was using to eliminate all relics. It is here:

/*

   v0.01 initial
   v0.02 rotate screen attempt
   v0.03 change text to match telephone
   v0.04 fonts
   v0.05 move reset from A4 to D13 to preparce for I2C


*/
#include <MCUFRIEND_kbv.h>
MCUFRIEND_kbv tft;

#include <Fonts/FreeMonoBold18pt7b.h>
#include <Fonts/FreeMonoBold9pt7b.h>

// The control pins for the LCD can be assigned to any digital or
// analog pins...but we'll use the analog pins as this allows us to
// double up the pins with the touch screen (see the TFT paint example).
#define LCD_CS A3 // Chip Select goes to Analog 3
#define LCD_CD A2 // Command/Data goes to Analog 2
#define LCD_WR A1 // LCD Write goes to Analog 1
#define LCD_RD A0 // LCD Read goes to Analog 0

#define LCD_RESET A4 // Can alternately just connect to Arduino's reset pin

// When using the BREAKOUT BOARD only, use these 8 data lines to the LCD:
// For the Arduino Uno, Duemilanove, Diecimila, etc.:
//   D0 connects to digital pin 8  (Notice these are
//   D1 connects to digital pin 9   NOT in order!)
//   D2 connects to digital pin 2
//   D3 connects to digital pin 3
//   D4 connects to digital pin 4
//   D5 connects to digital pin 5
//   D6 connects to digital pin 6
//   D7 connects to digital pin 7
// For the Arduino Mega, use digital pins 22 through 29
// (on the 2-row header at the end of the board).

// Assign human-readable names to some common 16-bit color values:
#define  BLACK   0x0000
#define BLUE    0x001F
#define RED     0xF800
#define GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF

unsigned int colour[] = { GREEN, CYAN, MAGENTA, YELLOW, WHITE} ;
byte colours = sizeof ( colour )  / sizeof ( colour[0] )  ;
byte currentColour = 0 ;

unsigned int bg = BLACK ;


void setup(void) {
  Serial.begin(9600);
  Serial.println(F("TFT LCD test"));

  Serial.print("TFT size is "); Serial.print(tft.width()); Serial.print("x"); Serial.println(tft.height());

  tft.reset();

  uint16_t identifier = tft.readID();
  if (identifier == 0x0101)
    identifier = 0x9341;

  if (identifier == 0x9325) {
    Serial.println(F("Found ILI9325 LCD driver"));
  } else if (identifier == 0x4535) {
    Serial.println(F("Found LGDP4535 LCD driver"));
  } else if (identifier == 0x9328) {
    Serial.println(F("Found ILI9328 LCD driver"));
  } else if (identifier == 0x7575) {
    Serial.println(F("Found HX8347G LCD driver"));
  } else if (identifier == 0x9341) {
    Serial.println(F("Found ILI9341 LCD driver"));
  } else if (identifier == 0x8357) {
    Serial.println(F("Found HX8357D LCD driver"));
  } else if (identifier == 0x9481) {
    Serial.println(F("Found ILI9481 LCD driver"));
  }
  else {
    Serial.print(F("Unknown LCD driver chip: "));
    Serial.println(identifier, HEX);
   
    return;
  }

  tft.begin(identifier);
  Serial.print("TFT size2 is "); Serial.print(tft.width()); Serial.print("x"); Serial.println(tft.height());

 
}

void loop(void) {
  tft.fillScreen( bg );   
  unsigned long start = micros();
  
  tft.setRotation(1) ;  
  tft.setCursor(0, 50);

   tft.setFont(&FreeMonoBold18pt7b);
  tft.setTextColor( colour[currentColour] );    tft.setTextSize(2);
  tft.println("079") ;
  tft.println("123 4567");
 
  tft.setFont(&FreeMonoBold9pt7b);
  tft.setTextColor(colour[currentColour]);    tft.setTextSize(2);
  tft.println("Mr. John Smith");
  tft.println("... but up to 50 ch") ;
  tft.setTextColor(colour[currentColour]);    tft.setTextSize(2);
  tft.println("22.06.2017 18:25");
 

  currentColour ++ ;
  if ( currentColour == colours )  {
    currentColour = 0 ;
  }

  delay(5000); 
}

I now see the problem which caused the false reporting of the screen resolution. The example sketch printed the screen resolution before the call tft.begin( ID ) and got a smaller default resolution back.
If the the resolution is referenced after that call, the screen resolution is reported correctly.
I guess I am just learning the relationship between your library and the Adafruit_GFX Library.

The output of the above script is, incidentally, here:

TFT LCD test
TFT size is 240x320
Found ILI9481 LCD driver
TFT size2 is 320x480

My next task is to move the screen reset pin from A4 to D13 so I can use I2C to drive the Arduino which is hosting the display. Can I do this without hacking libraries ?

Just snip the LCD_RST pin. And solder a 10k pullup from the remaining stub to 5V.

Easy on a 2.4". You can access the top of the snipped pin. On your 3.5" you can snip through both the LCD_RST and the adjacent unused A5 pin together with the plastic. This will let you solder the resistor to the stub.

Access the I2C pins on the D13 header.

Call tft.begin() before Wire.begin()

If you really want to use D13 as RST, you can not use the microSD. And you need to write your own SPECIAL.

David.

OK. Thanks. It is happy with the pullup resistor. Fortunately, I am using jumpers and have not actually plugged the shield into the arduino so there is no problem about cutting pins and soldering etc., at least not yet.

To attempt to stop the library interfering with pin A4 and disrupt the I2C communication, I used a constructor:

MCUFRIEND_kbv tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);

This compiled. I gave the LCD_RESET a value of (pin) 13 which I am not using because I don't intend to use the SD card.

However, this was not successful. Pin A4 appears still to be held high leaving it unusable, so I guess there is some hard coded definition somewhere.

The constructor arguments are all dummies.

The A4 pin is always driven as OUTPUT_HIGH by the tft.reset() and the tft.begin() methods.

But this is only ever called once in setup(). None of the other methods touch the TFT_RST. So a subsequent Wire.begin() will reconfigure A4 as OPEN_DRAIN. And your I2C bus should be fine.

David.

Hello! David. Can you help me, please? I'm using a kvb library and 4.64" LCD with 272x480 resolution. A test is not write in memory approximately 24pix. If I set the resolution to 320x 480, the test displayed at a center of LCD but not fit in full size. Chip in a display is RM68140. Thanks)))

I suspect that you have to add 24 to the X coordinate in Portrait mode.
Easy enough for drawing graphics, setCursor() etc.

Not much good for println() because it jumps to X=0 with each linefeed.

The library defaults to 320x480 for a RM68140.
Run the diagnose_TFT_support example.

Please tell me where the rectangles appear on the screen.

David.

The rectangles appear in the center of the screen if 320x480. If 272x480 to rectangles offset left in portrait to 24px and from the right side not write to the memory of screen noise bandwidth 24px. Sorry.

I upload a photo to my onedrive. https://1drv.ms/u/s!Auw_kkqM7FlpnRQFE-cVXViEt55b https://1drv.ms/u/s!Auw_kkqM7FlpnRMj7LXYMw01OH_A

https://forum.arduino.cc/index.php?topic=366304.735 He is not alone)))) How I may help you?

I have "visible 272x480 area from a virtual 320x480 panel" and RM68140 LCD. 0x0 is not in a visible area.

Maybe CASET (2Ah): Column Address Set and RASET (2Bh): Row Address Set

Or PTLAR (30h): Partial Area ))))

I gave a fairly comprehensive answer in this message You can follow the conversation with leonardojc.

I don't really want to compensate for the 24 pixel offset in the library. I note that you are running the Beta and not the regular Release from the Library Manager.

I could create a Branch for you to test. But I will only do this if you provide accurate feedback. For example. I asked for the result from diagnose_TFT_controller.ino with the default 320x480 RM68140. You chose to send photos of 272x480 i.e. you have altered the library.

David.

Sorry. I returned to default the library. At the link, https://1drv.ms/f/s!Auw_kkqM7FlpnHBVZ8vVudivBJZF can you see photos with 320x480. I give you true feedback as possible. Thanks)

In mcufriend_kvb.h I use #define USE_SPECIAL in mcufriend_special.h I use #define USE_MEGA_8BIT_SHIELD I have arduino DUE pcb.

I have posted a Branch called test_272x480 on GitHub.

If you have Forked, it is just a change Branch. If you have installed from ZIP, leave IDE, delete old library directory. start IDE, select Branch, download ZIP, install from ZIP

You must enable your SPECIAL macros.

Please test it on the examples.

David.

Thanks, David!! OK. It works)) https://1drv.ms/f/s!Auw_kkqM7FlpnHBVZ8vVudivBJZF Thank you very much))) RM68140 272x480 ARDUINO DUE