Slowing/Debouncing touch data from SMPTE610

I’ve built a simple number keypad using the Adafruit 2.8" TFT with resistive touch screen, using the SMTPE610 and ILI9341 libraries. It’s currently running on an Arduino Uno, but will port over to Particle soon…

My issue is that I’m unable to get usable data…one key press causes several number outputs. My hypothesis is that the touch screen is reading key presses so fast, that a simple ‘touch’ of a “4” puts several “4’s” in the buffer (for example).

I’ve tried doing things in my sketch to take the first number and throw out the remaining data, but haven’t found a good solution.

Also thought maybe I could tell the library to slow down, but not really sure how I’d do that…

Anyone familiar with these libraries have any good ideas?

I guess you’d need to do what you’d do with a physical button too.
A key press is registered on touch but only processed on release. This ensures to only ever get one trigger while keeping the key touched.

2 Likes

If you are sure you are getting a stream of button down signals whilst your finger is on the key then you could either just record a key press when released or if this bounces (?) you should put a simple debounce/release edge detection in. Some like this would work.

// Service routine called by a timer interrupt
bool_t DebounceSwitch2()
{
    static uint16_t State = 0; // Current debounce status
    State=(State<<1) | !RawKeyPressed() | 0xe000;
    if(State==0xf000)return TRUE;
    return FALSE; 
}

Returns TRUE once (only) when the debounced leading edge of the switch closure is encountered.

DebounceSwitch2() gets called regularly by a timer tick or similar scheduling mechanism. It shifts the current raw value of the switch into variable State. Assuming the contacts return zero for a closed condition, the routine returns FALSE till a dozen sequential closures are detected.

One bit of cleverness lurks in the algorithm. As long as the switch isn’t closed ones shift through State. When the user pushes on the button the stream changes to a bouncy pattern of ones and zeroes, but at some point there’s the last bounce (a one) followed by a stream of zeroes. The OR 0xe000 creates a “don’t care” condition in the upper bits. But as the button remains depressed State continues to propagate zeroes. There’s just the one time, when the last bouncy “one” was in the upper bit position, that the code returns a TRUE. That bit of wizardry eliminates bounces and detects the edge, the transition from open to closed. You can change the two hex constants to accommodate different bounce times and timer rates.

1 Like

Thanks so much @ScruffR and @armor! :+1:

@ScruffR, I guess I could use a version of the following to do that:

  if (!ts.touched()) {
    return;
  }

@armor, very clever bitwise approach…wizardry indeed! :wink: Seems like a very slick way to do it…

I came up with this little approach last night which is working well, but what do you think? Too clunky?

#define INTERVAL 200  // Defines time interval for reading keys, in milliseconds

  void loop() {
  
  while (ts.bufferEmpty()) {        // Wait in this while loop until touched
//    "Waiting..."
  }

  unsigned long currentMillis = millis();               // Get current time
  unsigned long previousMillis = millis();              // Get current time
  while ((currentMillis - previousMillis) < INTERVAL)   // Do while time is less than INTERVAL
  {
    TS_Point p = ts.getPoint();                         // getPoint()
    currentMillis = millis();                           // Update currentMillis with current time
  }
 
// RETRIVE A POINT, SCALE TO X,Y // 
  TS_Point p = ts.getPoint();
  p.x = map(p.x, TS_MINX, TS_MAXX, 0, tft.width());     // Scale from ~0->4000 to tft.width using the calibration #'s
  p.y = map(p.y, TS_MINY, TS_MAXY, 0, tft.height()); 

}

I figured this way, the ts.getPoint() buffer would be read until it was cleared out. This is just for a password entry and functional user interface, so I doesn’t really need it to be fast…

Thoughts?