TFT Screen Button Mapping Problem

Hi guys, forgive me if this is a simple problem,

I’m trying to create an interface with buttons leading to various pages, I’ve fallen at the first hurdle and the location of my button isn’t playing ball with where I’ve located it, I even added a rectangle of the required coordinates after the press to show where the region was,

so in a nutshell I have a button at the bottom of the screen and it only moves to the next page when I press around the left of the screen, I have no idea why it’s not working as I’ve followed numerous tutorials on this and my code looks no different to everyone else’s, please see attached,

EDIT: I think it’s a rotation problem as it seems the ‘imaginary’ button it’s using is rotated 90 degrees on the left side, not sure what the correction to this is however

#include <Elegoo_GFX.h>    // Core graphics library
#include <Elegoo_TFTLCD.h> // Hardware-specific library
#include <TouchScreen.h>

#define LCD_CS A3 
#define LCD_CD A2 
#define LCD_WR A1 
#define LCD_RD A0 
#define LCD_RESET A4 

#define TS_MINX 123
#define TS_MINY 133
#define TS_MAXX 938
#define TS_MAXY 880

#define YP A3
#define XM A2
#define YM 9
#define XP 8

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

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

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

boolean buttonEnabled = true;
int CurrentPage = 0;

void DrawHome()
{

  CurrentPage == 0;
  tft.fillScreen(WHITE);
  tft.drawRect(0,0,320,240,BLACK);
  
  tft.setCursor(30,40);
  tft.setTextColor(BLACK);
  tft.setTextSize(2);
  tft.print("  Automatic Drilling");
  
  tft.setCursor(30,80);
  tft.setTextColor(BLACK);
  tft.setTextSize(2);
  tft.print(" Press Start to Begin");
    
  tft.fillRect(105,180, 95, 40, RED);
  tft.drawRect(105,180,95,40,BLACK);
  tft.setCursor(120,190);
  tft.setTextColor(WHITE);
  tft.setTextSize(2);
  tft.print("Start");

}


void setup() 
{
  
  tft.reset();
  uint16_t identifier = tft.readID();
  tft.begin(0x9341);
  tft.setRotation(1);
DrawHome();

}


void loop() {
  TSPoint p = ts.getPoint();

if (CurrentPage == 0);
{
 /* if (p.z > 100) {*/
   
   p.x = map(p.x, TS_MINX, TS_MAXX, 0, 320);
   p.y = map(p.y, TS_MINY, TS_MAXY, 0, 240);
      
   if(p.x>106 && p.x<202 && p.y>187 && p.y<227 /*&& buttonEnabled */){
    
   // buttonEnabled = false;
    
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);


    
    tft.fillScreen(WHITE);
    tft.drawRect(0,0,320,240,YELLOW);
    tft.drawRect(106, 187, 96, 40, BLACK);
    /*tft.setCursor(50,70);
    tft.setTextColor(BLACK);
    tft.setTextSize(3);
    tft.print(" Test");*/
   }  
  }
  }
if (CurrentPage == 0);

It is extremely unusual to see a properly written if statement end in a semicolon.

   p.x = map(p.x, TS_MINX, TS_MAXX, 0, 320);
   p.y = map(p.y, TS_MINY, TS_MAXY, 0, 240);

Do you have a clue what p.x and p.y are before and after mapping? We certainly don't.

Hi Paul,

I used code to print p.x and p.y of where I was touching, I pressed the top left and bottom right of the button giving the following values,

Top left: p.x 106, p.y 187
Bottom right: p.x 202, p.y 227

hope this is of some use

I used code to print p.x and p.y of where I was touching

Before or after mapping?

Paul,

this is after mapping,

before mapping they follow the same sort of premise but with regard to the values relative to TS_MIN/MAX x,y

Hi Smiteh --

Apart from the conditionals typo that PaulS already mentioned, here are a couple other comments:

  • It didn't seem like your code was confirming the touch pressure (ie. p.z)
  • If you are seeing the results Top left: p.x 106, p.y 187 & Bottom right: p.x 202, p.y 227 after the map() when touching the corners of the button, then it sounds like your calibration values might be OK, since those appear to match your button's screen coordinates (though your comments seem to suggest otherwise).
  • There are many variations in how these analog touch overlays can be oriented versus the display. From the problem you describe, it sounds like your map() function could be problematic.
  • The touch map() function can perform combinations of four types of adjustments: calibrating the touch positioning/scale, flipping the X axis, flipping the Y axis and swapping X & Y axes.
  • If you use tft.setRotation(), then the touch remapping would need to be changed.

My guess is that you might need to swap your X & Y axes or flip one or more axes.

First, I would adjust your getPoint() to use a temporary variable so that you can more easily perform an XY swap:

// No swap/flip
TSPoint p_raw = ts.getPoint();
p.x = map(p_raw.x, TS_MINX, TS_MAXX, 0, 320);
p.y = map(p_raw.y, TS_MINY, TS_MAXY, 0, 240);

You might then find that one of the combinations of swapXY, flipX, flipY matches your touch to your display: (NOTE: this should really be done by a proper calibration routine... I'm just intending to give you a quick idea of what orientation might be correct for your hardware):

// SwapXY
TSPoint p_raw = ts.getPoint();
p.x = map(p_raw.y, TS_MINY, TS_MAXY, 0, 320);
p.y = map(p_raw.x, TS_MINX, TS_MAXX, 0, 240);

// OR FlipX
TSPoint p_raw = ts.getPoint();
p.x = map(p_raw.x, TS_MAXX, TS_MINX, 0, 320);
p.y = map(p_raw.y, TS_MINY, TS_MAXY, 0, 240);

// OR ... similarly for FlipY, SwapXY + FlipX, etc.

It will be much easier to see what is happening by adding in a visible marker that shows where your touch presses are being detected versus the screen coordinates. I would add something like the following into your loop: (after detecting a press)

tft.drawRect(p.x-1,p.y-1,2,2,YELLOW);