If...Else problem with repeating touch, ILI9341 TFT

Status
Not open for further replies.

Matadormac

Well-known member
Good morning.

I feel this is likely a silly logic issue I can't see my way out of but after several days of not solving it I think I am "blind" to the root problem and can't make this work.

I am working on a sketch to set the RTC on the Teensy. Right now I have fields for day, month, year, hour, minute, numbers and delete.

If you click/select the "Year" button, the field comes up and the touches are limited. But, if you select "Month" then the field comes up but the touches continue.

I am using Arduino 1.6.7 on Windows 10 using Teensy 1.2.7 beta 2 and the Teensy microcontroller is 3.2

I am going to feel silly I think but this is now driving me around the bend!https://forum.pjrc.com/images/smilies/redface.png

Here is the sketch code and the buttons are defined in the attached file:
Code:
#include <SPI.h>
#include <Wire.h>
#include <ILI9341_t3.h>
#include <XPT2046_Touchscreen.h>
#include <TimeLib.h>
#include <font_Arial.h> // from ILI9341_t3
#include "Calc_Buttons.h"


// This is calibration data for the raw touch data to the screen coordinates
#define TS_MINX 240
#define TS_MINY 325
#define TS_MAXX 3700
#define TS_MAXY 3670


#define CS_PIN 8
//XPT2046_Touchscreen ts(CS_PIN);
#define TFT_CS 10
#define TFT_DC  9
#define TIRQ_PIN  2
ILI9341_t3 tft = ILI9341_t3(TFT_CS, TFT_DC);
//XPT2046_Touchscreen ts(CS_PIN, TIRQ_PIN);  // Param 2 - Touch IRQ Pin - interrupt enabled polling
XPT2046_Touchscreen ts(CS_PIN);


struct TS_MAP {
  int16_t xt;
  int16_t xb;
  int16_t yl;
  int16_t yr;
};

TS_MAP tsMap[4] = {   { 0, 319, 0, 239 }, { 319, 0, 0, 239 }, { 319, 0, 239, 0 }, { 0, 319, 239, 0 } };
int16_t TS_Rotate = 1;


//===================================================
// variables to be used in this sketch
int All;
int SetTimeAndDate;
int NeedYear;
int NeedMonth;
int NeedDay;
int NeedHour;
int NeedMinute;
int InfoNeeded;
int noTouchLong = 0;
int DateTimeSet = 0;
//====================================================
//Strings we will need to use
String TheYear, TheMonth, TheDay, TheHour, TheMinute, TheSecond;

//====================================================

void setup(void)
{
  // set the Time library to use Teensy 3.0's RTC to keep time
  setSyncProvider(getTeensy3Time);

  Serial.begin(9600);
  while ( !Serial && (millis() < 2000)) ;
  tft.begin();
  ts.begin();
  if (!ts.begin()) {
    Serial.println("Unable to start touchscreen.");
  }
  else {
    Serial.println("Touchscreen started.");
  }
  int SetTimeAndDate = 0;
  // delay(100);
  tft.fillScreen(ILI9341_BLUE);
  TS_Rotate = 0;
  tft.setRotation(1 + TS_Rotate);
  //  tft.setRotation(3);

  SetDate();
  //  TimeButton();
  //  SetTimeButton();
  noTouchLong = 0;
  int  DateTimeSet = 0;
}
//========================================================================
boolean wastouched = true;
elapsedMillis waitTouch;
elapsedMillis noTouch;
TS_Point p;
//=========================================================================

void loop() {
  // put your main code here, to run repeatedly:

  if (waitTouch > 100)  {
    if ( ts.touched()) {
      p = ts.getPoint();
      Serial.print("Pressure = "); Serial.print(p.z);  Serial.print(", x = ");
      Serial.print(p.x); Serial.print(", y = "); Serial.print(p.y);  Serial.println();
      if ( !TS_GetMap( p.x, p.y ) ) {
        return;
      }      //Get Year Button
      if ((p.x > 3) && (p.x < (78))) {
        if ((p.y > 6) && (p.y <= (40))) {
          delay(200);
          Serial.print("SetTimeAndDate is now "); Serial.println(SetTimeAndDate);
          Serial.println("What Year is it button hit");
          tft.drawRoundRect(85, 6, 70, 35, 10, ILI9341_WHITE);
          InfoNeeded = 1; //Code for "InfoNeeded" is
          // NeedYear is 1, NeedMonth is 2, NeedDay is 3, NeedHour is 4, NeedMinute is 5
          Serial.print("InfoNeeded is now "); Serial.println(InfoNeeded);
          Serial.println();
        }
        delay(100);
        noTouch = 0;
      }
      waitTouch = 0;
    }
    else {
      //=======================================================
      //   3, 46, 88, 35, 10, Get Month Button
      if ((p.x > 3) && (p.x < (85)))  {
        if ((p.y > 46) && (p.y <= (80))) {
          delay(200);
          Serial.print("SetTimeAndDate is now "); Serial.println(SetTimeAndDate);
          Serial.println("What Month is it button hit");
          tft.drawRoundRect(98, 46, 40, 35, 10, ILI9341_WHITE);
          InfoNeeded = 2;
          Serial.print("InfoNeeded is now "); Serial.println(InfoNeeded);
          Serial.println();
        }
        delay(100);
        noTouch = 0;
      }
      waitTouch = 0;
    }
  }
}

//=====================================================
// END OF LOOP SECTION

#define TS_DEBOUNCE 2 // TX_Map() debounce factor
boolean TS_GetMap( int16_t &xx, int16_t &yy )
{
  static int16_t xxo = 500, yyo = 500;  // Store old/last returned x,y point
  if (!ts.touched()) return false;
  p = ts.getPoint();
  xx = map(p.x, TS_MINX, TS_MAXX, tsMap[TS_Rotate].xt, tsMap[TS_Rotate].xb);
  yy = map(p.y, TS_MINY, TS_MAXY, tsMap[TS_Rotate].yl, tsMap[TS_Rotate].yr);
  if (TS_Rotate % 2) {
    int16_t swap = xx;
    xx = yy;
    yy = swap;
  }
  // Debounce by +/-# pixel to minimize point jitter
  if ( ((xxo - TS_DEBOUNCE) <= xx) && ((xxo + TS_DEBOUNCE) >= xx) ) xx = xxo; else xxo = xx;
  if ( ((yyo - TS_DEBOUNCE) <= yy) && ((yyo + TS_DEBOUNCE) >= yy) ) yy = yyo; else yyo = yy;
  return true;
}

//================================================================
void digitalClockDisplay() {
  // digital clock display of the time
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.print(" ");
  Serial.print(day());
  Serial.print(" ");
  Serial.print(month());
  Serial.print(" ");
  Serial.print(year());
  Serial.println();
  tft.fillRoundRect(3, 96, 314, 51, 10, ILI9341_RED);
  tft.drawRoundRect(3, 96, 314, 51, 10, ILI9341_WHITE);
  tft.setCursor(10, 101);
  tft.setTextColor(ILI9341_WHITE);
  tft.setTextSize(2);
  tft.print( "Time: "); tft.print(hour()); tft.print(":"); tft.print(minute());
  tft.print(":"); tft.println(second());
  tft.setCursor(10, 126);
  tft.print( "Date: "); tft.print(day()); tft.print(" "); tft.print(month()); tft.print(" ");
  tft.println(year());
  //}
}

time_t getTeensy3Time()
{
  return Teensy3Clock.get();
}



void printDigits(int digits) {
  // utility function for digital clock display: prints preceding colon and leading 0
  Serial.print(":");
  if (digits < 10)
    Serial.print('0');
  Serial.print(digits);
}

/**************************************************************************/


[ATTACH]6268._xfImport[/ATTACH]
 
You're checking of the month button happens outside of
Code:
if ( ts.touched()) {
...
}

You should put it inside this check:
Code:
void loop() {
  if (waitTouch > 100)  {
    if ( ts.touched()) {
      p = ts.getPoint();
      Serial.print("Pressure = "); Serial.print(p.z);  Serial.print(", x = ");
      Serial.print(p.x); Serial.print(", y = "); Serial.print(p.y);  Serial.println();

      if ( !TS_GetMap( p.x, p.y ) ) {
        return;
      }

      //=======================================================
      // Get Year Button
      if ((p.x > 3) && (p.x < (78))) {
        if ((p.y > 6) && (p.y <= (40))) {
          delay(200);
          Serial.print("SetTimeAndDate is now "); Serial.println(SetTimeAndDate);
          Serial.println("What Year is it button hit");
          tft.drawRoundRect(85, 6, 70, 35, 10, ILI9341_WHITE);
          InfoNeeded = 1; //Code for "InfoNeeded" is
          // NeedYear is 1, NeedMonth is 2, NeedDay is 3, NeedHour is 4, NeedMinute is 5
          Serial.print("InfoNeeded is now "); Serial.println(InfoNeeded);
          Serial.println();
        }
        delay(100);
        noTouch = 0;
      }

      //=======================================================
      //   3, 46, 88, 35, 10, Get Month Button
      if ((p.x > 3) && (p.x < (85)))  {
        if ((p.y > 46) && (p.y <= (80))) {
          delay(200);
          Serial.print("SetTimeAndDate is now "); Serial.println(SetTimeAndDate);
          Serial.println("What Month is it button hit");
          tft.drawRoundRect(98, 46, 40, 35, 10, ILI9341_WHITE);
          InfoNeeded = 2;
          Serial.print("InfoNeeded is now "); Serial.println(InfoNeeded);
          Serial.println();
        }
        delay(100);
        noTouch = 0;
      }
      waitTouch = 0;
    }
  }
}
 
Last edited:
I need to add the RTC crystal to the Teensy on my display to run this. In the IDE if you click any open or close brace/parenthesis it will highlight the associated one to make the net logic show. I did that and your else clause seemed mis-associated and there was a waitTouch out of place then. There may be more needed - but as it was the else clause was active when "if ( ts.touched()) {" failed.

Perhaps you want this:

Code:
void loop() {
  // put your main code here, to run repeatedly:

  if (waitTouch > 100)  {
    if ( ts.touched()) {
      p = ts.getPoint();
      Serial.print("Pressure = "); Serial.print(p.z);  Serial.print(", x = ");
      Serial.print(p.x); Serial.print(", y = "); Serial.print(p.y);  Serial.println();
      if ( !TS_GetMap( p.x, p.y ) ) {
        return;
      }      //Get Year Button
      if ((p.x > 3) && (p.x < (78))) {
        if ((p.y > 6) && (p.y <= (40))) {
          delay(200);
          Serial.print("SetTimeAndDate is now "); Serial.println(SetTimeAndDate);
          Serial.println("What Year is it button hit");
          tft.drawRoundRect(85, 6, 70, 35, 10, ILI9341_WHITE);
          InfoNeeded = 1; //Code for "InfoNeeded" is
          // NeedYear is 1, NeedMonth is 2, NeedDay is 3, NeedHour is 4, NeedMinute is 5
          Serial.print("InfoNeeded is now "); Serial.println(InfoNeeded);
          Serial.println();
        }
        delay(100);
        noTouch = 0;
      }
      else {
        //=======================================================
        //   3, 46, 88, 35, 10, Get Month Button
        if ((p.x > 3) && (p.x < (85)))  {
          if ((p.y > 46) && (p.y <= (80))) {
            delay(200);
            Serial.print("SetTimeAndDate is now "); Serial.println(SetTimeAndDate);
            Serial.println("What Month is it button hit");
            tft.drawRoundRect(98, 46, 40, 35, 10, ILI9341_WHITE);
            InfoNeeded = 2;
            Serial.print("InfoNeeded is now "); Serial.println(InfoNeeded);
            Serial.println();
          }
          delay(100);
          noTouch = 0;
        }
      }
      waitTouch = 0;
    }
  }
}

BTW: If you init with the INT pin - you can check more often than 100ms at no (less) cost and be more responsive

//XPT2046_Touchscreen ts(CS_PIN, TIRQ_PIN); // Param 2 - Touch IRQ Pin - interrupt enabled polling
 
<edit 4> - This got lost in OP ::
Here is the sketch code and the buttons are defined in the attached file:

<edit 3> - I'm excited to try this as I want to use RTC and with touch is cool

pjrcFRule.PNG

I got it to compile but only a blue screen and Pressure,x,y debug spew out the USB port.

>> This is not defined in my system :: SetDate();

C:\tCode\TOUCH\RTCset_feb02a\RTCset_feb02a.ino: In function 'void setup()':
C:\tCode\TOUCH\RTCset_feb02a\RTCset_feb02a.ino:78:11: error: 'SetDate' was not declared in this scope
SetDate();
^
C:\tCode\TOUCH\RTCset_feb02a\RTCset_feb02a.ino:71:7: warning: unused variable 'SetTimeAndDate' [-Wunused-variable]
int SetTimeAndDate = 0;
^
C:\tCode\TOUCH\RTCset_feb02a\RTCset_feb02a.ino:82:8: warning: unused variable 'DateTimeSet' [-Wunused-variable]
int DateTimeSet = 0;

You didn't include #include "Calc_Buttons.h" ... other ?

<edit>
Also missing ButtonMap.h

Looks like you used my starter code - but to compile is taking adjustments . . .

<edit 2>
An older version with

TS_MAP tsMap[4] = { { 0, 319, 0, 239 }, { 319, 0, 0, 239 }, { 319, 0, 239, 0 }, { 0, 319, 239, 0 } };

instead of this from latest sample ( ColorButtonsMark3 ):

TS_MAP tsMap[5] = { {200, 3700, 325, 3670 }, { 0, 319, 0, 239 }, { 319, 0, 0, 239 }, { 319, 0, 239, 0 }, { 0, 319, 239, 0 } };
 
Last edited:
Hi defragster. I actually wrote most of the complete program but had to come back to this area because I have screwed up with somehow. I did include a link for the calc_buttons.h file but perhaps not with normal messaging protocol, you will find the link for it at the bottom of the sketch code inset. I just ran my mouse over it and it appears to be active for download. I am off to work shortly so I can't try and implement either Xenamor's or your suggestions. Will have to wait for tonight for that. Do let me know if you can't download the calc_buttons.h file and I will redo that or at least add in a different place that file.
Best
 
I can only guess you did upload and it shows in edit, but didn't do insert inline and check after posting, still no file?
 
@Metadormac: Anxious to see the rest of your code - using my 'ill-formed' library start and accessing RTC because I never spent time with that yet - but I may have more crystals than Teensy's so I intend to use them.

Looking at your code - my "'ill-formed' library start" precludes you from needing to do this.

if ((p.x > 3) && (p.x < (78))) {
if ((p.y > 6) && (p.y <= (40)))

By coding the button limits into the button struct - the code handles that. I'll see if I can make it right with the latest version when I see it and maybe I'll understand what I can do to make it less 'ill-formed' - for general usage. But I'm about 5 levels of interrupt deep distracted by other stuff since I started that. Seeing somebody using it is a good reason to get back to it.

BTW: the thread on the button code stuff and the latest updates are here: ILI9341-and-XPT2046-for-Teensy-Touchscreen-320x240-display
 
Last edited:
@Metadormac: I finally scrolled down in the embedded
Code:
 block and found the uploaded file.

I have your button drawn screen displayed.  And I see the bits of debug text coming out . . . I'm not clear yet what is going on where and how far along you are . . . 

It seems you used mapping parts of the code I published - but perhaps it poor clarity ( especially that early work [not that I added any docs]) left lots of specific code drawing buttons rather than working within the BUTTONS struct usage I was working toward.
 
Status
Not open for further replies.
Back
Top