Adafruit Industries, Essential service and business: NYC – Executive Order 202.6 - Read more. Accepting essential orders - here's how.
0

Touch Screen - singel signal for touch input
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

Touch Screen - singel signal for touch input

by Resiak on Sat Feb 04, 2017 1:25 pm

Hi,
i am developing a touch GUI to controll stepper motors. I am new to arduino and C++ coding... .Untill now i got through really well and totally enjoy it! :-) However i am stuck with a problem i just cant get a solution for... .
My hardware consits of an Ardunio UNO with the Adafrui motorshield v2 stacked onto an the 2.8" TFT Touch Shield for Arduino with Resistive Touch Screen from adafruit.

So far i've made several bottons which work fine and set the motos ins motion.

However when the botton is pressed and not released fast enough the arduino "thinks" the botton is hitted twice, three times... or even more times. Thus the suppoedly one hit on the Touchscreen botton leads to multiple signals (which should be only one)... .

Is there a way to only get a signal when the botton is hit and than released? or the resistive signal is "lost" within the botton borders? Or to only allow one hit per second?.. Thus not getting multiple hits during the supposedly one bottons press?

I hope the question in not too stupid. I searched this forum however could not really find something.

For the touchscreen i use
Adafruit_GFX.h, Adafruit_ILI9341.h, Adafruit_STMPE610.h libs

an typical botton hit looks like.
Code: Select all | TOGGLE FULL SIZE
if ((y>feinBtPosFrameY) && (y <= (feinBtPosFrameY+50)))
      {
         //hit neg  botton
         if((x>feinBtPosFrameX) && (x < (feinBtPosFrameX + 50)))
         {
            Serial.println(" hit NEG fein ");
            fineFoc->step(stepsFeinV, BACKWARD, INTERLEAVE);
         }


i used the adafruit example of the onoff Botton from the ILI9341 to get started ... .

I hope everthing could be understood (non native english speaker here).

Thanks for the read and i hope there is a easy solution.

greetings

Resiak
 
Posts: 10
Joined: Wed Nov 09, 2016 7:10 pm

Re: Touch Screen - singel signal for touch input

by jim_lee on Sun Feb 05, 2017 4:05 am

When you see the button go down, wait for, say.. 50ms then hold-(loop) 'till it releases. THEN do your button action.

Hope this helps.

-jim lee

jim_lee
 
Posts: 600
Joined: Thu May 24, 2012 8:24 pm

Re: Touch Screen - singel signal for touch input

by asteroid on Sun Feb 05, 2017 5:21 am

The following source code uses the data from a single hit to change a control value by +/- 1. As you have discovered, a single hit generates multiple point values, the number depending on the duration of the touch, which causes the control value to change by a varying amount. This work around places a counter on the data points and uses only the third point (counter == 2); the first two (0,1) and any point greater than three are ignored. The first two are ignored because they contain the values from the preceding hit and if used, would cause stray hits on the screen to generate a data value change even though the touch did not occur in the control area. To prevent this from happening, I attempted to use writeRegister8(STMPE_INT_STA, 0xFF); to reset all integers after the touch ended, but was unable to get it to work for this purpose. I realize that this solution is not ideal, but perhaps will work until a better one can be found.

Code: Select all | TOGGLE FULL SIZE
/*
 * Demonstrates little arrows (vertical)
 * For Adafruit 2.8" resistive touch screen.
 * Any of the four screen rotations may be used.
*/

#include <SPI.h>
#include <Wire.h>
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341.h"
#include "Adafruit_STMPE610.h"

// Default values for Adafruit shield v2.
#define STMPE_CS 8
#define TFT_DC 9
#define TFT_CS 10

Adafruit_STMPE610 ts = Adafruit_STMPE610(STMPE_CS);
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);

// 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

#define TS_MINX 150
#define TS_MINY 130
#define TS_MAXX 3800
#define TS_MAXY 4000

 typedef struct {
  int left;
  int top;
  int width;
  int height;
 }rect;

 typedef struct{
  int Min;
  int Max;
  int Init;
  int Step;
 }arrowRec;

 // Rotations 0,2 = portrait  : 0->USB=right,upper : 2->USB=left,lower
 // Rotations 1,3 = landscape : 1->USB=left,upper  : 3->USB=right,lower
 const int rotation = 3; //(0->3)
 int x, y;
 TS_Point p;

 //arrowRec{Min, Max, Init, Step}
 arrowRec arrw = {0,100,0,1};

 const int arrwWidth = 44;
 const int arrwHeight = 44;
 const int arrwDisplayWidth = 100;
 const int arrwDisplayHeight = 44;
 
 int arrwValue = arrw.Init;
 char arrwValueStr[5];
 int counter = 0;
 
 rect arrwFrameR = {180, 70, arrwWidth, arrwHeight*2 };
 rect upArrwR = {arrwFrameR.left, arrwFrameR.top, arrwWidth, arrwHeight};
 rect dwnArrwR = {arrwFrameR.left, arrwFrameR.top+arrwFrameR.height/2, arrwWidth, arrwHeight };
 rect arrwDisplayR = {arrwFrameR.left-arrwDisplayWidth-10, arrwFrameR.top+arrwFrameR.height/2-arrwDisplayHeight/2, arrwDisplayWidth, arrwDisplayHeight};
 TS_Point upArrwTip, upArrwRBase, upArrwLBase;
 TS_Point dwnArrwTip, dwnArrwRBase, dwnArrwLBase;
 
 void showArrwValue(int arrowValue)
 {
  tft.setCursor(arrwDisplayR.left+20, arrwDisplayR.top+12);
  tft.setTextColor(WHITE, BLUE);
  tft.setTextSize(3);
  sprintf(arrwValueStr,"%03d",arrowValue);
  tft.print(arrwValueStr);
 }
 
 void littleArrows()
 {
  tft.drawRect( arrwFrameR.left, arrwFrameR.top, arrwFrameR.width, arrwFrameR.height, WHITE);
  upArrwTip.x = upArrwR.left+upArrwR.width/2;
  upArrwTip.y = upArrwR.top+5;
  upArrwLBase.x = upArrwR.left+5;
  upArrwLBase.y = upArrwR.top+upArrwR.height-5;
  upArrwRBase.x = upArrwR.left+upArrwR.width-5;
  upArrwRBase.y = upArrwR.top+upArrwR.height-5;
  tft.fillTriangle( upArrwTip.x, upArrwTip.y, upArrwLBase.x, upArrwLBase.y, upArrwRBase.x, upArrwRBase.y, WHITE);
  dwnArrwTip.x = dwnArrwR.left+dwnArrwR.width/2;
  dwnArrwTip.y = dwnArrwR.top+dwnArrwR.height-5;
  dwnArrwLBase.x = dwnArrwR.left+5;
  dwnArrwLBase.y = dwnArrwR.top+5;
  dwnArrwRBase.x = dwnArrwR.left+dwnArrwR.width-5;
  dwnArrwRBase.y = dwnArrwR.top+5;
  tft.fillTriangle( dwnArrwTip.x, dwnArrwTip.y, dwnArrwLBase.x, dwnArrwLBase.y, dwnArrwRBase.x, dwnArrwRBase.y, WHITE);
  tft.drawRect( arrwDisplayR.left, arrwDisplayR.top, arrwDisplayR.width, arrwDisplayR.height, WHITE);
  showArrwValue(arrw.Init);
 }

 void upArrowHandler()
 {
  arrwValue = arrwValue + arrw.Step;
  if(arrwValue > arrw.Max) arrwValue = arrw.Min;
  showArrwValue(arrwValue);
  Serial.println("================");
  Serial.println("up arrow hit.");
  Serial.println("================");
 }
 
 void downArrowHandler()
 {
  arrwValue = arrwValue - arrw.Step;
  if(arrwValue < arrw.Min) arrwValue = arrw.Max;
  showArrwValue(arrwValue);
  Serial.println("&&&&&&&&&&&&&&&&");
  Serial.println("down arrow hit.");
  Serial.println("&&&&&&&&&&&&&&&&");
 }
 
 void showZeroZero()
 {
  tft.setCursor(0, 0);
  tft.setTextColor(WHITE, BLUE);
  tft.setTextSize(2);
  tft.print("0,0");
 }
 
 void setup() {
  Serial.begin(9600);
  tft.begin();
  ts.begin();
  if (! ts.begin()) {
    Serial.println("Couldn't start touchscreen controller");
    while (1);
  }
  tft.setRotation(rotation);
  tft.fillScreen(BLUE);
  littleArrows();
  showZeroZero();
}

void loop() {
  //unmapped coordinates which will not correspond to rectangle being hit.
  p = ts.getPoint();
 if (ts.touched()) {
  // map coordinates depending on rotation of screen
  switch(rotation) {
  case 0:
   x = map(p.x, TS_MINX, TS_MAXX, 0, tft.width());
   y = map(p.y, TS_MINY, TS_MAXY, 0, tft.height());
   break;
  case 1:
  // p.x, p.y reversed // 
   x = map(p.y, TS_MINY, TS_MAXY, 0, tft.width());
   y = map(p.x, TS_MAXX, TS_MINX, 0, tft.height());
   break;
  case 2:
   x = map(p.x, TS_MAXX, TS_MINX, 0, tft.width());
   y = map(p.y, TS_MAXY, TS_MINY, 0, tft.height());   
   break;
  case 3:
  // p.x, p.y reversed //
   x = map(p.y, TS_MAXY, TS_MINY, 0, tft.width());
   y = map(p.x, TS_MINX, TS_MAXX, 0, tft.height());
   break;
   }
  Serial.print("counter = ");
  Serial.println(counter);
  Serial.print("x = ");
  Serial.print(x);
  Serial.print(" : y = ");
  Serial.println(y);
  Serial.print("upArrw.left = ");
  Serial.print(upArrwR.left);
  Serial.print(" : upArrw.top = ");
  Serial.println(upArrwR.top);
  if(x > upArrwR.left && x < upArrwR.left + upArrwR.width ){
    if(y > upArrwR.top && y < upArrwR.top + upArrwR.height ){
      if(counter == 2 ){ upArrowHandler(); }   
     }
    }
    if(x > dwnArrwR.left && x < dwnArrwR.left + dwnArrwR.width){
     if(y > dwnArrwR.top && y < dwnArrwR.top + dwnArrwR.height){
      if(counter == 2 ){ downArrowHandler(); }
     }
    }   
    counter++;
    }else {
    // not touched, so reset counter to zero 
    counter = 0;
    }
  }

asteroid
 
Posts: 298
Joined: Tue Oct 22, 2013 9:10 pm

Re: Touch Screen - singel signal for touch input

by Resiak on Sun Feb 05, 2017 7:12 am

jim_lee wrote:When you see the button go down, wait for, say.. 50ms then hold-(loop) 'till it releases. THEN do your button action.

Hope this helps.

-jim lee


I tryed the delay(100) function. I just read about the millis() timer, which ill try out right now.

@Asteroid: the idea with the couter seems to be the best and most functional!

Ill try both out and let u guys know thanks for the answeres!

Edit: So i actually set for the counter-solution, it seemed to be the more correct way.

And it works like a charm! :-)
Thanks a lot for it!

Resiak
 
Posts: 10
Joined: Wed Nov 09, 2016 7:10 pm

Please be positive and constructive with your questions and comments.