Offset Touchscreen Accuracy

Hello,
I´m struggling around with the 2.8" Touchscreen I ordered last week. I`ve got it hook up on an original Arduino Uno. The Chipset on the Display is a ILI9341. I wrote a Sketch that just draws a little rectangle whereever the Screen gets touched. My problem is that I have a offset of about 6-8 Pixels in the Y-Direction and about 2 in the X-Direction. I also noticed that the last 2mm above the bottom from Display don´t react to the stylus. Therefor on the Top of the Display the Screen reacts to the stylus, although the border of the LCD is about 3mm underneath from that point. I calibrated the Touchscreen a few times with the test from MCUfriend and the one from Adafruit. About a year ago I made a UI with an 2.4" Touchscreen and never had any of this problems... Is this a fault on my own where I don´t hit the corners accurate enough, or are there Issues known thats just a simple production failure? If you need any pictures or the sketch I use, I can upload those too.

best regards Patrick

The Display I use:


Run the Calibration sketch from the examples.
Run the TouchShield sketch from the examples with your calibration results.
e.g. observe pixel coordinates. observe accuracy in "Paint" section. observe any "dead" corners. Write notes on paper.

Report back. (with your notes)

It is always wise to run all the library examples before writing your own custom code.

David.

First off all, thanks for the reply. I ran the calibration and the paint sketch again and adjusted the values in my Sketch, that I get from the Serial Monitor. I´m still a few Pixels off but a bit closer than last time. I ordered a new display just to check if there is an fabrication failure. But now running into the next problem..
This is Sketch I wrote to test the accuracy of the touchscreen:

#include <Adafruit_TFTLCD.h>
#include <Adafruit_GFX.h>
#include <TouchScreen.h>

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


// MCU Values
//const int XP=8,XM=A2,YP=A3,YM=9; //240x320 ID=0x9341
//const int TS_LEFT=918,TS_RT=98,TS_TOP=75,TS_BOT=901;

//PORTRAIT  CALIBRATION     240 x 320
//x = map(p.x, LEFT=918, RT=98, 0, 240)
//y = map(p.y, TOP=75, BOT=901, 0, 320)


// USB-Port faces downwards
#define TS_MINX 918// TS_LEFT  
#define TS_MINY 75// TS_TOP
#define TS_MAXX 98// TS_RT
#define TS_MAXY 901// TS_BOT


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


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

const int XP = 8;
const int XM = A2;
const int YP = A3;
const int YM = 9;


TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300); // Resistance between D8 and A2

void setup() {
  Serial.begin(9600);
  Serial.print("Starting...");
  tft.reset();
  //tft.begin(tft.readID());
  tft.begin(0x9341);
  tft.setRotation(0);

}

void loop() {
  TSPoint p = ts.getPoint();  //Get touch point

  
  if (p.z > ts.pressureThreshhold) {
    p.x = map(p.x, TS_MINX, TS_MAXX, 240, 0);// setRotation(0)
    p.y = map(p.y, TS_MINY, TS_MAXY, 320, 0);// setRotation(0)
    Serial.println("Koordinaten");
    Serial.println(p.x);
    Serial.println(p.y);
  }

  if (p.x > 0 && p.x < 240 && p.y > 0 && p.y < 320) {
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
    tft.fillScreen(BLACK);
    tft.fillRect(p.x, p.y, 2, 2, YELLOW); // draws 2 pixel rectangle

    tft.setCursor(100, 70);
    tft.setTextColor(WHITE, BLACK );  tft.setTextSize(4);
    tft.print("Hello"); // just to see to the alignment / rotation 

  }
}

Display is in portrait mode(USB facing downwards) and anywhere the Screen gets touched it draws a yellow rectangle and prints out the XY coordinates. Works perfectly for me. Next I tried to rotate the Screen to the landscape mode with the same fuctions as above. So I wrote this:

#include <Adafruit_TFTLCD.h>
#include <Adafruit_GFX.h>
#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 918// TS_LEFT  75
#define TS_MINY 75// TS_TOP 98
#define TS_MAXX 98// TS_RT 901
#define TS_MAXY 901// TS_BOT 917

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

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

const int XP = 8;
const int XM = A2;
const int YP = A3;
const int YM = 9;

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

void setup() {
  Serial.begin(9600);
  Serial.print("Starting...");
  tft.reset();
  //tft.begin(tft.readID());
  tft.begin(0x9341);
  tft.setRotation(1);
  tft.fillScreen(BLACK);
}

void loop()
{
  TSPoint p = ts.getPoint();  //Get touch point

  if (p.z > ts.pressureThreshhold) {
    p.x = map(p.y, TS_MINY, TS_MAXY, 320, 0);
    p.y = map(p.x, TS_MAXX, TS_MINX, 0, 240);
    Serial.println("Koordinaten");
    Serial.println(p.x);
    Serial.println(p.y);
  }
  
  if (p.x > 0 && p.x < 320 && p.y > 0 && p.y < 240){ 
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
    tft.fillScreen(BLACK);
    tft.fillRect(p.x, p.y, 2, 2, YELLOW); // draws 2 pixel rectangle
    tft.setCursor(100, 70);
    tft.setTextColor(WHITE, BLACK );  tft.setTextSize(4);
    tft.print("Hello"); // just to see to the alignment / rotation
  }
}

The problem is that it dont prints the XY Values correct. If I comment out "p.x = map(p.y, TS_MINY, TS_MAXY, 320, 0);" and the "Serial.println(p.x);" lines I get the right Values and vica versa. But not both at the same time. The Value I map at first in the loop gives the right coordinats back and the second one jumps in a range of 20 to 30. For me the loop in both sketches look similar. Any idea what it could be?

** Serial Output mapping X Value at first
Koordinaten
X0
Y268 (Bottom left corner)

Koordinaten
X321
Y175 (Top right corner)

** Serial Output mapping Y Value at first
Koordinaten
347
0(Bottom left corner)

Koordinaten
256
242(Top right corner)

I expected to hear some actual numbers e.g. +2mm wrong in X and -3mm in Y at top right. Or missing corner at bottom left.

If you want to use PORTRAIT_REV just say so. You choose whichever rotation suits you. You can run the TouchShield sketch in any rotation e.g. PORTRAIT_REV.

I find it easier to advise about MCUFRIEND_kbv.

But if you want to use Adafruit_TFTLCD you need to test it first. e.g. can it read the ID ?
Does it work in PORTRAIT_REV ok ?

And you seem to mix up X, Y from screen pixels and Touch ADC values.
I strongly advise following the style in TouchShield example.

David.

Hello,
So i´ve got it finally working . Thanks for your Help :slight_smile: I followed your advice(seen in other helpfull post from you) to draw the Layout on a piece of paper and rotate it to the direction i want to map the XY Values.
I still got a offset of about 1mm in the X, and 2mm in the Y Direction(Portrait Modus). I still hope that a new Touchscreen will fix this Problem.
To the Problem with the Values in the Serial Monitor: The Solution was to rename p.y and p.x to pixel_x and pixel_y.. Thats Ok for me and I will stay with those names.
The Chip is an ILI9341. I got it from that from the manual and from the read.ID function.

What I still don´t understand, but maybe I was thinking wrong all the time:
In Portrait Mode X0, Y0 is in the Top Left Corner. So I suggest that from that point the ADC Value increase to the X240, Y320(Bottom right corner) Position. But in my Case:
X0 = ADC 918
X240 = ADC 98
Y0 = ADC 75
Y320 = ADC 901
For the Y Axis my understandig is correct but not for the X axis, here is the bigger ADC value the logical Zero point for this Axis.. But ok, I can live with that :smiley:

Maybe it will help someone in the future who also bought a Elegoo Touchscreen:
Thats the Code that works for me. Landscape Mode 1 XY=0 Top Left corner.

I really appreciate your help!!!
Patrick

//for 2.8" Touchscreen from Elegoo with the ILI9341
//Landscape Mode USB facing right
// Draws a yellow Dot whereever the Display gets touched
// XY Origin in the Top Left corner 
// XY coordinats can be seen in the Serial Monitor

#include <Adafruit_TFTLCD.h>
#include <Adafruit_GFX.h>
#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 75 // TS_LEFT
#define TS_MINY 901 // TS_TOP
#define TS_MAXX 918 // TS_RIGHT
#define TS_MAXY 98 // TS_BOTTOM

#define BLACK   0x0000
#define BLUE    0x001F
#define RED     0xF800
#define GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF
Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);
const int XP = 8;
const int XM = A2;
const int YP = A3;
const int YM = 9;
int pixel_x, pixel_y;
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300); // Resistance between D8 and A2




void setup() {
  Serial.begin(9600);
  Serial.print("Starting...");
  tft.reset();
  tft.begin(0x9341);
  tft.setRotation(1);
}

void loop() {
  TSPoint p = ts.getPoint();  //Get touch point

  // Mapping und Serial Print der XY Touch Koordinaten
  if (p.z > ts.pressureThreshhold) {
    Serial.println("Koordinaten");
    pixel_y = map(p.x, TS_MINY, TS_MAXY, 0, 240);
    pixel_x = map(p.y, TS_MINX, TS_MAXX, 0, 320);
    pixel_x = (320 - pixel_x);
    Serial.println(pixel_x);
    Serial.println(pixel_y);
  }
  
  // Gelber Punkt Touchscreen Debug
  if (pixel_x > 0 && pixel_x < 320 && pixel_y > 0 && pixel_y < 240) {
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
    tft.fillScreen(BLACK);
    tft.fillRect(pixel_x, pixel_y, 2, 2, YELLOW); // draws 2 pixel rectangle
    tft.setCursor(100, 70);
    tft.setTextColor(WHITE, BLACK );  tft.setTextSize(4);
    tft.print("Hello"); // just to see to the alignment / rotation
    pixel_x = 0;
    pixel_y = 0;
  }
}

Most TFT panels have natural mode as Portrait. i.e. with ribbon at the bottom of the screen.

Many TFT + Touch Panels have an extra Touch area at the bottom e.g. with icons of a House, Phone, ...

Most TFT shields are mounted on a Uno with USB at the top. 3x2 SPI header at the bottom.

Uno Resistive Touch panels have 4 wires that connect to 4 GPIO pins. These are shared with the TFT pins.
You can imagine that there are many different ways to route the Touch pins. Hence my Calibration sketch diagnoses the exact pin mapping.
Yes, sometimes ADC will increase from left to right and sometimes from right to left. Live with it.
That is why I call values TS_LEFT, TS_RT rather than TS_MINX, TS_MAXX.

There is no mystery when you draw a screen shape on paper. Mark (portrait) LEFT, RT, TOP, BOT on each edge.
Rotate the paper. Easy to see how to change the pixel mapping.
Or just copy paste the relevant switch case from the example.

David.

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