Touch screen mistakes recognizing press

I am trying to build a function menu on a touch screen (buttons etc.) using Arduino. and i am facing a terrible problem which causes my touch screen to mistake reading the pressure at a given location:
every long press turns to series of touch and release.

the library i am using: GitHub - adafruit/Adafruit_TouchScreen: Arduino library for 4-wire resistive touchscreens

link to touch screen: https://www.ebay.com/itm/184556907031

3.2 inch TFT LCD Display Resistive Touch Screen Shield Module 400x240 ILI9327

code that shows what is the problem:

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

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

uint8_t YP = A1; 
uint8_t XM = A2; 
uint8_t YM = 7;  
uint8_t XP = 6;   

const uint16_t TOUCHSCREEN_LEFT = 150;
const uint16_t TOUCHSCREEN_RIGHT  = 950;
const uint16_t TOUCHSCREEN_BOTTOM = 160;
const uint16_t TOUCHSCREEN_TOP = 920;


MCUFRIEND_kbv tft; 
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 500);
TSPoint tp;



void printMistakes()
{
  int c1 = 0;
  int c2 = 0;
  tp = ts.getPoint();   
  Serial.println("put your finger on the display and don't release it");
  while (tp.z == 0)tp = ts.getPoint();
  Serial.println("started");
  
  for (int i = 0; i < 1000; i++)
  {
    
    digitalWrite(A3,HIGH);
    tp = ts.getPoint();   

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

    if (tp.z > 0)
    c1++;
    else c2++;
  }
  Serial.println("times pressed = " + String(c1));
  Serial.println("times released = " + String(c2));
}

void setup() {
 Serial.begin(9600);
 tft.begin(tft.readID());
 tft.fillScreen(BLACK);

 printMistakes();
}

void loop() {


}

in my case the serial monitor shows the following output
times pressed = 16
times released = 984

this is not a constant output but it keeps being around it.

I want a smooth touch. the output has to be "times pressed = 1000". how can i fix it?

I don't know what else you're up to, but this is nonsense. You only need to set pinMode once, never 1000 times. You must have a mistaken idea of what it does.

Take a look at [solved] Problem with debouncing touchscreen buttons.

Believe me I do, but this is what is written in the examples of the library
code:

// the regular Adafruit "TouchScreen.h" library only works on AVRs

// different mcufriend shields have Touchscreen on different pins
// and rotation.
// Run the UTouch_calibr_kbv sketch for calibration of your shield

#include <Adafruit_GFX.h>    // Core graphics library
//#include <Adafruit_TFTLCD.h> // Hardware-specific library
//Adafruit_TFTLCD tft(A3, A2, A1, A0, A4);
#include <MCUFRIEND_kbv.h>
MCUFRIEND_kbv tft;       // hard-wired for UNO shields anyway.
#include <TouchScreen.h>

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

//----------------------------------------|
// TFT Breakout  -- Arduino UNO / Mega2560 / OPEN-SMART UNO Black
// GND              -- GND
// 3V3               -- 3.3V
// CS                 -- A3
// RS                 -- A2
// WR                -- A1
// RD                 -- A0
// RST                -- RESET
// LED                -- GND
// DB0                -- 8
// DB1                -- 9
// DB2                -- 10
// DB3                -- 11
// DB4                -- 4
// DB5                -- 13
// DB6                -- 6
// DB7                -- 7
// most mcufriend shields use these pins and Portrait mode:
uint8_t YP = A1;  // must be an analog pin, use "An" notation!
uint8_t XM = A2;  // must be an analog pin, use "An" notation!
uint8_t YM = 7;   // can be a digital pin
uint8_t XP = 6;   // can be a digital pin
uint8_t SwapXY = 0;

uint16_t TS_LEFT = 920;
uint16_t TS_RT  = 90;
uint16_t TS_TOP = 940;
uint16_t TS_BOT = 140;
char *name = "Unknown controller";

// For better pressure precision, we need to know the resistance
// between X+ and X- Use any multimeter to read it
// For the one we're using, its 300 ohms across the X plate
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 500);
TSPoint tp;

#define MINPRESSURE 100
#define MAXPRESSURE 6000

#define SWAP(a, b) {uint16_t tmp = a; a = b; b = tmp;}

int16_t BOXSIZE;
int16_t PENRADIUS = 3;
uint16_t identifier, oldcolor, currentcolor;
uint8_t Orientation = 0;    //PORTRAIT

// Assign human-readable names to some common 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

void show_Serial(void)
{
    Serial.print(F("Found "));
    Serial.print(name);
    Serial.println(F(" LCD driver"));
    Serial.print(F("ID=0x"));
    Serial.println(identifier, HEX);
    Serial.println("Screen is " + String(tft.width()) + "x" + String(tft.height()));
    Serial.println("Calibration is: ");
    Serial.println("LEFT = " + String(TS_LEFT) + " RT  = " + String(TS_RT));
    Serial.println("TOP  = " + String(TS_TOP)  + " BOT = " + String(TS_BOT));
    Serial.print("Wiring is: ");
    Serial.println(SwapXY ? "SWAPXY" : "PORTRAIT");
    Serial.println("YP=" + String(YP)  + " XM=" + String(XM));
    Serial.println("YM=" + String(YM)  + " XP=" + String(XP));
}

void show_tft(void)
{
    tft.setCursor(0, 0);
    tft.setTextSize(2);
    tft.print(F("Found "));
    tft.print(name);
    tft.println(F(" LCD"));
    tft.setTextSize(1);
    tft.print(F("ID=0x"));
    tft.println(identifier, HEX);
    tft.println("Screen is " + String(tft.width()) + "x" + String(tft.height()));
    tft.println("Calibration is: ");
    tft.println("LEFT = " + String(TS_LEFT) + " RT  = " + String(TS_RT));
    tft.println("TOP  = " + String(TS_TOP)  + " BOT = " + String(TS_BOT));
    tft.print("\nWiring is: ");
    if (SwapXY) {
        tft.setTextColor(CYAN);
        tft.setTextSize(2);
    }
    tft.println(SwapXY ? "SWAPXY" : "PORTRAIT");
    tft.println("YP=" + String(YP)  + " XM=" + String(XM));
    tft.println("YM=" + String(YM)  + " XP=" + String(XP));
    tft.setTextSize(2);
    tft.setTextColor(RED);
    tft.setCursor((tft.width() - 48) / 2, (tft.height() * 2) / 4);
    tft.print("EXIT");
    tft.setTextColor(YELLOW, BLACK);
    tft.setCursor(0, (tft.height() * 6) / 8);
    tft.print("Touch screen for loc");
    while (1) {
        tp = ts.getPoint();
        pinMode(XM, OUTPUT);
        pinMode(YP, OUTPUT);
        pinMode(XP, OUTPUT);
        pinMode(YM, OUTPUT);
        if (tp.z < MINPRESSURE || tp.z > MAXPRESSURE) continue;
        if (tp.x > 450 && tp.x < 570  && tp.y > 450 && tp.y < 570) break;
        tft.setCursor(0, (tft.height() * 3) / 4);
        tft.print("tp.x=" + String(tp.x) + " tp.y=" + String(tp.y) + "   ");
    }
}


void setup(void)
{
    uint16_t tmp;
    tft.begin(9600);
    
    tft.reset();
    identifier = tft.readID();
  
    switch (Orientation) {      // adjust for different aspects
        case 0:   break;        //no change,  calibrated for PORTRAIT
        case 1:   tmp = TS_LEFT, TS_LEFT = TS_BOT, TS_BOT = TS_RT, TS_RT = TS_TOP, TS_TOP = tmp;  break;
        case 2:   SWAP(TS_LEFT, TS_RT);  SWAP(TS_TOP, TS_BOT); break;
        case 3:   tmp = TS_LEFT, TS_LEFT = TS_TOP, TS_TOP = TS_RT, TS_RT = TS_BOT, TS_BOT = tmp;  break;
    }

    Serial.begin(9600);

    tft.begin(identifier);
    show_Serial();
    tft.setRotation(Orientation);
    tft.fillScreen(BLACK);
   show_tft();

    BOXSIZE = tft.width() / 6;
    tft.fillScreen(BLACK);

    tft.fillRect(0, 0, BOXSIZE, BOXSIZE, RED);
    tft.fillRect(BOXSIZE, 0, BOXSIZE, BOXSIZE, YELLOW);
    tft.fillRect(BOXSIZE * 2, 0, BOXSIZE, BOXSIZE, GREEN);
    tft.fillRect(BOXSIZE * 3, 0, BOXSIZE, BOXSIZE, CYAN);
    tft.fillRect(BOXSIZE * 4, 0, BOXSIZE, BOXSIZE, BLUE);
    tft.fillRect(BOXSIZE * 5, 0, BOXSIZE, BOXSIZE, MAGENTA);

    tft.drawRect(0, 0, BOXSIZE, BOXSIZE, WHITE);
    currentcolor = RED;
    delay(1000);
}

void loop()
{
    uint16_t xpos, ypos;  //screen coordinates
    digitalWrite(A3,HIGH);
    tp = ts.getPoint();   //tp.x, tp.y are ADC values

    // if sharing pins, you'll need to fix the directions of the touchscreen pins
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
    pinMode(XP, OUTPUT);
    pinMode(YM, OUTPUT);
    //    digitalWrite(XM, HIGH);
    //    digitalWrite(YP, HIGH);
    // we have some minimum pressure we consider 'valid'
    // pressure of 0 means no pressing!

    if (tp.z > MINPRESSURE && tp.z < MAXPRESSURE) {
       Serial.print("X = "); Serial.print(tp.x);
     Serial.print("\tY = "); Serial.print(tp.y);
     Serial.print("\tPressure = "); Serial.println(tp.z);
        // is controller wired for Landscape ? or are we oriented in Landscape?
        if (SwapXY != (Orientation & 1)) SWAP(tp.x, tp.y);
        // scale from 0->1023 to tft.width  i.e. left = 0, rt = width
        // most mcufriend have touch (with icons) that extends below the TFT
        // screens without icons need to reserve a space for "erase"
        // scale the ADC values from ts.getPoint() to screen values e.g. 0-239
       
        xpos = map(tp.x, TS_LEFT, TS_RT, 0, tft.width());
        ypos = map(tp.y, TS_TOP, TS_BOT, 0, tft.height());

        // are we in top color box area ?
        if (ypos < BOXSIZE) {               //draw white border on selected color box
            oldcolor = currentcolor;

            if (xpos < BOXSIZE) {
                currentcolor = RED;
                tft.drawRect(0, 0, BOXSIZE, BOXSIZE, WHITE);
            } else if (xpos < BOXSIZE * 2) {
                currentcolor = YELLOW;
                tft.drawRect(BOXSIZE, 0, BOXSIZE, BOXSIZE, WHITE);
            } else if (xpos < BOXSIZE * 3) {
                currentcolor = GREEN;
                tft.drawRect(BOXSIZE * 2, 0, BOXSIZE, BOXSIZE, WHITE);
            } else if (xpos < BOXSIZE * 4) {
                currentcolor = CYAN;
                tft.drawRect(BOXSIZE * 3, 0, BOXSIZE, BOXSIZE, WHITE);
            } else if (xpos < BOXSIZE * 5) {
                currentcolor = BLUE;
                tft.drawRect(BOXSIZE * 4, 0, BOXSIZE, BOXSIZE, WHITE);
            } else if (xpos < BOXSIZE * 6) {
                currentcolor = MAGENTA;
                tft.drawRect(BOXSIZE * 5, 0, BOXSIZE, BOXSIZE, WHITE);
            }

            if (oldcolor != currentcolor) { //rub out the previous white border
                if (oldcolor == RED) tft.fillRect(0, 0, BOXSIZE, BOXSIZE, RED);
                if (oldcolor == YELLOW) tft.fillRect(BOXSIZE, 0, BOXSIZE, BOXSIZE, YELLOW);
                if (oldcolor == GREEN) tft.fillRect(BOXSIZE * 2, 0, BOXSIZE, BOXSIZE, GREEN);
                if (oldcolor == CYAN) tft.fillRect(BOXSIZE * 3, 0, BOXSIZE, BOXSIZE, CYAN);
                if (oldcolor == BLUE) tft.fillRect(BOXSIZE * 4, 0, BOXSIZE, BOXSIZE, BLUE);
                if (oldcolor == MAGENTA) tft.fillRect(BOXSIZE * 5, 0, BOXSIZE, BOXSIZE, MAGENTA);
            }
        }
        // are we in drawing area ?
        if (((ypos - PENRADIUS) > BOXSIZE) && ((ypos + PENRADIUS) < tft.height())) {
            tft.fillCircle(xpos, ypos, PENRADIUS, currentcolor);
        }
        // are we in erase area ?
        if (ypos > tft.height() - 10) {
            // press the bottom of the screen to erase
            tft.fillRect(0, BOXSIZE, tft.width(), tft.height() - BOXSIZE, BLACK);
        }
    }
}

I find no logic in this too, but i can't argue with the library creator. moreover, deleting this lines doesn't contribute solving the problem

I don't recognise that code. Please can you quote the name of the library example. And where you got the library from with a web link if possible.

I see that it is an OPEN-SMART display in your Shield link.
Which probably accounts for your unusual code.

Open-Smart hacked a 6-year old obsolete version of MCUFRIEND_kbv and never chose to change the library version e.g. to MCUFRIEND_hacked_by_Open_Smart

This is one of the "problems" with "Open Source software". People can modify libraries and distribute them without changing class names.
I would be happy to cooperate with Open-Smart, Elegoo, ... if they asked in the normal way. i.e. posting Issues, Pull Requests, on GitHub.

David.

link to the library is sent above, find the example for ILI9327 touch screen.
I am not sure about what you mean by part numbers. but I can read what is written on to of the chips
which is SM74HC245D BEAWRY AC33. there is one small chip that i can't really read what is written on it.

Setting the pinMode after reading the touchscreen is needed because the same pins are also used for the TFT display. I'm guessing the library does not do this itself because a touchpad can be used without a TFT, in which case the pins may be in use for something that shouldn't have them set to output.

You replied while I was editing #5. On further inspection of the photo I saw that it was Open-Smart.

I strongly advise that you delete the Open-Smart stuff and install MCUFRIEND_kbv via the IDE Library Manager.

Yes, you will have to make two small edits to change the Shield mapping for the Open-Smart shield. It is described in the extras/mcufriend_how_to.txt

David.

p.s. there is new example on the Beta https://github.com/prenticedavid/MCUFRIEND_kbv/tree/master/examples/showBMP_OpenSmart_Uno

I see. Well that makes sense. I think we could agree that it's a sign of poor coordination between different software modules.

Anyone who really has to do something like that should at least add an in line comment.

Thanks I found the solution to the problem. One thing that has to be changed in the TouchScreen.cpp is the NUMSAMPLES amount, i changed it from 2 to 3 and it worked.

But this lead to another problem: now when i follow the drawing example from this library:
https://drive.google.com/drive/folders/1VKY0X-OQ14WJ8M0Km7rtcYdudXKuV5_W
for my ILI touch screen display it is mapping points from first touch incorrectly making them appear twice in different locations

I really don't get what you mean by this because the MCUFRIEND_kbv is installed in my Open-Smart folder. What edits should I do? i didn't find it in the file .

From the how_to file

19. OPEN-SMART Shields have different wiring to regular Uno Shields:
    Edit utility/mcufriend_shield.h:  #define USE_SPECIAL
    Edit utility/mcufriend_special.h: #define USE_OPENSMART_SHIELD_PINOUT_xxx e.g. USE_OPENSMART_SHIELD_PINOUT_MEGA
    Edit MCUFRIEND_kbv.cpp:           #define SUPPORT_8352B

20. OPEN-SMART Shields can not read LM75A on a Mega because there are no SDA/SCL pins next on AREF header.
    Uno:  LM75A on pcb works.  Difficult to add external I2C devices when Shield is plugged in.
	Uno:  All use of SPI bus should use SPI.beginTransaction(), SPI.endTransaction()
	Leo:  I do not support USE_OPENSMART_SHIELD_PINOUT_LEO
	Mega: Old boards do not have SDA/SCL on AREF header.   Only external I2C devices on COMMS header
	Due:  MAX809 Reset chip interferes with 3.3V RST on SPI header.  Manual reset for Upload / Run.
	

In your case you just do

    Edit utility/mcufriend_shield.h:  #define USE_SPECIAL
    Edit utility/mcufriend_special.h: #define USE_OPENSMART_SHIELD_PINOUT_UNO

Regarding your Adafruit_GFX library from #10. This is obsolete.
It is another problem with Open-Smart hacking standard libraries.

It is wise to install libraries via the IDE Library Manager.

Do not trust random libraries that you find on the Internet.
They might be good but they are probably out of date.
If in doubt, just ask on the Forum.

David.

Thanks to everyone, Now everything works

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