Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 16 of 16

Thread: ILI9341 Touch Screen debounce?

  1. #1
    Senior Member
    Join Date
    Jun 2017
    Posts
    153

    ILI9341 Touch Screen debounce?

    Hi,

    I have been working with a Teensy 3.2 connected to a ILI9341 TFT/Touch display from Paul's store, and I am having a problem debouncing the touch screen. I have a very simple sketch that takes a stylus touch point, maps it to an appropriate display coordinate, and draws a small filled circle at the mapped point. For each point I print out the program time in milliSec, the raw (touch screen) coordinates and the mapped display coordinates. I also have some 'debounce' code to prevent multiple touch detections from a single stylus tap. The debounce code works perfectly, UNLESS I tap on the lower left hand corner of the screen, where I get 10-15 touch detections even with the debounce code present. Here's the sketch:

    Code:
    /*
        Name:       KurtTouchV2.ino
        Created:	2/15/2021 4:16:52 PM
        Author:     FRANKNEWXPS15\Frank
    
    */
    
     //****************************************************************************
     // Includes
     //****************************************************************************
    #include <XPT2046_Touchscreen.h>
    #include <ILI9341_t3n.h>
    #include "ili9341_t3n_font_Arial.h"
    
    //****************************************************************************
    // This is calibration data for the raw touch data to the screen coordinates
    //****************************************************************************
    // Warning, These are approximate values
    #define TS_MINX 600
    #define TS_MINY 600
    #define TS_MAXX 3758
    #define TS_MAXY 3612
    
    #define SCREEN_ORIENTATION_1
    
    //02/16/21 change from using #defines to variables, so can 
    //  update via calibration.
    uint16_t ts_minx = TS_MINX;
    uint16_t ts_maxx = TS_MAXX;
    uint16_t ts_miny = TS_MINY;
    uint16_t ts_maxy = TS_MAXY;
    
    
    //****************************************************************************
    // Settings and objects
    //****************************************************************************
    //02/15/21 pin assignments from https://www.pjrc.com/store/display_ili9341_touch.html
    #define TFT_DC  9
    #define TFT_CS 10
    #define TFT_RST 7
    #define TFT_SCK 13
    #define TFT_MISO 12
    #define TFT_MOSI 11
    #define TOUCH_CS  8
    
    XPT2046_Touchscreen ts(TOUCH_CS);
    ILI9341_t3n tft = ILI9341_t3n(TFT_CS, TFT_DC, TFT_RST, TFT_MOSI, TFT_SCK, TFT_MISO);
    
    // Size of the color selection boxes and the paintbrush size
    #define MAX_DISPLAY_X 240
    #define MAX_DISPLAY_Y 320
    #define NUMBOXES 7
    //#define BOXSIZE MAX_DISPLAY_X / NUMBOXES
    #define BOXSIZE 34
    #define PENRADIUS 3
    int oldcolor, currentcolor;
    
    int BoxColorArray[] = { ILI9341_RED, ILI9341_YELLOW, ILI9341_GREEN, ILI9341_CYAN,
      ILI9341_BLUE, ILI9341_MAGENTA, ILI9341_WHITE, ILI9341_ORANGE, ILI9341_GREENYELLOW, ILI9341_PINK };
    
    //****************************************************************************
    // Setup
    //****************************************************************************
    void setup(void) 
    {
      Serial.begin(9600);
      while (!Serial && (millis() <= 3000))
      {
        delay(100);
      }
    
      tft.begin();
      tft.setRotation(1);
    
      // by default use SPI
      if (!ts.begin()) {
        Serial.println("Couldn't start touchscreen controller");
        while (1);
      }
      Serial.println("Touchscreen started");
    
    
      tft.fillScreen(ILI9341_BLACK);
      }
    
    void loop()
    {
      // See if there's any  touch data for us
      // You can also wait for a touch
      if (!ts.touched()) 
      {
        return;
      }
    
      // Retrieve a point
      TS_Point p = ts.getPoint();
    
      Serial.printf("%lu: Raw P(%d,%d) maps to ", millis(), p.x, p.y);
    
      // Scale from ~0->4000 to tft.width using the calibration #'s
    #ifdef SCREEN_ORIENTATION_1
      p.x = map(p.x, TS_MAXX, TS_MINX, 0, tft.width());
      p.y = map(p.y, TS_MAXY, TS_MINY, 0, tft.height());
    #else
      uint16_t px = map(p.y, TS_MINY, TS_MAXY, 0, tft.width());
      p.y = map(p.x, TS_MAXX, TS_MINX, 0, tft.height());
      p.x = px;
    #endif
    
      Serial.printf(" (%d,%d): ", p.x, p.y);
      Serial.printf("drawing circle at (%d,%d)\n", p.x, p.y);
      tft.fillCircle(p.x, p.y, PENRADIUS, ILI9341_RED);
    
      //touch screen debounce
      while (ts.touched())
      {
        p = ts.getPoint();
        delay(10);
      }
    }
    And a photo of the setup, showing some of the dots from the program

    Click image for larger version. 

Name:	IMG_4055.jpg 
Views:	7 
Size:	131.0 KB 
ID:	23863

    And here's some of the printed output, showing individual stylus presses and then a run of touch detections spaced about 10 mSec apart, all with the same approximate coordinates; these were generated from just one stylus touch in the lower left hand corner (corner closest to the Teensy and farthest away from the prototype board)

    Code:
    Opening port
    Port open
    19651: Raw P(3766,3562) maps to  (0,3): drawing circle at (0,3)
    29334: Raw P(708,3459) maps to  (309,12): drawing circle at (309,12)
    38322: Raw P(3813,362) maps to  (-5,258): drawing circle at (-5,258)
    38333: Raw P(3825,307) maps to  (-6,263): drawing circle at (-6,263)
    38343: Raw P(3844,307) maps to  (-8,263): drawing circle at (-8,263)
    38354: Raw P(3840,305) maps to  (-8,263): drawing circle at (-8,263)
    38364: Raw P(3840,305) maps to  (-8,263): drawing circle at (-8,263)
    38375: Raw P(3862,317) maps to  (-10,262): drawing circle at (-10,262)
    38385: Raw P(3861,301) maps to  (-10,263): drawing circle at (-10,263)
    38395: Raw P(3845,292) maps to  (-8,264): drawing circle at (-8,264)
    Any ideas why this is happening?

    TIA,

    Frank
    Last edited by paynterf; 02-28-2021 at 12:50 AM. Reason: forgot to add program output

  2. #2
    Senior Member
    Join Date
    Jul 2020
    Posts
    897
    The library has no hysteresis for Z_THRESHOLD so will inherently generate noisy z-values. This
    probably is an oversight. The Z-threshold(s) probably ought to be tweakable in the API too.

    Your debounce time is perhaps too short at 10ms, and the reason one corner is particularly sensitive is
    likely that its closer to the threshold at normal stylus pressure for no deep reason.

  3. #3
    Senior Member
    Join Date
    May 2017
    Posts
    238
    >> drawing circle at (-8,263)

    This is probably not your issue but something I noticed:
    Your calls to fillCircle with coordinates off the screen probably return without doing any drawing. So your program will not have whatever delay fillCircle provides when you touch in the corner.

  4. #4
    Senior Member
    Join Date
    Jun 2017
    Posts
    153
    I modified my sketch to just record raw touch screen data every 10mSec during touch periods, and then touched each corner in turn for about 1 second, trying to apply approximately the same pressure each time. When I graphed the results in Excel I got the following chart

    Click image for larger version. 

Name:	210228 CornerZVals1.jpg 
Views:	3 
Size:	39.1 KB 
ID:	23867

    The last segment of this chart is from the press event in the lower left-hand corner - the same corner that is giving me problems with the de-bounce code. It now appears that the problem with this corner isn't too much[ sensitivity, but too little. I've repeated this test a number of times, and it comes up the same way - that one corner is MUCH less sensitive than the others

    Then I drew a rectangle, starting from UL to UR to LR to LL and then back to UL, offset about 8mm in from each edge, resulting in the following chart. I tried to keep the touch pressure as constant as possible during the procedure.

    Click image for larger version. 

Name:	210228 CornerZVals2.jpg 
Views:	4 
Size:	52.9 KB 
ID:	23868

    The 'dip' in the graph corresponds to approaching and departing from the LL corner. Looks like this particular display is very insensitive in that one corner.

    Frank

  5. #5
    Senior Member
    Join Date
    Jun 2017
    Posts
    153
    rcarr,

    Thanks for the head-up! I noticed the off-screen coordinates but didn't think much of them at the time. I figured I would handle that later, when I actually had something working ;-)

    Frank

  6. #6
    Senior Member
    Join Date
    Jun 2017
    Posts
    153
    I made some further tests by drawing a continuous rectangle starting at the upper left-hand corner and proceeding clockwise around the screen, ending up at upper left again. I did this twice - once with the rectangle as close to the screen edges as I could, and a second time with a smaller rectangle more-or-less centered in the display (see the photos). On each pass I recorded the X/Y coordinates as mapped to display pixel space, and the touchscreen pressure (Z-axis) value. When I charted the results it was clear that the lower left-hand region of the display has significantly lower Z-axis output.

    Has anyone else had this experience or have some thoughts about these results?

    TIA,

    Frank

    Click image for larger version. 

Name:	IMG_4057.jpg 
Views:	2 
Size:	90.3 KB 
ID:	23869

    Click image for larger version. 

Name:	IMG_4056.jpg 
Views:	3 
Size:	85.7 KB 
ID:	23870

    Click image for larger version. 

Name:	210228 LargeRectangleZValues.jpg 
Views:	3 
Size:	65.8 KB 
ID:	23871
    Click image for larger version. 

Name:	210228 SmallRectangleZValues.jpg 
Views:	3 
Size:	67.1 KB 
ID:	23872

  7. #7
    Senior Member
    Join Date
    Apr 2020
    Location
    DFW area in Texas
    Posts
    229
    Frank:

    I can imagine that it would be almost impossible to keep the pressure on the display constant as the rectangle is drawn. Would you expect a different result if the test was run four times, rotating the display 90 degrees between tests. That way, you can see if the lower sensitivity follows the specific corner, or if it might be either a result of the way the rectangle is drawn, or exacerbated by the method. You may be able to remove some of the variability by using an object (e.g. a large ball bearing) to rest on the display, which would provide an almost constant pressure. Food for thought . . .

    Mark J Culross
    KD5RXT

    P.S. I likewise experienced an insufferable variability in the touch point that was being detected when touching near the edges of my PJRC touchscreen (which made it almost impossible to layout my graphical touch sliders all the way to the edge of my screen). Turns out in my particular case, I was causing my own problem by trying to read the touchscreen way too quickly. A simple delay between touchscreen reads fixed the particular problem that I was seeing in my project. Hopefully yours turns out to be equally easy to find & fix. MJC

  8. #8
    Senior Member
    Join Date
    Jun 2017
    Posts
    153
    Mark,

    Do you happen to remember what delay you found to be most effective? Where you just delaying, or averaging multiple readings?

    To address your thoughts about the pressure variation being due to stylus pressure variations as a result of hand position/rotation, I ran another experiment where I first drew a rectangle in the original orientation to verify that the 'low output' phenomenon still existed (it did) and then physically rotated the entire prototype assembly 180 degrees so that now the UL corner was originally the LR corner. Then I drew the same rectangle using the same technique (as near as I could tell, anyway) and recorded the result in the chart shown below

    Click image for larger version. 

Name:	210228 LargeRectangleRotated180ZValues.jpg 
Views:	2 
Size:	87.0 KB 
ID:	23874

    As I think you can see, now the second corner is the low output one, and this is the same physical corner as before. If the low output was occurring due to different pressure imposed by a biomechanics issue of some sort, I would expect it would show up in the third corner, not the second.

    Thoughts?

  9. #9
    Senior Member
    Join Date
    Jul 2020
    Posts
    897
    Quote Originally Posted by paynterf View Post
    As I think you can see, now the second corner is the low output one, and this is the same physical corner as before. If the low output was occurring due to different pressure imposed by a biomechanics issue of some sort, I would expect it would show up in the third corner, not the second.

    Thoughts?
    Had another look at the XPT2046 library code and it doesn't calculate Z values as per the datasheet, so its
    sentitivity is inherently poor in one corner. The raw readings of x, y, z1, z2 have to be combined in an
    equation to determine the touch resistance, and this equation requires knowing the x and y resistances of
    the particular touchscreen to be properly calibrated, although I think only the ratio between them matters
    so its not so critical (but not applying the equation is always going to be poor).

  10. #10
    Senior Member
    Join Date
    Jun 2017
    Posts
    153
    Interesting - I had seen some documentation in some of the Adafruit example code about measuring the X & Y resistance values, but since there seemed no way to do that with the PJRC displays using the XPT2046 chip I basically ignored it.

    Is there a way to measure these values? I don't see anything obvious on my display. I guess I could cheat by reverse engineering the values needed to normalize the pressure readings in all four corners ;-)

    Frank

  11. #11
    Senior Member
    Join Date
    Jul 2020
    Posts
    897
    Unplug it, stick a multimeter on X-/X+, and Y-/Y+...

  12. #12
    Senior Member
    Join Date
    Apr 2020
    Location
    DFW area in Texas
    Posts
    229
    Quote Originally Posted by paynterf View Post
    Mark,

    Do you happen to remember what delay you found to be most effective? Where you just delaying, or averaging multiple readings?

    [snipped]

    As I think you can see, now the second corner is the low output one, and this is the same physical corner as before. If the low output was occurring due to different pressure imposed by a biomechanics issue of some sort, I would expect it would show up in the third corner, not the second.

    Thoughts?
    Frank:

    Yup, your 180 test confirms that (as you put it) "biomechanics" is not a major contributing factor . . . well done !!

    My current project uses a millis() comparison set at 200ms (in loop(), don't take another touchscreen reading unless/until 200ms have elapsed since the last reading) & no averaging, but in my experimentation, I started seeing a positive effect at 100ms between readings. My first stab at averaging (keeping a running average, 5-values deep) caused a different problem: as my touchpoints moved across the screen (touch a point on a slider towards the left-hand side of the screen, release, then touch a point on a different slider towards the right-hand side of the screen), the touch point averaging was triggering sliders everywhere in between as the average made its way from the left-hand touch to the right-hand touch . . . most likely just very bad coding !! Simply delaying between reads settled things well enough that I did not need the additional averaging.

    Mark J Culross
    KD5RXT

  13. #13
    Senior Member
    Join Date
    Jun 2017
    Posts
    153
    MarkT,

    That is a very good idea, but I don't have a clue where to find the X-/X+ and Y-/Y+ terminals. There's nothing labeled like that anywhere on the display I have from PJRC (or eBay), and I've even popped the display out of its spring-loaded clips to have a look at the back.

    Can someone post a photo showing how to access these terminals

    TIA,

    Frank

  14. #14
    Senior Member
    Join Date
    Jul 2020
    Posts
    897
    Resistive touchscreens are an overlay, typically having a 4 wire flat-flex cable going the PCB in a different place to the
    main CoG flatflex.

  15. #15
    Senior Member
    Join Date
    Jun 2017
    Posts
    153
    MarkT,

    I understand the physics - I just can't find a way to physically access the X+/X- & Y+/Y- wires. Here's a photo of the back of the display, showing the flex cable routing. There doesn't appear to be any easy way to put a probe on these wires - am I missing something?

    Click image for larger version. 

Name:	IMG_4058.jpg 
Views:	4 
Size:	115.9 KB 
ID:	23883

  16. #16
    Senior Member
    Join Date
    Jul 2020
    Posts
    897
    Well I guess you just have to assume they are the same, or close enough, and apply the equations anyway - the
    test circuit is ratiometric so the absolute resistance isn't important.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •