Wrong button coordinates from touch screen

I have an OPEN_SMART 3.2" TFT Lcd shield ILI9327 chipset touch screen working fine with a Mega (thanks to @david_prentice ). I have run the calibration test and got the appropriate values for my screen which are in my code.

I have a 4 button display with some text in the centre of the screen. I used the button_simple example code from the MCUFriend examples as my starting point. I am new to programming the Mega but am currently not finding it too difficult as I can code in PHP and to date it seems fairly similar.

The problem I have is that even though the buttons are correctly positioned and displayed on the TFT screen only clicking on 2 of the 4 buttons has the desired effect clicking on one of the non-correct buttons it activates its diagonally opposite button and the other non-correct one does nothing.

I suspect it is my coding that is at fault but I have been at this all day and not getting any further forward. My code is below if anyone has any suggestions they would be most welcome.

#if 1

#include <Adafruit_GFX.h>
#include <MCUFRIEND_kbv.h>
MCUFRIEND_kbv tft;
#include <TouchScreen.h>
#define MINPRESSURE 200
#define MAXPRESSURE 1000

// ALL Touch panels and wiring is DIFFERENT
// copy-paste results from TouchScreen_Calibr_native.ino
const int XP = 6, XM = A2, YP = A1, YM = 7; //ID=0x9327
const int TS_LEFT = 959, TS_RT = 176, TS_TOP = 179, TS_BOT = 913;

TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);

//Define buttons
Adafruit_GFX_Button on_btn, off_btn, up_btn, dwn_btn;

int pixel_x, pixel_y;     //Touch_getXY() updates global vars
bool Touch_getXY(void)
    TSPoint p = ts.getPoint();
    pinMode(YP, OUTPUT);      //restore shared pins
    pinMode(XM, OUTPUT);
    digitalWrite(YP, HIGH);   //because TFT control pins
    digitalWrite(XM, HIGH);
    bool pressed = (p.z > MINPRESSURE && p.z < MAXPRESSURE);
    if (pressed) {
        pixel_x = map(p.x, TS_LEFT, TS_RT, 0, tft.width()); //.kbv makes sense to me
        pixel_y = map(p.y, TS_TOP, TS_BOT, 0, tft.height());
    return pressed;

#define BLACK   0x0000
#define BLUE    0x001F
#define RED     0xF800
#define GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF

void setup(void)
    uint16_t ID = tft.readID();
    Serial.print("TFT ID = 0x");
    Serial.println(ID, HEX);
    Serial.println("Calibrate for your Touch Panel");
    if (ID == 0xD3D3) ID = 0x9486; // write-only shield
    tft.setRotation(1);            //PORTRAIT
    on_btn.initButton(&tft,  350, 50, 100, 100, WHITE, GREEN, BLACK, "ON", 2);
    off_btn.initButton(&tft, 350, 180, 100, 100, WHITE, RED, BLACK, "OFF", 2);
    up_btn.initButton(&tft, 60, 50, 60, 60, WHITE, CYAN, BLACK, "+", 2);
    dwn_btn.initButton(&tft, 60, 190, 60, 60, WHITE, CYAN, BLACK, "-", 2);
    tft.fillRect(140, 60, 120, 20, RED);

void loop(void)

    bool down = Touch_getXY();
    on_btn.press(down && on_btn.contains(pixel_x, pixel_y));
    off_btn.press(down && off_btn.contains(pixel_x, pixel_y));
    up_btn.press(down && up_btn.contains(pixel_x, pixel_y));
    dwn_btn.press(down && dwn_btn.contains(pixel_x, pixel_y));
    if (on_btn.justReleased())
    if (off_btn.justReleased())
    if (up_btn.justReleased())
    if (dwn_btn.justReleased())
    if (on_btn.justPressed()) {
        tft.fillRect(140, 60, 120, 20, GREEN);
    if (off_btn.justPressed()) {
        tft.fillRect(140, 60, 120, 20, RED);
    if (up_btn.justPressed()) {
        tft.fillRect(140, 60, 120, 20, BLUE);
    if (dwn_btn.justPressed()) {
        tft.fillRect(140, 60, 120, 20, MAGENTA);

Run the Touch_shield_new.ino example. (with your Calibration Data)

You should see the ADC values from the TouchScreen library vary with your stylus.
Then press [EXIT]. And you are in a “Paint” screen. The coloured dot should follow the stylus perfectly.

Now edit the rotation e.g.

uint8_t Orientation = 1;    //LANDSCAPE

Run again. The Paint screen should work 100% in Landscape.

Now study the code. You will see that the raw ADC values get mapped according to the rotation.

From memory, you can change the Rotation in button_simple.ino
If I kept it too “simple”, just copy the function from the Touch_shield example.


Thanks but in landscape everything is reversed select Magenta get Red select Red get Magenta so it looks like the calibration is incorrect. I will keep playing

I have just run the Touch_shield_new example with a ILI9340 Shield plugged into a Uno clone.

I entered my calibration:

const int XP=6,XM=A2,YP=A1,YM=7; //240x320 ID=0x9340
const int TS_LEFT=892,TS_RT=135,TS_TOP=98,TS_BOT=933;

and it worked perfectly in all four rotations i.e.
uint8_t Orientation = 1; //try 0, 1, 2, 3

In the Paint screen, draw a horizontal line. then draw a vertical line.

If you get the “wrong” result report back with what the result was e.g.
Orientation = 0, horiz was right to left.



Portrait orientation is perfect in both.

Landscape is incorrect right to left goes left to right but up and down are correct.

Thanks for sticking with this.


I used the regular v2.9.9-Release. Which is what the IDE Library Manager will install / update.

Please check whether you have installed something different.
Mind you, I guess that v2.9.8-Release should be fine too.
Orientation = 0, 1, 2 are fine.
Orientation = 3; //(LANDSCAPE_REV) fails. There is a typo in the case 3: block.

The case 3 failure gives a yellow diagonal trace regardless of where you put the stylus.
Your symptoms are completely different. I suspect that you do not have a proper “Library Manager” installation.



Mine is also 2.9.9. I will see if I can find what the issue is as portrait seems fine.


I strongly advise you to re-install v2.9.9-Release via the IDE Library Manager

If you had manually installed from a suspect location e.g. BangGood, OpenSmart, … leave the IDE. Delete the folder. Start the IDE. Fresh Install via Library Manager.



I did this yesterday on my other thread at your prompting and that got the screen working fine. I will do it again just to make sure but have not changed from your release version.



Re-installed and no different.

In your readme you say:

Edit MCUFRIEND_kbv.cpp:           #define SUPPORT_8352B

Which I have done but is this correct for the ILI9327?

No, you don’t need to support HX8352B. ILI9327 is supported by default.

I don’t have an Open-Smart ILI9327. I do have an Open-Smart HX8352B. I will run the Calibration and the Touch_shield examples with v2.9.9-Release.

Do you want my to test on Uno or on Mega2560?
I am busy with something else at the moment.



Thanks for that I will undo the change.

I am running on a Mega2560.

I tried the v2.9.8 as well as the 2.9.9 installed using library manager without success.

I have re-designed my GUI to be portrait with orientation set to 0 it works fine. With orientation set to 2 the wrong button performs the action (upper buttons perform the lower functions).

With my original GUI the situation is exactly as per my OP with orientation set to 1 or 3.

There is no rush with this as I have lots more programming to do to get the screen to do what I actually want to achieve. So park this until you have some time. I will continue developing in orientation 0 to get the functionality that I want and worry about landscape orientation later.

Thanks for all your help so far


I ran the Calibration on my Open-Smart HX8352B w Mega2560 using v2.9.9-Release

const int XP=6,XM=A2,YP=A1,YM=7; //240x400 ID=0x0065
const int TS_LEFT=922,TS_RT=186,TS_TOP=956,TS_BOT=184;

Then ran the Touch_shield example in all four rotations.
It worked fine.

I used code, examples, … from the v2.9.9-Release.
Seriously. Are you sure that you have not installed from “elsewhere” ? Or have made some top-secret edits ?

Ah-ha. Have you altered Adafruit_Touchscreen code ?
It is wise to downgrade then upgrade in the Library Manager. Then you can be sure that you have a virgin installation.


I can definitely confirm I am using vanilla libraries. I have downgraded and then upgraded using the Library Manager. I have not altered Adafruit_Touchscreen code and to make sure I downgraded and then updated that too.

My numbers are very similar to yours for the const left right etc and are the same for XP etc.

I have re installed my landscape GUI and in orientation 1 top left button performs bottom right function and vice versa.

I have run Touch_Shield_New with my settings for landscape in the const and set the orientation to both 1 and 3 and left and right are reversed. For portrait in both 0 and 2 it works correctly.

It seems that something in Landscape is not quite right with the latest ILI9327 on the board that I have, it was only purchased this week.


Ok. So I tried a regular ILI9327 Shield.

const int XP=7,XM=A1,YP=A2,YM=6; //240x400 ID=0x9327
const int TS_LEFT=126,TS_RT=905,TS_TOP=106,TS_BOT=966;

It is working fine in Landscape. The other rotations all work 100% too.

Please post your build report. This is mine:

Using library Mcufriend_kbv at version 2.9.9-Release in folder: C:\Users\David Prentice\Documents\Arduino\libraries\Mcufriend_kbv 
Using library Adafruit_GFX_Library at version 1.10.7 in folder: C:\Users\David Prentice\Documents\Arduino\libraries\Adafruit_GFX_Library 
Using library Adafruit_TouchScreen at version 1.1.1 in folder: C:\Users\David Prentice\Documents\Arduino\libraries\Adafruit_TouchScreen 
Using library Adafruit_BusIO at version 1.7.3 in folder: C:\Users\David Prentice\Documents\Arduino\libraries\Adafruit_BusIO 
Using library Wire at version 1.0 in folder: C:\Program Files (x86)\Arduino-1.8.13\hardware\arduino\avr\libraries\Wire 
Using library SPI at version 1.0 in folder: C:\Program Files (x86)\Arduino-1.8.13\hardware\arduino\avr\libraries\SPI 
"C:\\Users\\David Prentice\\AppData\\Local\\Arduino15\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-size" -A "C:\\Users\\DAVIDP~1\\AppData\\Local\\Temp\\arduino_build_980015/Touch_shield_new.ino.elf"
Sketch uses 26608 bytes (10%) of program storage space. Maximum is 253952 bytes.
Global variables use 645 bytes (7%) of dynamic memory, leaving 7547 bytes for local variables. Maximum is 8192 bytes.

I suggest that you get on with other things. Perhaps someone else has a problem with Open-Smart or with ILI9327.


This is mine (bear in mind I am on a Mac not a PC)

Using library Adafruit_GFX_Library at version 1.10.7 in folder: /Users/colin/Documents/Arduino/libraries/Adafruit_GFX_Library
Using library MCUFRIEND_kbv at version 2.9.9-Release in folder: /Users/colin/Documents/Arduino/libraries/MCUFRIEND_kbv
Using library Adafruit_TouchScreen at version 1.1.1 in folder: /Users/colin/Documents/Arduino/libraries/Adafruit_TouchScreen
Using library Adafruit_BusIO at version 1.7.3 in folder: /Users/colin/Documents/Arduino/libraries/Adafruit_BusIO
Using library Wire at version 1.0 in folder: /Applications/Arduino.app/Contents/Java/hardware/arduino/avr/libraries/Wire
Using library SPI at version 1.0 in folder: /Applications/Arduino.app/Contents/Java/hardware/arduino/avr/libraries/SPI
/Applications/Arduino.app/Contents/Java/hardware/tools/avr/bin/avr-size -A /var/folders/p0/_wc3mb552d9bvw54l7kskjd80000gn/T/arduino_build_97479/buttons_cs.ino.elf
Sketch uses 22808 bytes (8%) of program storage space. Maximum is 253952 bytes.
Global variables use 610 bytes (7%) of dynamic memory, leaving 7582 bytes for local variables. Maximum is 8192 bytes.


Our versions are identical. I removed the 8352B support and configured for USE_SPECIAL and USE_OPENSMART_SHIELD_PINOUT_MEGA

Sketch uses 24734 bytes (9%) of program storage space. Maximum is 253952 bytes.
Global variables use 644 bytes (7%) of dynamic memory, leaving 7548 bytes for local variables. Maximum is 8192 bytes.

I would expect the exactly the same executable code on Mac as on this Win10-64 PC if you are using v1.8.13 IDE


Yes same version of IDE.

Really odd.