Programming touchscreen to map x,y coordinates in landscape Mode

Hello,

I am fairly new to programming the arduino and have tried to look on the forum, watch youtube videos, and change lines of code one by one to try to fix the issue. I have spent hours trying to figure this out and I can't.

I am using a Elegoo 2560 board
touchscreen is a Elegoo 2.8" TFT with 0x9341 LCD driver

I am having a problem mapping touch (x,y) coordinates when the touchscreen is in landscape mode (setrotation (1)).

I want to create a button in landscape mode which I can get the button displayed but because I rotated the screen my button (x,y) coordinates do not match with the LCD button coordinates. I have tried swapping p.x and p.y in the mapping code and a bunch of other things, all which have not changed the problem.

My code has the LCD screen displaying (0,0) at the top left of the screen for
(setrotation(1))

Second, what is the mapping code to have x left to right and y top to bottom while in landscape mode?

currently:
top left (x,y) = (0,240)
top right (x,y) = (0,0)
bottom left (x,y) = (320,240)
bottom right (x,y) = (320,0)

What I want:

top left (x,y) = (0,0)
top right (x,y) = (320,0)
bottom left (x,y) = (0,240)
bottom right (x,y) = (320,240)

summary: I am trying to get display coordinates to equal touch coordinates even though the LCD screen has been rotated while touch part does not rotate.

This code I posted below is to see if my x and y LCD and my x and y touchpoint are equal which they are not. By placing the green box I know what point I set that at and therefore know what the point should be.

sorry for the rambling, just trying to give as much information as possible.

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

#if defined(__SAM3X8E__)
    #undef __FlashStringHelper::F(string_literal)
    #define F(string_literal) string_literal
#endif

#define YP A3  // must be an analog pin, use "An" notation!
#define XM A2  // must be an analog pin, use "An" notation!
#define YM 9   // can be a digital pin
#define XP 8 // can be a digital pin




#define TS_MINX 112
#define TS_MAXX 912

#define TS_MINY 78
#define TS_MAXY 903

// pressure resisistance @300ohms
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);

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

//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



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

void setup() {


  Serial.begin(9600) ;
Serial.println("Program run") ;

pinMode(13,OUTPUT) ;
   pinMode(XM, OUTPUT);
  pinMode(YP, OUTPUT);
  

  tft.reset() ;
tft.begin(0x9341);
 tft.setRotation(1) ;
tft.fillScreen(BLUE) ;
tft.fillRect (50,180, 220,40,GREEN) ;
tft.setCursor(60,190) ;
tft.setTextColor(RED) ;
tft.setTextSize(2) ;
tft.print("I hope this works") ;


#define MINPRESSURE 10
#define MAXPRESSURE 1000

}
void loop () {

  digitalWrite (13,HIGH) ;
TSPoint p = ts.getPoint();
digitalWrite (13,LOW) ;

if (p.z > MINPRESSURE && p.z < MAXPRESSURE) {


  //Serial.print("X = "); Serial.print(p.x);
   // Serial.print("\tY = "); Serial.print(p.y);
    //Serial.print("\tPressure = "); Serial.println(p.z);

      //example code uses lines 1 & 3

   p.x = map(p.x, TS_MINX, TS_MAXX, tft.width(), 0);
    //p.x = tft.width()-map(p.x, TS_MINX, TS_MAXX, tft.width(), 0);
    p.y = (tft.height()-map(p.y, TS_MINY, TS_MAXY, tft.height(), 0));
    // p.y = map(p.y, TS_MINY, TS_MAXY, tft.height(), 0);

 

     Serial.print("("); Serial.print(p.x);
    Serial.print(", "); Serial.print(p.y);
    Serial.println(")");
    
}

}

Once I can figure out the mapping problem will be the program.

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

#if defined(__SAM3X8E__)
    #undef __FlashStringHelper::F(string_literal)
    #define F(string_literal) string_literal
#endif

#define YP A3  // must be an analog pin, use "An" notation!
#define XM A2  // must be an analog pin, use "An" notation!
#define YM 9   // can be a digital pin
#define XP 8   // can be a digital pin

#define TS_MINX 120
#define TS_MAXX 900

#define TS_MINY 70
#define TS_MAXY 920

// pressure resisistance @300ohms
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);

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

//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



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


#define BOXSIZE 40 //size of boxes for button
#define PENRADIUS 3 //size of what how big of a line (circle)
int oldcolor, currentcolor;
//----------------------------------------

int on=LOW ;
int off=HIGH ;
int fillPin=23 ;
int drainPin=22 ;
int highlevelPin=24 ;
int lowlevelPin= 25 ;
int SWCPin=26 ;
int SWCButton ;
int SWCButtonNew ;
int highLevel ;
int lowLevel ;
int newState ;
int dt=250 ;
int NewlowLevel;
int drainfillDelay=3000 ;



void setup() {
  // put your setup code here, to run once:
Serial.begin(9600) ;
Serial.println("Program run") ;

pinMode(13,OUTPUT) ;
   pinMode(XM, OUTPUT);
  pinMode(YP, OUTPUT);
  

  tft.reset() ;
tft.begin(0x9341);
 tft.setRotation(1) ;
tft.fillScreen(BLUE) ;

//Draw white frame
    tft.drawRect (0,0,319,240,WHITE) ;

//Print "hello" text
tft.setCursor(100,30) ;
tft.setTextColor (WHITE) ;
tft.setTextSize(4) ;
tft.print("Hello") ;

//create water change button
tft.fillRect(40,180,260,40,GREEN) ;
tft.drawRect(40,180,260,40,WHITE) ;
tft.setCursor(60,188) ;
tft.setTextColor(BLACK) ;
tft.setTextSize(2) ;
tft.print("Begin Water Change") ;
    



#define MINPRESSURE 10
#define MAXPRESSURE 1000

//-----------------------------------------------------
pinMode(drainPin,OUTPUT);
pinMode(SWCButton,INPUT);
pinMode(highlevelPin,INPUT) ;
pinMode(lowlevelPin,INPUT);
digitalWrite(drainPin,off);
digitalWrite(fillPin,off);
pinMode(fillPin,OUTPUT) ;
}


void loop() {
  // put your main code here, to run repeatedly:
digitalWrite (13,HIGH) ;
TSPoint p = ts.getPoint() ;
digitalWrite (13,LOW) ;




//--------------------------------------------------------

if (p.z > MINPRESSURE && p.z < MAXPRESSURE) {

   p.x = map(p.x, TS_MINX, TS_MAXX, tft.width(), 0);
   p.x = map(p.x, TS_MINX, TS_MAXX, tft.width(), 0);

   if ( p.x > 40 && p.x < 300) && ( p.y > 180 && p.y < 220) {
   
   pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
 
 //create water change in progress button
tft.fillRect(40,180,260,40,RED) ;
tft.drawRect(40,180,260,40,WHITE) ;
tft.setCursor(60,188) ;
tft.setTextColor(BLACK) ;
tft.setTextSize(1) ;
tft.print("Water change in progress") ;

highLevel=digitalRead(highlevelPin) ;
    lowLevel=digitalRead(lowlevelPin) ;
    Serial.print("low Level is ") ;
    Serial.println(lowLevel) ;
    Serial.print("High Level is ") ;
    Serial.println(highLevel) ;
    if (highLevel==1 && lowLevel==1) {
      Serial.println ("sensors working") ;
     lowLevel=digitalRead(lowlevelPin) ;
      while (lowLevel==1) {
      
             digitalWrite(drainPin,on) ;
             Serial.println ("Drain on") ;
             lowLevel=digitalRead(lowlevelPin) ;
             Serial.print("low level is ") ;
             Serial.println (lowLevel) ;
              }
      digitalWrite(drainPin,off) ;
      delay(drainfillDelay) ;

      highLevel=digitalRead(highlevelPin) ;

      while (highLevel==0) {
      
             digitalWrite(fillPin,on) ;
             Serial.println ("Filling") ;
             highLevel=digitalRead(highlevelPin) ;
             Serial.print("High level pin is ") ;
             Serial.println (highLevel) ;
              }
      digitalWrite(drainPin,off) ;
      digitalWrite(fillPin,off) ;
      
    
    }




delay(2000) ;

 pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);

    tft.fillScreen(BLUE) ;

//Draw white frame
    tft.drawRect (0,0,319,240,WHITE) ;

//Print "hello" text
tft.setCursor(100,30) ;
tft.setTextColor (WHITE) ;
tft.setTextSize(4) ;
tft.print("Hello") ;

//create water change button
tft.fillRect(40,180,260,40,GREEN) ;
tft.drawRect(40,180,260,40,WHITE) ;
tft.setCursor(60,188) ;
tft.setTextColor(BLACK) ;
tft.setTextSize(2) ;
tft.print("Begin Water Change") ;
    }
}

highLevel=digitalRead(highlevelPin) ;
Serial.println(highLevel) ;
if (highLevel==0) {
  digitalWrite(fillPin,on) ;
  
}
if (highLevel==1) {
  digitalWrite(fillPin,off) ;
  
}
    
}

Are you saying that if you put a button on the screen at x1, y1, x2, y2 then, when the button is activated by a touch the coordinates returned are not in that range ?

The touch coordinates from where I touch are not in that range of where the lcd screen button is displayed so if i touch the button on the screen it does not see the range specified because the display x and y do not equal the touch screen x and y so the button would not be activated

You may need to swap x and y on one of the two coordinate systems.

You may need to reverse (mirror) one or both axes.

You def need to calibrate the touchscreen.

First get a feel for the numbers that touching will develop as you press the corners, just a simple continuous report of the touch coordinates.

Then see if this helps you think about it:

Poke around google search like

  calibrate mirror touchscreen arduino

It's just simple maths to the rescue, shows up in any screen + touchscreen deployment.

a7

No one knows how you are holding the screen. There are two orientations for "landscape mode", with different coordinate definitions.

Ok I thought by saying it was set to (setrotation(1)) it would be the same. The serial port is in the bottom right.

Thanks!

You just need to decide which of the two orientations is "correct" and stick with that. The required coordinate transformations depend on your choice.

Ok Thanks I will look into that.

Thanks for all the help from everyone. I figured I would post what I found to work in case anyone else was having trouble.

#define TS_LEFT 85
#define TS_RIGHT 900

#define TS_TOP 105
#define TS_BOT 920

The actual mapping:

 py = map (p.x, TS_TOP, TS_BOT, 0, tft.height()) ;
    px = map (p.y, TS_LEFT, TS_RIGHT,0, tft.width()) ;

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