GIGA Display Touch samples pipeline info

@Cavagnis

I'm trying to understand when the GIGA Display Touch takes a sample and how it queues the data. I have a situation where a single touch results in two events in my code and the obvious things haven't worked for me to resolve it yet.

#include "Arduino_GigaDisplayTouch.h"
Arduino_GigaDisplayTouch touchDetector;

void setup() {
  Serial.begin(115200);
  while (!Serial) {}
  if (touchDetector.begin()) {
    Serial.println("Touch controller init - OK");
  } else {
    Serial.println("Touch controller init - FAILED");
    while (1) {}
  }
}
int taskCounter;
void loop() {
  uint8_t contacts;
  GDTpoint_t points[5];
  contacts = touchDetector.getTouchPoints(points);
  if (contacts > 0) {
    Serial.print("Contacts: ");
    Serial.println(contacts);
    for (uint8_t i = 0; i < contacts; i++) {
      Serial.print(points[i].x);
      Serial.print(" ");
      Serial.println(points[i].y);
    }
    // Do task here triggered by touch
    // Why does this run twice for each touch tap???
    Serial.print("Doing the task now ");
    Serial.println(taskCounter++);
    delay(2000);
  }
  delay(1);
}

Here's the GIGA Display Touch polling Example with very slight modification to show the issue. Run this code on a GIGA with a Display Touch attached, make one quick tap anywhere on the screen and see two task running messages in the Serial Console.

Note how the coordinates for the second task are identical to the first task. And note that those identical coordinates are returned by the touchDetector 2 seconds after the initial touch. So a call to touchDetector can apparently return coordinates from a previous touch, even if no touch is currently occurring.

So it would seem there's some buffering or queuing occurring but I haven't figured out how to characterize it yet. I've tried reading the touchDetector multiple times at the first touch in an attempt to drain any buffering, but I still got the phantom touch when I called touchDetector two seconds later.

And this seems the opposite of the typical approach of ignoring any touches that occur within 250 ms of a prior touch. In this case a phantom touch is being detected 2 seconds after a valid touch. The phantom touch even occurs if I wait 40 seconds to check touchDetector again.

Does anyone have any experience with this or any ideas of how to work around it?

Jo, did you resolve this problem with the second touch event - I have the same problem here.

Geoff

Geoff

Here’s the code I came up with. Basically I ignore apparent button presses that come in too close together.

Hope that helps.

Cheers, Joe

//Check touch screen
////Touch_getXY() updates global vars
int touch_x, touch_y, touch_trackId, touch_area;
unsigned long lastTouch = 0, threshold = 250;

void InitTouch() {
//Setup touch screen
if (touchDetector.begin()) {
Log.verboseln("Touch controller init - OK");
} else {
Log.verboseln("Touch controller init - FAILED");
}
}

bool Touch_getXY(void) {
static GDTpoint_t priorPoint;
uint8_t contacts;
GDTpoint_t firstPoint, points[5];
bool pressed;
contacts = touchDetector.getTouchPoints(points);

if (contacts > 0) {
// Serial.print("Contacts: ");
// Serial.println(contacts);

for (uint8_t i = 0; i < contacts; i++) {
  // Serial.print(points[i].x);
  // Serial.print(" ");
  // Serial.println(points[i].y);
  // printf("x:%d y:%d track:%d area:%d\n", points[i].x, points[i].y, points[i].trackId, points[i].area);
  // Log.verbose("Touch_getXY()  Contact:%d x:%d y:%d track:%d area:%d\n", (i + 1), points[i].x, points[i].y, points[i].trackId, points[i].area);
}

firstPoint = points[0];
// If this point is exactly the same as the prior point then ignore it.
bool samePoints = (firstPoint.x == priorPoint.x && firstPoint.y == priorPoint.y && firstPoint.trackId == priorPoint.trackId && firstPoint.area == priorPoint.area);

pressed = (!samePoints && (millis() - lastTouch > threshold));  // maybe check pressure here
if (pressed) {
  // may not need for all 4 cases
  const int TS_LEFT = 10, TS_RT = 473, TS_TOP = 8, TS_BOT = 793;
  switch (tft.getRotation()) {
    case 0:
      touch_x = map(firstPoint.x, TS_LEFT, TS_RT, 0, tft.width());
      touch_y = map(firstPoint.y, TS_TOP, TS_BOT, 0, tft.height());
      break;
    case 1:
      touch_x = map(firstPoint.y, TS_TOP, TS_BOT, 0, tft.width());
      touch_y = map(firstPoint.x, TS_RT, TS_LEFT, 0, tft.height());
      break;
    case 2:
      touch_x = map(firstPoint.x, TS_RT, TS_LEFT, 0, tft.width());
      touch_y = map(firstPoint.y, TS_BOT, TS_TOP, 0, tft.height());
      break;
    case 3:
      touch_x = map(firstPoint.y, TS_BOT, TS_TOP, 0, tft.width());
      touch_y = map(firstPoint.x, TS_LEFT, TS_RT, 0, tft.height());
      break;
  }
  // Serial.print(points[0].x, DEC);
  // Serial.print(",");
  // Serial.print(points[0].y, DEC);
  // Serial.print(" ");
  // Serial.print(touch_x, DEC);
  // Serial.print(",");
  // Serial.println(touch_y, DEC);
  touch_trackId = firstPoint.trackId;
  touch_area = firstPoint.area;
  priorPoint = firstPoint;
  lastTouch = millis();
}
return pressed;

}
}

Dear Joe

Thanks for the feed back, I had tried this approach without any success. The second touch seems to come much later in my case. What I am now trying is to compare the second (duplicated) touch with the first one and if the (X,Y)s are identical then I ignore it. This seems to work but at the risk of missing a real touch at the identical point (perhaps not likely)!

Geoff