Problem correctly reading touch screen

EL Wire/Tape/Panels, LEDs, pixels and strips, LCDs and TFTs, etc products from Adafruit

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
bradv
 
Posts: 35
Joined: Sat Feb 22, 2014 2:38 am

Problem correctly reading touch screen

Post by bradv »

I have a Mega 2560 hooked to an RA8875 and 5" display with touch screen and a DS1307 RTC.
Am trying to debug a routine to set the RTC.
My touch screen reads from the main screen menu work fine. i.e. when I touch the "4 button" I get a "4" returned.
For the clock set routine, I drew a 10 key pad with an enter button on the display and get the key "hits" logged reliably.
When I try to read a screen touch from the clock set routine, I keep getting a double "hit" giving me the same number (return) twice for each touch screen event.

Here is the set clock routine

Code: Select all

void setTime()
{
  char setBuffer[32];
  int setMonth = 0;
  int setDay = 0;
  int setYear = 2014;
  int setHour = 0;
  int setMinute = 0;
  int setSecond = 0;
  
  tft.fillScreen(RA8875_BLACK);
  tft.textMode();
  tft.textEnlarge (2);
  tft.textSetCursor(80,50);
  tft.textTransparent(RA8875_GREEN);
  tft.textWrite("Set Time");
  tft.textTransparent(RA8875_WHITE);
  tft.textSetCursor(60,150);
  tft.textWrite("mm/dd/yyyy");
  tft.textSetCursor(60,200);
  tft.textWrite("hh:mm:ss");
  DrawNumKeypad ();
  tft.textMode();

  sprintf( setBuffer, 
     "%02d/%02d/%4d  %02d:%02d:%02d",
     setMonth, setDay, setYear, setHour, setMinute, setSecond);
 
  tft.textSetCursor(60,250);
  tft.textTransparent(RA8875_WHITE);  
  tft.textWrite( setBuffer );

  for(int x=0; x<12; x++)
  {
  GetNumKey ();
  if (numKeyPress <0) x--;
  delay(200);
  tft.textSetCursor(60,250);
  tft.textTransparent(RA8875_BLACK);  
  tft.textWrite( setBuffer );
  
  if (x == 0) setMonth = numKeyPress * 10 , Serial.println ("Set Month tens");
  if (x == 1) setMonth = setMonth + numKeyPress, Serial.println ("Set Month ones");
  if (x == 2) setDay = numKeyPress * 10 , Serial.println ("Set Day tens");
  if (x == 3) setDay = setDay + numKeyPress, Serial.println ("Set Day ones");
  if (x == 4) setYear = numKeyPress * 1000, Serial.println ("Set Year thousands");
  if (x == 5) setYear = setYear + (numKeyPress * 100), Serial.println ("Set Year hundreds");
  if (x == 6) setYear = setYear + (numKeyPress * 10), Serial.println ("Set Year tens");
  if (x == 7) setYear = setYear + numKeyPress, Serial.println ("Set Year ones");
  if (x == 8) setHour = numKeyPress * 10, Serial.println ("Set Hour tens");
  if (x == 9) setHour = setHour + numKeyPress, Serial.println ("Set Hour ones");
  if (x == 10) setMinute = numKeyPress * 10, Serial.println ("Set Minutes tens");
  if (x == 11) setMinute = setMinute + numKeyPress, Serial.println ("Set Minutes ones");

  sprintf( setBuffer, 
     "%02d/%02d/%4d  %02d:%02d:%02d",
     setMonth, setDay, setYear, setHour, setMinute, setSecond);
Serial.println(setBuffer);
 
  tft.textSetCursor(60,250);
  tft.textTransparent(RA8875_WHITE);  
  tft.textWrite( setBuffer );
  }
  tft.graphicsMode();
  delay(3000);
  welcomeScreen();
}
and here is the routine that reads the key

Code: Select all

int GetNumKey ()
{
  keyPress = '*';
  numKeyPress = 0;
  int keyTouched = 0;
  float xScale = 1024.0F/tft.width();
  float yScale = 1024.0F/tft.height();
delay(200);
  /* Wait around for touch events */
Serial.println("Waiting for touch events ...");
  while(keyTouched == 0)
  {
    if (!digitalRead(RA8875_INT)) 
//Serial.println("Waiting for interrupt ...");
delay(50);
{
      if (tft.touched()) 
      {
//Serial.print("Touch: "); 
        tft.touchRead(&tx, &ty);
//delay(200);
//Serial.print(tx); Serial.print(", "); Serial.println(ty);
        keyTouched = 1;
//        break;
      }
    }
  }
  if (ty > 342 && ty < 440)
  {
    if(tx >684 && tx < 750) keyPress = '7';
    if(tx >775 && tx < 850) keyPress = '8';
    if(tx >872 && tx < 941) keyPress = '9';
  }
  if (ty > 480 && ty < 583)
  {
    if(tx >684 && tx < 750) keyPress = '4';
    if(tx >775 && tx < 850) keyPress = '5';
    if(tx >872 && tx < 941) keyPress = '6';
  }
  if (ty > 623 && ty < 730)
  {
    if(tx >684 && tx < 750) keyPress = '1';
    if(tx >775 && tx < 850) keyPress = '2';
    if(tx >872 && tx < 941) keyPress = '3';
  }
  if (ty > 764 && ty < 865)
  {
    if(tx >684 && tx < 750) keyPress = '0';
    if(tx >775 && tx < 941) keyPress = 'E';
  }
//Serial.print("Key Char = ");Serial.println(keyPress);
//  ****  Turn keypress into integer  ****
  numKeyPress = keyPress - 48;
//  delay(250);
return (numKeyPress,keyPress);
}
What's bugging me is that the call to read the keyboard executes fine and returns the correct result.
Then instead of doing it again for the next key, the result displays and then goes back to "getNumKey()" again returning the same result without touching the screen. Then it correctly waits for the next touch screen event and double hits that one too.
The loop counter exits when 6 touch events have occurred instead of 12.

The code could probably be better written, but I'm not that good with this language.
Sometimes it's hard to figure out what's going on when a function calls a library that calls another library which calls another library, etc.

Any thoughts would be helpful.

User avatar
adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am

Re: Problem correctly reading touch screen

Post by adafruit_support_rick »

The problem is that your code loops much more quickly than you can touch and release a key.
The best approach is to register a "release" event instead of a "touch" event. In your code, instead of performing an action when you detect a touch, set a flag or state variable to indicate that a particular key has been touched. Continue looping until you detect no touch, then execute the action for the last key that was touched.

User avatar
bradv
 
Posts: 35
Joined: Sat Feb 22, 2014 2:38 am

Re: Problem correctly reading touch screen

Post by bradv »

Not the problem, I've tried adding really big delays (5 sec) with no help.
Also the act of reading the touch screen coordinates clears the interrupt line.
Kind of acts as it's own release function.
The real problem isn't in reading the touch screen but in the fact that the main routine (top one)
calls "GetNumKey" and returns correctly but then executes again without resetting the tx and ty parameters.
If I hold down the key, things are slow enough that I get (depending on the delays) about 1 pair of returns per second.
Not 1 or 3 or more returns but exactly 2 every time.
I think I've got something messed up in the program flow but I can't find it.
The only other thing I can think of is that when executed, the "GetNumKey" routine falls right through the waiting for key part the second time but then recovers and acts normally (waiting for a key to be pressed) for the next call.

Thanks for the suggestion anyway. It reminded me that I needed a way to escape the screen if I didn't want to enter any data.

User avatar
bradv
 
Posts: 35
Joined: Sat Feb 22, 2014 2:38 am

Re: Problem correctly reading touch screen

Post by bradv »

Thanks for helping me change my viewport.
I fixed the problem and learned something about string handling.

Brad

User avatar
adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am

Re: Problem correctly reading touch screen

Post by adafruit_support_rick »

Cool. What was the problem?

User avatar
bradv
 
Posts: 35
Joined: Sat Feb 22, 2014 2:38 am

Re: Problem correctly reading touch screen

Post by bradv »

At the heart of the GetNumKey() routine is this code

Code: Select all

  while(keyTouched == 0)
  {
    if (!digitalRead(RA8875_INT)) 
    delay(50);
    {
      while (tft.touched()) 
      {
        tft.touchRead(&tx, &ty);
        delay(50);
        keyTouched = 1;
       }
    }
  }
the original code had "if (tft.touched())" which, as you can see, changed to "while ((tft.touched())".
The if statement allowed the execution to "fall through" getting a new read.
The while statement trapped it there until a the key was released.
I think it has to do with the interaction between the tft.toched() function and how the INT signal is processed.
The last time I wrote any significant code was in the 80's in assembly where I was a lot closer to the hardware and could more easily see what was happening to the hardware.
C is good in that you can produce more results with less effort but you pay for it by removing yourself from the target hardware. I guess the longer you live in the C world the easier it gets.

Thanks for the help.
My project isn't over so you'll probably hear from me again.

User avatar
bradv
 
Posts: 35
Joined: Sat Feb 22, 2014 2:38 am

Re: Problem correctly reading touch screen

Post by bradv »

Since I'm here with the touch screen question, let me ask one more.
I've been scouring the tutorials and can't find what I'm looking for.
I know this must be in every programmers toolbox.
I'm looking for a routine to input multiple, consecutive key press inputs and put them into a single variable.
The inputs would be in the form of decimal or floating point.
i.e. 34, or 456.78
I have keys defined that return "0-9", ".", and "E"(enter).
Any suggestions where to go look?
I'm sure that this has been done a thousand times and am into inventing not re-inventing.
Thanks in advance,
Brad

User avatar
adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am

Re: Problem correctly reading touch screen

Post by adafruit_support_rick »

The simple thing would be to concatenate the keypresses as ASCII characters into a string, then convert the string to an integer using the atoi function.
The other approach would be to add the keypresses as digits to a floating point variable. Multiply by ten before adding another digit. You would need to remember your state, so that, once you see a decimal point, you start dividing the digit by 10, 100, 1,000, etc. before adding it, instead of multiplying the FP variable by 10

User avatar
bradv
 
Posts: 35
Joined: Sat Feb 22, 2014 2:38 am

Re: Problem correctly reading touch screen

Post by bradv »

Kind of already figured that one out.
Just thought someone might have a library for doing all that nice and neat.
My code is still a little messy and not all that compact.

Thanks Again

User avatar
adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am

Re: Problem correctly reading touch screen

Post by adafruit_support_rick »

I've never seen a canned routine like that.

Locked
Please be positive and constructive with your questions and comments.

Return to “Glowy things (LCD, LED, TFT, EL) purchased at Adafruit”