Problems with library TouchScreen_Calibr_native using 3.95"TFT / 16Bit MEGA2560

Hi, I am new here but have read many of the posts concerning ST7796S controller display which I am trying to use with an Arduino Mega 2560 R3. Here is an image of the 3.95" TFT and the AtMega 2560:

On the TFT I have shorted R5 and removed R4 thus using 16 Bits.

Thanks to all the posts on this forum I have managed to get most of the libraries working properly by forcing ID=0x7796. The issue I have is when I try to use the touch screen libraries of MCUFRIEND_kbv-2.9.9 (button_simple and TouchScreen_Calibr_native).

For button_simple I get the graphics on the screen but nothing happens when I press the buttons.

For TouchScreen_Calibr_native I get the following on the serial monitor.
TouchScreen.h GFX Calibration
Making all control and bus pins INPUT_PULLUP
Typical 30k Analog pullup with corresponding pin
would read low when digital is written LOW
e.g. reads ~25 for 300R X direction
e.g. reads ~30 for 500R Y direction

ID = 0x7796

And I get the following on the TFT display.
Touch Calibration FAILED
Unable to read the position
of the press. This is a
hardware issue and can not
be corrected in software.
check XP, XM pins with a multimeter
check YP, YM pins with a multimeter
should be about 300 ohms

What pins exactly on the AtMega should I be testing with my MM?

From the posts I read, I tried the following changes in the code of TouchScreen_Calibr_native.ino
Last 2 lines (int XP..... and int TS_LEFT.....).

#define PORTRAIT 0
#define LANDSCAPE 1
#define USE_XPT2046 0
#define USE_LOCAL_KBV 1


#if defined(USB_PID) && USB_PID == 0x804E // Arduino M0 Native
#define Serial SerialUSB

#define SWAP(x, y) { int t = x; x = y; y = t; }

#define TITLE "TouchScreen.h GFX Calibration"
#include <Adafruit_GFX.h>
#include <MCUFRIEND_kbv.h>
MCUFRIEND_kbv tft;

// MCUFRIEND UNO shield shares pins with the TFT.
#if defined(ESP32)
int XP = 27, YP = 4, XM = 15, YM = 14; //most common configuration
int XP = 8, XM = 56, YP = 57, YM =9 ; //320x480 ID=0x7796, XM=A2=56, YP=A3=57
int TS_LEFT = 924, TS_RT = 127, TS_TOP = 59, TS_BOT = 931;

I also forced the id after tft.readID() with:
if (ID == 0xD3D3) ID = 0x7796;

Not sure if this helps. When I run the library LCD_ID_readnew I get the following Serial print:

diagnose any controller
reg(0x0000) 00 00 ID: ILI9320, ILI9325, ILI9335, ...
reg(0x0004) 04 04 04 04 Manufacturer ID
reg(0x0009) 09 09 09 09 09 Status Register
reg(0x000A) 0A 0A Get Power Mode
reg(0x000C) 0C 0C Get Pixel Format
reg(0x0030) 30 30 30 30 30 PTLAR
reg(0x0033) 33 33 33 33 33 33 33 VSCRLDEF
reg(0x0061) 61 61 RDID1 HX8347-G
reg(0x0062) 62 62 RDID2 HX8347-G
reg(0x0063) 63 63 RDID3 HX8347-G
reg(0x0064) 64 64 RDID1 HX8347-A
reg(0x0065) 65 65 RDID2 HX8347-A
reg(0x0066) 66 66 RDID3 HX8347-A
reg(0x0067) 67 67 RDID Himax HX8347-A
reg(0x0070) 70 70 Panel Himax HX8347-A
reg(0x00A1) A1 A1 A1 A1 A1 RD_DDB SSD1963
reg(0x00B0) B0 B0 RGB Interface Signal Control
reg(0x00B3) B3 B3 B3 B3 B3 Frame Memory
reg(0x00B4) B4 B4 Frame Mode
reg(0x00B6) B6 B6 B6 B6 B6 Display Control
reg(0x00B7) B7 B7 Entry Mode Set
reg(0x00BF) BF BF BF BF BF BF ILI9481, HX8357-B
reg(0x00C0) C0 C0 C0 C0 C0 C0 C0 C0 C0 Panel Control
reg(0x00C1) C1 C1 C1 C1 Display Timing
reg(0x00C5) C5 C5 Frame Rate
reg(0x00C8) C8 C8 C8 C8 C8 C8 C8 C8 C8 C8 C8 C8 C8 GAMMA
reg(0x00CC) CC CC Panel Control
reg(0x00D0) D0 D0 D0 D0 Power Control
reg(0x00D1) D1 D1 D1 D1 VCOM Control
reg(0x00D2) D2 D2 D2 Power Normal
reg(0x00D3) D3 D3 D3 D3 ILI9341, ILI9488
reg(0x00D4) D4 D4 D4 D4 Novatek
reg(0x00DA) DA DA RDID1
reg(0x00DB) DB DB RDID2
reg(0x00DC) DC DC RDID3
reg(0x00E0) E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 GAMMA-P
reg(0x00E1) E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 E1 GAMMA-N
reg(0x00EF) EF EF EF EF EF EF ILI9327
reg(0x00F2) F2 F2 F2 F2 F2 F2 F2 F2 F2 F2 F2 F2 Adjust Control 2
reg(0x00F6) F6 F6 F6 F6 Interface Control

I hope the provided info helps. Please let me know anything else I can do.

That display is write-only. It has an XPT2046 Touch controller chip.
The regular Uno Shields can read registers, GRAM etc. They have a bare Resistive Touchscreen with no controller.

So no only do you have to use a special USE_MEGA_16BIT_SHIELD
but you have to use XPT2046_Touchscreen library.


Please read the first topic telling how to use this forum, how to get the best of it.

Word sallad never replaces technical data. Post code, not links to code, not snippets of code, schematics, links to none standard devices.

What works and what doesn't?
Don't make a mix of everything.
What clear hardware issues are there?
What software issues, wanted versus real result...

I strongly disagree.

The OP provided clear pictures of hardware. (I prefer links to sale site)
The OP described his hardware and software mods.

The OP described his problem. And provided Serial output too.

Ok, he had not realised that this display is write-only. (They designed it wrong)

So +1 to the OP for his question.

Post code, not links to code, not snippets of code,

I always prefer buildable code to snippets. But when you have a problem with a "library example" it is best to quote the "example name" and only describe and copy-paste "your changes":
e.g. pin #defines
e.g. constructor() statements


You are really one of the kind.

Hi David, thanks for your quick reply.

I did modify the file mcufriend_special.h to use only the macro USE_MEGA_16BIT_SHIELD.
I will do some reading about the XPT2046_Touchscreen library and see if I can get it working.


Hi David, I downloaded both "XPT2046_Touchscreen" and "XPT2046_Calibrated" libraries.

I got the "XPT2046_Touchscreen" library example "TouchTest" to work after I changed the CS_PIN and TIRQ_PIN:

#define CS_PIN 8
#define TIRQ_PIN 2

#define CS_PIN 53
#define TIRQ_PIN 255

The Serial Monitor gives me various readings as I move my stylus, as below.

Pressure = 1078, x = 896, y = 932
Pressure = 2430, x = 835, y = 1081
Pressure = 2494, x = 922, y = 1171
Pressure = 2450, x = 1115, y = 1258
Pressure = 2463, x = 1374, y = 1401
Pressure = 2475, x = 1613, y = 1619
Pressure = 2435, x = 1817, y = 1895
Pressure = 2374, x = 2138, y = 2281
Pressure = 2310, x = 2541, y = 2648
Pressure = 2185, x = 2866, y = 2956
Pressure = 2163, x = 3019, y = 3174
Pressure = 2325, x = 3018, y = 3225
Pressure = 2011, x = 3019, y = 3171

My next step was to calibrate my screen using the example "TouchCalibration" from the "XPT2046_Calibrated" library.

As before I modified the CS_PIN.
#define CS_PIN 53

And I forced the ID = 0x7796.

I have mixed results.
The screen is white and I see no cross-hairs. Something is clearly not working here.

However, when I touch the screen in different places I get the following from the Serial Monitor:

Not possible to diagnose Touch pins on ARM or ESP32
ID = 0x7796

cx=3688 cy=626 cz=300 X, Y, Pressure
cx=3748 cy=3634 cz=300 X, Y, Pressure
cx=2021 cy=453 cz=300 X, Y, Pressure
cx=2108 cy=3555 cz=300 X, Y, Pressure
cx=495 cy=549 cz=300 X, Y, Pressure
cx=415 cy=3588 cz=300 X, Y, Pressure
cx=1778 cy=2306 cz=300 X, Y, Pressure
cx=2601 cy=2257 cz=300 X, Y, Pressure

*** COPY-PASTE from Serial Terminal:
const int TS_LANDSCAPE=1; //XPT2046_TouchScreen.h
const int TS_LEFT=1518,TS_RT=2769,TS_TOP=2082,TS_BOT=1692;

x = map(p.x, LEFT=1518, RT=2769, 0, 240)
y = map(p.y, TOP=2082, BOT=1692, 0, 320)

x = map(p.y, LEFT=2082, RT=1692, 0, 320)
y = map(p.x, TOP=2769, BOT=1518, 0, 240)


Any idea what I am missing to get both the display and touchscreen to work simultaneously (my display is 320x480)?

No need to reply David.
I found another post " ST7796S 16bit speed" where you helped out someone else and got my calibration to finally work.