A UBlox GPS Module Primer for beginners

Good luck. Thanks for the offer - you hang on to them for your project. Don't need it right away :)
 
Hey Mike no problem thanks, It's my bday today so I have plenty of family over just wondering if you having any luck with the touch part? ;)
 
Yes and no. Screen is very weird. I run the calibration and touch the four corners no problem. But then I move my finger to see how the calibration worked out its mirrored and flipped so if I touch say the upper right side of the screen the points show up in the lower left. If I go in and change the way map works so its minx,0 instead of 0,minx the that part works but then the rest doesn't. Its either the unit or library or something else. Haven't figured it out yet - need a break from it for a while.
 
I see take a break man, I can't fix this today but you are digging in the right place (it's just the code issue).

The change will have to be done in 2 places:
1st. in
#ifdef TFTCalibration
and
2nd. in
TouchData();
Code:
      if (rotation == 3) { //
        t_y = map(Ty, TS_MINY, TS_MAXY, 0, tft.height());
        t_x = map(Tx, TS_MINX, TS_MAXX, 0, tft.width());
      } else { // rotation == 1
        t_y = map(Ty, TS_MINY, TS_MAXY, tft.height(), 0);
        t_x = map(Tx, TS_MAXX, TS_MINX, 0, tft.width());
      }
 
mjs513 - I worked on a rotatable mapping function that worked well for my ILI9341's - about 2 years back - posted a link for it the other day again. Sounds like the rotation direction changes between the two - or the rotation isn't being taken into account properly in use.

This is a Nov, 2016 link . . . ILI9341_t3-Touch-Screen-Trouble that might lead to a solution.

This post is only 12.5 months old :: Teensy-3-2-ILI9341-Touch-and-SD-wiring-(ILI9341_t-examples)

I forum searched for tsmap - there is a newer one that may end up with the same info
 
Here is it - not even 2 months old:

I made a map function in posts two years ago that is posted on the forum - it doesn't seem to made it into the library or any sketches as I went. KurtE posted a similar version a couple months back.

I just did a BING search and it hits this November 2015 thread/post that may point to examples that should still be on GitHub: https://forum.pjrc.com/threads/31634-ILI9341-and-XPT2046-for-Teensy-Touchscreen-320x240-display

Indeed - here is a link to the tsMap[] array I made that works in all four rotations as 1,2,3,4 where the [0] element is the base number for the X and Y Min and Max in the default rotation on the display I had.

There may be newer versions of the display hardware out with different extents or default rotation.

Code:
TS_MAP tsMap[5] = { {200, 3700, 325, 3670 }, { 0, 319, 0, 239 }, { 319, 0, 0, 239 }, { 319, 0, 239, 0 }, { 0, 319, 239, 0 } };

This code refers to that array and for current rotation (TS_Rotate) gives X and Y from touch point pp.x and pp.y:
Code:
  xx = map(pp.x, tsMap[0].xt, tsMap[0].xb, tsMap[TS_Rotate].xt, tsMap[TS_Rotate].xb);
  yy = map(pp.y, tsMap[0].yl, tsMap[0].yr, tsMap[TS_Rotate].yl, tsMap[TS_Rotate].yr);

<edit>: hopefully that leads you to a good answer. If not check the rest of that thread or similar threads perhaps I gave more details as I evolved that code. If you find a better post please drop it here. If Kurt hasn't gotten his map code into a sample I should hook up a display and get that done. There was a recent add to the library for rotation I didn't follow - rotation was already supported as I used it - perhaps it was improved and this could find a good home in that sample.
 
Good luck. The code on github should show full context and drop in to work for you? Let me know if you find my default edge numbers are common to your display. They were found on the 2.8" touch - and I think they had some variants - and IIRC this was on a 2.4" touch?

To test edges I used a stylus point off all four edges to see MAX and MIN on the edges.
 
Hey Mike can you give this a shot, don't forget (set up your GPS port and TFT pin definitions).

v1.1
Addition: set up touch rotation independent from the screen rotation.
//Rotations 1 or 3 = Landscape mode only ~ 1->TFT conn. Pins on right side: 3->TFT conn. Pins on left side
const int rotation = 3;//(1 or 3 only)
const int TouchRotation = 1;//(1 or 3 only)

# 1 should work on your display i hope.

Code:
// ***********************************************************************************************************
// *(c) Chris O 2018/4 - License: MIT
// * U-Blox UBX-CFG-TP5 (0x06 0x31) Quick configuration editor - ILI9341 TFT + Touch interface
// * v1.1
// *
// * Permission is hereby granted, free of charge, to any person obtaining
// * a copy of this software and associated documentation files (the
// * "Software"), to deal in the Software without restriction, including
// * without limitation the rights to use, copy, modify, merge, publish,
// * distribute, sublicense, and/or sell copies of the Software, and to
// * permit persons to whom the Software is furnished to do so, subject to
// * the following conditions:
// *
// * 1. The above copyright notice and this permission notice shall be
// * included in all copies or substantial portions of the Software.
// *
// * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// * SOFTWARE.
// ***********************************************************************************************************

// ***********************************************************************************************************
// *                            UBLOX GPS - Important set this to the GPS hardware serial port
// ***********************************************************************************************************
#include "UBLOX.h" // Update #4 U-BLOX lib v1.0.3  https://forum.pjrc.com/threads/36103-uBlox-Library/page2
// Set this to the GPS hardware serial port you wish to use
#define GPShwSERIAL 3 // 1 = Serial1, 2 = Serial2, 3 = Serial3, 4 = Serial4 ....

// ***********************************************************************************************************
// *                            RUN TFT Touch Calibration
// ***********************************************************************************************************
// comment or uncomment me.
#define TFTCalibration  // calibrate the touch screen.
//

uint32_t const BaudDefault = 9600; // default settings
// a uBlox object, which is on Teensy hardware
// GPS serial port
UBLOX gps(GPShwSERIAL);
// the uBlox data structure
gpsData uBloxData;

// ***********************************************************************************************************
// *                            TFT
// ***********************************************************************************************************
#include <SPI.h>
#include <Wire.h>      // this is needed even tho we aren't using it
#include <ILI9341_t3.h>
#include <XPT2046_Touchscreen.h>
//#include <Adafruit_STMPE610.h>

// Rotations 1 or 3 = Landscape mode only ~ 1->TFT conn. pins on right side  : 3->TFT conn. pins on left side
const int rotation = 3; //(1 or 3 only)
const int TouchRotation = 1; //(1 or 3 only)

// This is calibration data for the raw touch data to the screen coordinates
int TS_MINX = 367;
int TS_MINY = 226;
int TS_MAXX = 3920;
int TS_MAXY = 3809;

// https://www.pjrc.com/store/display_ili9341_touch.html
// Connections For optimized ILI9341_t3 library + XPT2046 Touch library
// ------------------------------------------------------------------------------------------
// ILI9341 Pin | - Teensy 3.x - | - Notes -
// VCC         |           VIN  | Power: 3.6 to 5.5 volts
// GND         |           GND  |
// CS          |            20  | Alternate Pins: 9, 10, 15, 20, 21
// RESET       |         +3.3V  | Optional; #define TFT_RST 255, = unused, connect to 3.3V
// D/C         |            15  | Alternate Pins: 9, 10, 15, 20, 21
// SDI   (MOSI)|(DOUT~MOSI) 11  | Alternate Pin:  7 [SPI.setMOSI(7); - Use befor tft.begin()]
// SCK   (SCK0)|     (SCK0) 13  | Alternate Pin: 14 [SPI.setSCK(14); - Use befor tft.begin()]
// LED         |           VIN  | Use 100 ohm resistor, TFT dependent I'm not using any.
// SDO   (MISO)| (DIN~MISO) 12  | Alternate Pin:  8 [SPI.setMISO(8); - Use befor tft.begin()]
// T_CLK (SCK0)|     (SCK0) 13  | Alternate Pin: 14 [SPI.setSCK(14); - Use befor tft.begin()]
// T_CS        |            16  | Alternate: can use any digital pin  e.g. 6
// T_DIN (MOSI)|(DOUT~MOSI) 11  | Alternate Pin:  7 [SPI.setMOSI(7); - Use befor tft.begin()]
// T_DO  (MISO)| (DIN~MISO) 12  | Alternate Pin:  8 [SPI.setMISO(8); - Use befor tft.begin()]
// T_IRQ       |    NOT IN USE  | Optional: can use any digital pin
// ------------------------------------------------------------------------------------------

#define TOUCH_CS  16 // 8
//Adafruit_STMPE610 ts = Adafruit_STMPE610(TOUCH_CS);
XPT2046_Touchscreen ts(TOUCH_CS);

// For optimized ILI9341_t3 library
#define TFT_DC      15
#define TFT_CS      20
#define TFT_RST    255  // 255 = unused, connect to 3.3V
#define TFT_MOSI    11
#define TFT_SCLK    13
#define TFT_MISO    12
ILI9341_t3 tft = ILI9341_t3(TFT_CS, TFT_DC, TFT_RST, TFT_MOSI, TFT_SCLK, TFT_MISO);

#include "font_Arial.h"

int t_x; // Retrieve point x
int t_y; // Retrieve point y
int Tx = 0;
int Ty = 0;
byte touch_event_detected = 0;
#define MINPRESSURE 5   // 10
#define MAXPRESSURE 3000  // this was 1000

// Slider value editor
uint32_t xFreq = 1; // Hz, Maps the values
uint32_t xAnt = 50; // ns
float xDuty = 50.0000; // %
float xR = 29; // Slider

// The elapsedMillis feature is built into Teensyduino.
// For non-Teensy boards, it is available as a library.
elapsedMillis BLINK;
uint8_t Toggle = 1; // Toggle
uint8_t Select = 22; // 22 ant ,39 freq, 55 duty

// ***********************************************************************************************************
// *
// *                                Setup()
// *
// ***********************************************************************************************************
void setup(void) {
  tft.begin();
  tft.setRotation(rotation); // TFT Rotation 0~3

  tft.fillScreen(ILI9341_BLACK);
  tft.setTextColor(ILI9341_WHITE);
  tft.setFont(Arial_16);
  byte i = 0;
  while (!Serial && millis() < 5000) { // wait for Arduino Serial Monitor
    if (i >= 240) {
      i = 255;
    }
    tft.fillRect(250, 5, 42, 18, ILI9341_BLACK);
    tft.setCursor(250, 5);
    tft.print((5000.0 - (float)millis()) / 1000.0, 1);
    tft.print(" sec");

    delay(100);
    // BackLight
    if (i <= 254) {
      i += 10;
    }
  }

  if (!ts.begin()) {
    Serial.println("Couldn't start touchscreen controller");
    while (1);
  }
  Serial.println("U-Blox UBX-CFG-TP5 (0x06 0x31), TFT + Touch interface");
  Serial.println("Touchscreen started");

#ifdef TFTCalibration
  //int Tx = 0;
  //int Ty = 0;
  bool EXIT = true;
  unsigned long y = 10000;
  tft.fillScreen(ILI9341_BLACK);
  tft.setTextColor(ILI9341_WHITE);
  tft.setFont(Arial_9);
  tft.drawRoundRect(250, 140, 70, 40, 3, ILI9341_ORANGE);
  tft.setCursor(273, 155);
  tft.print("EXIT");

  tft.drawRoundRect(250, 200, 70, 40, 3, ILI9341_ORANGE);
  tft.setCursor(273, 208);
  tft.print("RUN");
  tft.setCursor(255, 222);
  tft.print("Calibration");

  tft.setTextColor(ILI9341_WHITE);
  tft.setCursor(2, 2);
  tft.print("Click on screen to draw Pixel");
  tft.setFont(Arial_16);
  while (millis() < y) { // wait for
    tft.fillRect(250, 5, 42, 18, ILI9341_BLACK);
    tft.setCursor(250, 5);
    tft.print((y - (float)millis()) / 1000.0, 1);
    tft.print(" sec");
    delay(10);

    TS_Point p = ts.getPoint();
    if (p.z > MINPRESSURE && p.z < MAXPRESSURE) {
      // Retrieve a point
      TS_Point p = ts.getPoint();
      Tx = p.x;
      Ty = p.y;
      /*
        if (rotation == 3) { // 3
        t_y = map(Ty, TS_MINY, TS_MAXY, 0, tft.height());
        t_x = map(Tx, TS_MINX, TS_MAXX, 0, tft.width());
        } else { // 1
        t_y = map(Ty, TS_MINY, TS_MAXY, tft.height(), 0);
        t_x = map(Tx, TS_MAXX, TS_MINX, 0, tft.width());
        } */
      Touchrot();

      tft.drawPixel(t_x, t_y, ILI9341_BLUE);
      // EXIT
      if (t_x > 250 && t_x < 320 && t_y > 140 && t_y < 180) {
        tft.fillScreen(ILI9341_BLACK);
        y = 0;
        EXIT = true;
        delay(300);
      }
      if (t_x > 250 && t_x < 320 && t_y > 200 && t_y < 240) {
        tft.fillScreen(ILI9341_BLACK);
        y = 0;
        EXIT = false;
        delay(300);
      }
    }
  }
  if (EXIT == false) {
    TS_MINX = 450;
    TS_MINY = 450;
    TS_MAXX = 3700;
    TS_MAXY = 3700;
    TFTCali(); // Run TFT Touch Calibration
  }
#endif

  tft.fillScreen(ILI9341_BLACK);
  ResetScreen();
  // ***********************************************************************************************************
  // *                            UBLOX GPS setup
  // ***********************************************************************************************************
  // serial to display data
  Serial.begin(9600); // Teensy Serial object always communicates at 12 Mbit/sec USB speed.

  /*
    // -- AutoBauding test -- experimental baud rate 1500000
    // Try communication with the GPS receiver at 9600 baud, default settings
    // then set GPS UART Baud to 1500000
    gps.begin(BaudDefault);                   // Enable Teensy serial communication @ 9600 baud, default settings.
    gps.SetGPSbaud(1500000, false);           // Set GPS Port Baud, Possible Baud Rate Configurations 4800~9600~19200~38400~57600~115200~230400~460800-921600
    gps.end();                                // Disables Teensy serial communication, to re-enable serial communication, call gps.begin(Baud, bool);.
    gps.begin(19200);
    gps.SetGPSbaud(1500000, false);
    gps.end();
    gps.begin(38400);
    gps.SetGPSbaud(1500000, false);
    gps.end();
    gps.begin(57600);
    gps.SetGPSbaud(1500000, false);
    gps.end();
    gps.begin(115200);
    gps.SetGPSbaud(1500000, false);
    gps.end();
    gps.begin(230400);
    gps.SetGPSbaud(1500000, false);
    gps.end();
    gps.begin(460800);
    gps.SetGPSbaud(1500000, false);
    gps.end();
    gps.begin(921600);
    gps.SetGPSbaud(1500000, true);
    gps.end();
    // now start communication with the GPS
    // receiver at 1500000 baud,
    gps.begin(1500000);                       // Enable Teensy serial communication @ given baud rate
  */

  // -- AutoBauding test -- baud rate 921600
  // Try communication with the GPS receiver at 9600 baud, default settings
  // then set GPS UART Baud to 921600
  gps.begin(BaudDefault);
  gps.SetGPSbaud(921600, false);
  gps.end();
  gps.begin(19200);
  gps.SetGPSbaud(921600, false);
  gps.end();
  gps.begin(38400);
  gps.SetGPSbaud(921600, false);
  gps.end();
  gps.begin(57600);
  gps.SetGPSbaud(921600, false);
  gps.end();
  gps.begin(115200);
  gps.SetGPSbaud(921600, false);
  gps.end();
  gps.begin(230400);
  gps.SetGPSbaud(921600, false);
  gps.end();
  gps.begin(460800);
  gps.SetGPSbaud(921600, false);
  gps.end();
  gps.begin(921600);
  gps.SetGPSbaud(921600, false);
  gps.end();
  gps.begin(1500000);
  gps.SetGPSbaud(921600, true);
  gps.end();
  // now start communication with the GPS
  // receiver at 921600 baud,
  gps.begin(921600);                        // Enable Teensy serial communication @ given baud rate
  if (gps.read(&uBloxData) ) {}             // reading data clears the hw serial port.

  gps.SetRATE(1000, false);                 // Navigation/Measurement Rate Settings, e.g. 100ms => 10Hz, 200 => 5.00Hz, 1000ms => 1Hz, 10000ms => 0.1Hz
  // Possible Configurations:
  // 60=>16.67Hz, 64=>15.63Hz, 72=>13.89Hz, 80=>12.50Hz, 100=>10.00Hz, 125=>8.00Hz, 200=>5.00Hz, 250=>4.00Hz, 500=>2.00Hz
  // 800=>1.25Hz, 1000=>1.00Hz, 2000=>0.50Hz, 4000=>0.25Hz, 10000=>0.10Hz, 20000=>0.05Hz, 50000=>0.02Hz

  // NOTE: Dis_all_NMEA -strongly suggest changing RX buffer to 255 or more,*otherwise you will miss ACKs*on serial monitor
  gps.Dis_all_NMEA_Child_MSGs(false);       // Disable All NMEA Child Messages Command

  gps.SetNAV5(3, false);                    // Set Dynamic platform model Navigation Engine Settings (0:portable, 2: stationary, 3:pedestrian, Etc)
  // Possible Configurations
  // 0: portable, 2: stationary, 3: pedestrian, 4: automotive, 5: sea, 6: airborne with <1g, 7: airborne with <2g
  // 8: airborne with <4g, 9: wrist worn watch (not supported in protocol v.less than 18)

  // ### Periodic auto update ON,OFF Command ###
  gps.Ena_NAV_PVT(false);                    // Enable periodic auto update NAV_PVT
  //gps.Dis_NAV_PVT(false);                  // Disable periodic auto update NAV_PVT

  //gps.Ena_NAV_ATT(true);                   // Enable periodic auto update NAV_ATT ~ U-blox M8 from protocol version 19
  //gps.Dis_NAV_ATT(false);                  // Disable periodic auto update NAV_ATT ~ ---^

  //gps.Ena_NAV_POSLLH(true);                // Enable periodic auto update NAV_POSLLH
  //gps.Dis_NAV_POSLLH(false);               // Disable periodic auto update NAV_POSLLH

  gps.Ena_Dis_MON_IO(true, false);           // Ena/Dis periodic auto update I/O Subsystem Status, bytes(received, sent), parity errors, framing errors, overrun errors)

  gps.Poll_MON_IO(false);                   // Polls UBX-MON-IO (0x0A 0x02) I/O Subsystem Status
  gps.Poll_MON_VER(false);                  // Polls UBX-MON-VER (0x0A 0x04) Receiver/Software Version

  // A UBlox GPS Module Primer for beginners https://forum.pjrc.com/threads/46058-A-UBlox-GPS-Module-Primer-for-beginners
  gps.SetCFG_TP5(1, 50.0000, 50, true);    // UBX-CFG-TP5 (0x06 0x31) - Set Time Pulse 0 Parameters.
  //          (1Hz,50%,ant50ns,print usb)
  // Possible Configurations:
  // SetCFG_TP5(FreqLocked- 1Hz ~ 24000000Hz, DutyLocked- 0.000000% ~ 100.000000%, antCableDelay- 0~32767ns, print usb ACK- true or false);

  gps.Poll_CFG_TP5(false);                 // Polls CFG-TP5        (0x06 0x31) Poll Time Pulse 0 Parameters
}

// ***********************************************************************************************************
// *
// *                                Loop()
// *
// ***********************************************************************************************************
void loop()
{
  if (BLINK > 500) {
    BLINK = 0; // reset since
    Toggle = ! Toggle;
    if (Toggle == 0) {
      tft.setFont(Arial_12);
      tft.setTextColor(ILI9341_YELLOW);
      tft.setCursor(10, Select); //
      tft.print(">");

      tft.setFont(Arial_11); // Arial, Arial
      if (Select == 22) {
        tft.setCursor(85, 100);  // 22
        tft.print("Ant");
      } else if (Select == 39) {
        tft.setCursor(85, 115);  // 22
        tft.print("Freq");
      } else if (Select == 55) {
        tft.setCursor(85, 130);  // 22
        tft.print("Duty");
      }
    } else {
      tft.setFont(Arial_12);
      tft.setTextColor(ILI9341_BLACK);
      tft.setCursor(10, Select); //
      tft.print(">");

      tft.setFont(Arial_11);
      tft.setCursor(85, 100);
      tft.print("Ant");
      tft.setCursor(85, 115);
      tft.print("Freq");
      tft.setCursor(85, 130);
      tft.print("Duty");
    }
  }
  // ***********************************************************************************************************
  // *                            UBLOX GPS read
  // ***********************************************************************************************************
  if (gps.read(&uBloxData) ) {

    //numSV
    tft.setFont(Arial_9);
    tft.setTextColor(ILI9341_CYAN);
    tft.setCursor(265, 6);
    tft.fillRect(297 , 6 , 18, 10, ILI9341_BLACK);
    tft.print("#SV: ");
    tft.print(uBloxData.numSV);

    tft.setCursor(263, 20);
    tft.print("Fix Type:");
    tft.setCursor(263, 35);
    tft.fillRect(263 , 35 , 55, 10, ILI9341_BLACK);
    //fixType;///< [ND], GNSSfix Type: 0: no fix, 1: dead reckoning only, 2: 2D-fix, 3: 3D-fix, 4: GNSS + dead reckoning combined, 5: time only fix
    switch (uBloxData.fixType) { // fixType
      case 0:    // 0: no-fix
        tft.setTextColor(ILI9341_RED);
        tft.print(" NO-fix");
        break;
      case 1:    // 1: dead reckoning only
        tft.print("dead rec");
        break;
      case 2:    // 2: 2D-fix
        tft.setTextColor(ILI9341_BLUE);
        tft.print(" 2D-fix");
        break;
      case 3:    // 3: 3D-fix
        tft.setTextColor(ILI9341_GREEN);
        tft.print(" 3D-fix");
        break;
      case 4:    //  4: GNSS + dead reckoning combined
        tft.print("GNSS+d");
        break;
      case 5:    //  5: time only fix
        tft.print("Time only");
        break;
      default:
        // Not Supported
        tft.print("Not Sup:"), tft.print(uBloxData.fixType);
        break;
    }

    // UBX-CFG-TP5 (0x06 0x31) - Set Time Pulse 0 Parameters.
    //tft.setTextSize(2);
    tft.setFont(Arial_11);
    tft.setTextColor(ILI9341_GREEN);
    tft.fillRect(185 , 23 , 60, 11,  ILI9341_BLACK);
    tft.setCursor(25, 23);
    tft.print("Ant Cable Delay");
    tft.setTextColor(ILI9341_YELLOW);
    tft.setCursor(163, 23);
    tft.print(" ns: ");
    tft.print(uBloxData.antCableDelay);  // antCableDelay

    tft.setTextColor(ILI9341_GREEN);
    tft.fillRect(185 , 40 , 75, 11, ILI9341_BLACK);
    tft.setCursor(25, 40);
    tft.print("Freq Locked");
    tft.setTextColor(ILI9341_YELLOW);
    tft.setCursor(161, 40);
    tft.print(" Hz: ");
    tft.println(uBloxData.freqPeriodL);  // freqPeriodL

    tft.setTextColor(ILI9341_GREEN);
    // CurrentfreqPeriodL = uBloxData.freqPeriodL; //TODO REMOVE?
    tft.fillRect(181 , 58 , 68, 11, ILI9341_BLACK);
    tft.setCursor(25, 58);
    tft.print("Duty Cycle Locked");
    tft.setTextColor(ILI9341_YELLOW);
    tft.setCursor(165, 58);
    tft.print(" %: ");
    tft.print(uBloxData.dutycycleL, 4);  // duty cycle%

    //tft.setTextSize(0);
    tft.setFont(Arial_8);
    tft.setTextColor(ILI9341_CYAN);
    tft.setCursor(0, 200);
    tft.print("I/O Subsystem Status");
    tft.setTextColor(ILI9341_WHITE);
    tft.setCursor(0, 210);
    tft.fillRect(47 , 210 , 70, 8, ILI9341_BLACK);
    tft.print("RX Bytes: "), tft.print(uBloxData.rxBytes); ///< [B], Number of bytes ever received
    tft.setCursor(0, 220);
    tft.fillRect(45 , 220 , 70, 8, ILI9341_BLACK);
    tft.print("TX Bytes: "), tft.print(uBloxData.txBytes); ///< [B], Number of bytes ever sent
    tft.setCursor(0, 230);
    tft.fillRect(66 , 230 , 70, 8, ILI9341_BLACK);
    tft.print("Overrun Errs: "), tft.print(uBloxData.overrunErrs); ///< [ms], Number of 100ms timeslots with overrun errors

    tft.setTextColor(ILI9341_CYAN);
    tft.setCursor(90, 158);
    tft.fillRect(180 , 158 , 30, 8, 0x31C7);
    tft.print("UBlox SW Version: "), tft.print(uBloxData.swVersion); ///< Software Version
    tft.setCursor(140, 168);
    tft.fillRect(165 , 168 , 50, 8, 0x31C7);
    tft.print("Rev# "), tft.print(uBloxData.revVersion); ///< Rev#
    tft.setCursor(121, 178);
    tft.fillRect(180 , 178 , 16, 8, 0x31C7);
    tft.print("HW Version: "), tft.print(uBloxData.hwVersion); ///< Hardware Version, 7 = u-blox 7
    tft.setCursor(121, 188);
    tft.fillRect(164 , 188 , 32, 8, 0x31C7);
    tft.print("Protocol: "), tft.print(uBloxData.extension1); ///< Protocol version, e.g. 14.00

    tft.drawRoundRect(180, 200, 120, 40, 6, ILI9341_CYAN); // SEND BTN
    tft.setFont(Arial_20);
    tft.setTextColor(ILI9341_GREEN);
    tft.setCursor(208, 210);
    tft.print("SEND");

    ScreenUpdate ();
  }
  // ***********************************************************************************************************
  // *                            TFT
  // ***********************************************************************************************************
  // See if there's any touch data for us
  TouchData();
  if (touch_event_detected == 1) {
    // SEND BUTTON
    if (t_x > 180 && t_x < 300 && t_y > 200 && t_y < 240) {
      tft.drawRoundRect(180, 200, 120, 40, 6, ILI9341_BLUE);
      tft.setFont(Arial_20);
      tft.setTextColor(ILI9341_RED);
      tft.setCursor(208, 210);
      tft.print("SEND");
      gps.SetCFG_TP5(xFreq, xDuty, xAnt, true);  // UBX-CFG-TP5   (0x06 0x31) - Set Time Pulse 0 Parameters.
      gps.Poll_CFG_TP5(true);                  // Polls CFG-TP5 (0x06 0x31) - Poll Time Pulse 0 Parameters
      gps.Poll_MON_VER(false);                 // Polls UBX-MON-VER (0x0A 0x04) Receiver/Software Version
    }
    // Select cur. ant, freq, duty
    byte temp = Select; // clear
    if (t_x > 0 && t_x < 320 && t_y > 20 && t_y < 34) {
      Select = 22; // y = 22
      tft.drawRoundRect(20, 21, 140, 17, 3, ILI9341_ORANGE);

      tft.drawRoundRect(20, 38, 140, 17, 3, ILI9341_BLACK);
      tft.drawRoundRect(20, 56, 140, 17, 3, ILI9341_BLACK);
    }
    if (t_x > 0 && t_x < 320 && t_y > 40 && t_y < 50) {
      Select = 39;
      tft.drawRoundRect(20, 38, 140, 17, 3, ILI9341_ORANGE);

      tft.drawRoundRect(20, 21, 140, 17, 3, ILI9341_BLACK);
      tft.drawRoundRect(20, 56, 140, 17, 3, ILI9341_BLACK);
    }
    if (t_x > 0 && t_x < 320 && t_y > 60 && t_y < 70) {
      Select = 55;
      tft.drawRoundRect(20, 56, 140, 17, 3, ILI9341_ORANGE);

      tft.drawRoundRect(20, 21, 140, 17, 3, ILI9341_BLACK);
      tft.drawRoundRect(20, 38, 140, 17, 3, ILI9341_BLACK);
    }
    tft.setFont(Arial_12);
    tft.setTextColor(ILI9341_BLACK); // clear old
    tft.setCursor(10, temp);
    tft.print(">");
  }
}

void ScreenUpdate () {
  if (Select == 22) { // Ant
    xR = modifiedMap(xAnt, 0, 32767, 29, 285); // 0~32767, default 50ns
    // Draws the positioners
    tft.fillRoundRect(29, 80, xR - 28 , 15, 1, ILI9341_BLUE);
    tft.fillRoundRect(xR + 2 , 80, 285 - xR , 15, 1, ILI9341_BLACK);
    tft.fillRoundRect(xR - 1, 80, 4, 15, 3, ILI9341_RED);
    // Draws the positioner outside box
    tft.drawRoundRect(28, 79, 285 - 25, 17, 1, ILI9341_GREEN);
    tft.drawRoundRect(27, 78, 285 - 25, 19, 3, ILI9341_CYAN);
  } // Ant
  tft.setCursor(125, 100);
  if (xAnt == uBloxData.antCableDelay) {
    tft.setTextColor(ILI9341_YELLOW);
  }  else {
    tft.setTextColor(ILI9341_RED);
  }
  // print the new value in the slider bar
  tft.setFont(Arial_12);
  tft.fillRect(125, 100, 100, 12, ILI9341_BLACK); // Clear
  tft.print(xAnt);

  if (Select == 39) { // Freq
    xR = modifiedMap(xFreq, 1, 24000000, 29, 285); // 1Hz ~ 24000000Hz
    // Draws the positioners
    tft.fillRoundRect(29, 80, xR - 28 , 15, 1, ILI9341_BLUE);
    tft.fillRoundRect(xR + 2 , 80, 285 - xR , 15, 1, ILI9341_BLACK);
    tft.fillRoundRect(xR - 1, 80, 4, 15, 3, ILI9341_RED);
    // Draws the positioner outside box
    tft.drawRoundRect(28, 79, 285 - 25, 17, 1, ILI9341_GREEN);
    tft.drawRoundRect(27, 78, 285 - 25, 19, 3, ILI9341_CYAN);
  } // Freq
  tft.setCursor(125, 115);
  if (xFreq == uBloxData.freqPeriodL) {
    tft.setTextColor(ILI9341_YELLOW);
  }  else {
    tft.setTextColor(ILI9341_RED);
  }
  // print the new value in the slider bar
  tft.setFont(Arial_12);
  tft.fillRect(125, 115, 100, 12, ILI9341_BLACK); // Clear
  tft.print(xFreq);

  if (Select == 55) { // Duty
    xR = map(xDuty, 0 , 100, 29, 285);
    // Draws the positioners
    tft.fillRoundRect(29, 80, xR - 28 , 15, 1, ILI9341_BLUE);
    tft.fillRoundRect(xR + 2 , 80, 285 - xR , 15, 1, ILI9341_BLACK);
    tft.fillRoundRect(xR - 1, 80, 4, 15, 3, ILI9341_RED);
    // Draws the positioner outside box
    tft.drawRoundRect(28, 79, 285 - 25, 17, 1, ILI9341_GREEN);
    tft.drawRoundRect(27, 78, 285 - 25, 19, 3, ILI9341_CYAN);
  } // Duty

  tft.setCursor(125, 130);
  if (xDuty == uBloxData.dutycycleL) {
    tft.setTextColor(ILI9341_YELLOW);
  }  else {
    tft.setTextColor(ILI9341_RED);
  }
  // print the new value in the slider bar
  tft.setFont(Arial_12);
  tft.fillRect(125, 130, 100, 12, ILI9341_BLACK); // Clear
  tft.print(xDuty, 4);
}

void ResetScreen () {
  tft.fillScreen(ILI9341_BLACK);
  tft.fillRoundRect(5, 1, 256, 73, 3, 0x1000); // 0x52AA

  tft.setCursor(6, 6);
  tft.setTextColor(ILI9341_BLUE);
  tft.setFont(Arial_8);
  tft.print("UBX-CFG-TP5 Current Time Pulse Configuration");

  // Select = 22; // y = 22
  tft.drawRoundRect(20, 21, 140, 17, 3, ILI9341_ORANGE);

  tft.drawRoundRect(20, 38, 140, 17, 3, ILI9341_BLACK);
  tft.drawRoundRect(20, 56, 140, 17, 3, ILI9341_BLACK);

  //http://www.barth-dev.de/online/rgb565-color-picker/
  //COLOR GRAY 0x52AA
  //DK GRY 0x31C7
  //DK BLUE 0x006F
  tft.fillRoundRect(0, 75, 320, 123, 5, 0x31C7); // frame around slider and black rear axle msg. box
  tft.drawRoundRect(0, 75, 320, 124, 5, ILI9341_GREEN); //
  tft.fillRoundRect(20, 76, 274, 52, 5, ILI9341_BLACK); // frame around slider and - + bottons
  tft.fillRoundRect(20, 125, 64, 72, 5, ILI9341_BLACK); // blue side
  tft.fillRoundRect(230, 125, 64, 72, 5, ILI9341_BLACK); // red side
  tft.fillRoundRect(81, 98, 152, 60, 5, ILI9341_GREEN); // red side
  tft.fillRoundRect(82, 99, 150, 58, 5, ILI9341_BLACK); // red side
  tft.fillRoundRect(83, 100, 35, 56, 5, 0x31C7); // red side

  tft.drawRoundRect(0, 0, 320, 75, 5, ILI9341_YELLOW); //

  tft.drawRoundRect(28, 97, 51, 29, 5, ILI9341_BLUE); // - botton
  tft.setCursor( 50, 105);
  tft.setTextColor(ILI9341_BLUE);
  tft.setFont(Arial_16);
  tft.print("-");
  tft.drawRoundRect(284 - 48, 97, 53, 29, 5, ILI9341_RED); // + botton
  tft.setCursor(284 - 28, 105);
  tft.setTextColor(ILI9341_RED);
  tft.setFont(Arial_16);
  tft.print("+");

  tft.drawRoundRect(28, 130, 51, 29, 5, ILI9341_BLUE); // - botton
  tft.setCursor( 30, 137);
  tft.setTextColor(ILI9341_BLUE);
  tft.setFont(Arial_16);
  tft.print("-500");
  tft.drawRoundRect(284 - 48, 130, 53, 29, 5, ILI9341_RED); // + botton
  tft.setCursor(284 - 48, 137);
  tft.setTextColor(ILI9341_RED);
  tft.setFont(Arial_16);
  tft.print("+500");

  tft.drawRoundRect(28, 165, 51, 29, 5, ILI9341_BLUE); // - botton
  tft.setCursor( 30, 173);
  tft.setTextColor(ILI9341_BLUE);
  tft.setFont(Arial_13);
  tft.print("-5000");
  tft.drawRoundRect(284 - 48, 165, 53, 29, 5, ILI9341_RED); // + botton
  tft.setCursor(284 - 48, 173);
  tft.setTextColor(ILI9341_RED);
  tft.setFont(Arial_13);
  tft.print("+5000");

  Draw_Slider(); // Draw Slider
}

void TouchData()
{
  touch_event_detected = 0; // reset flag

  // See if there's any touch data for us
  if (ts.touched())
  {

    // Retrieve a point
    TS_Point p = ts.getPoint();

    // we have some minimum pressure we consider 'valid'
    // pressure of 0 means no pressing!
    if (p.z > MINPRESSURE && p.z < MAXPRESSURE) {
      // Wait for end of the touch event before continuing
      while (ts.touched()) { //
        Touchrot();

        // drawPixel
        //  if ((t_x) && ((t_y) < tft.height())) {
        //    tft.drawPixel(t_x, t_y, currentcolor);
        //  }

        if (gps.read(&uBloxData)) {
        }

        // Area of the slider
        if ( (t_y >= 80) && (t_y <= 95)) {
          xR = t_x; // Stores the X value where the screen has been pressed in to variable xR
          if (xR <= 29) { // Confines the area of the slider to be above 38 pixels
            xR = 29;
          }
          if (xR >= 285) { /// Confines the area of the slider to be under 310 pixels
            xR = 285;
          }

          if (Select == 22) { // Ant
            xAnt = modifiedMap(xR, 29, 285, 0, 32767); // 0~32767
            // Draws the positioners
            tft.fillRoundRect(29, 80, xR - 28 , 15, 1, ILI9341_BLUE);
            tft.fillRoundRect(xR + 2 , 80, 285 - xR , 15, 1, ILI9341_BLACK);
            tft.fillRoundRect(xR - 1, 80, 4, 15, 3, ILI9341_RED);
            // Draws the positioner outside box
            tft.drawRoundRect(28, 79, 285 - 25, 17, 1, ILI9341_GREEN);
            tft.drawRoundRect(27, 78, 285 - 25, 19, 3, ILI9341_CYAN);

            tft.setCursor(125, 100);
            if (xAnt == uBloxData.antCableDelay) {
              tft.setTextColor(ILI9341_YELLOW);
            }  else {
              tft.setTextColor(ILI9341_RED);
            }
            // print the new value in the slider bar
            tft.setFont(Arial_12);
            tft.fillRect(125, 100, 100, 12, ILI9341_BLACK); // Clear
            tft.print(xAnt);
          } // Ant

          if (Select == 39) { // Freq
            xFreq = modifiedMap(xR, 29, 285, 1, 24000000);
            // Draws the positioners
            tft.fillRoundRect(29, 80, xR - 28 , 15, 1, ILI9341_BLUE);
            tft.fillRoundRect(xR + 2 , 80, 285 - xR , 15, 1, ILI9341_BLACK);
            tft.fillRoundRect(xR - 1, 80, 4, 15, 3, ILI9341_RED);
            // Draws the positioner outside box
            tft.drawRoundRect(28, 79, 285 - 25, 17, 1, ILI9341_GREEN);
            tft.drawRoundRect(27, 78, 285 - 25, 19, 3, ILI9341_CYAN);

            tft.setCursor(125, 115);
            if (xFreq == uBloxData.freqPeriodL) {
              tft.setTextColor(ILI9341_YELLOW);
            }  else {
              tft.setTextColor(ILI9341_RED);
            }
            // print the new value in the slider bar
            tft.setFont(Arial_12);
            tft.fillRect(125, 115, 100, 12, ILI9341_BLACK); // Clear
            tft.print(xFreq);
          } // Freq

          if (Select == 55) { // Duty
            //xDuty = modifiedMap(xR, 29, 285, (0 - 0.125), (100 - 0.125)); // 100% 4294967295
            xDuty = map(xR, 29, 285, 0 , 100); // 100% 4294967295
            // Draws the positioners
            tft.fillRoundRect(29, 80, xR - 28 , 15, 1, ILI9341_BLUE);
            tft.fillRoundRect(xR + 2 , 80, 285 - xR , 15, 1, ILI9341_BLACK);
            tft.fillRoundRect(xR - 1, 80, 4, 15, 3, ILI9341_RED);
            // Draws the positioner outside box
            tft.drawRoundRect(28, 79, 285 - 25, 17, 1, ILI9341_GREEN);
            tft.drawRoundRect(27, 78, 285 - 25, 19, 3, ILI9341_CYAN);

            tft.setCursor(125, 130);
            if (xDuty == uBloxData.dutycycleL) {
              tft.setTextColor(ILI9341_YELLOW);
            }  else {
              tft.setTextColor(ILI9341_RED);
            }
            // print the new value in the slider bar
            tft.setFont(Arial_12);
            tft.fillRect(125, 130, 100, 12, ILI9341_BLACK); // Clear
            tft.print(xDuty, 4);
          }
        }
      } // while
      touch_event_detected = 1; // reset flag
    }
    Draw_Slider(); // Draw Slider
    Touchrot();
    touch_event_detected = 1; // set flag
  }
}

void Draw_Slider() { // Slider
  if (Select == 22) { // antCableDelay, 0~32767, default 50ns
    // If we press the [-] Button
    if ((t_x >= 28) && (t_x <= 78) && (t_y >= 97) && (t_y <= 126)) {
      xAnt = xAnt - 1;
    }
    // If we press the [+] Button
    if ((t_x >= 284 - 48) && (t_x <= 286) && (t_y >= 97) && (t_y <= 126)) {
      xAnt = xAnt + 1;
    }

    // If we press the [-]500 Button
    if ((t_x >= 28) && (t_x <= 78) && (t_y >= 140) && (t_y <= 165)) {
      if (xAnt < 502) {
        xAnt = 1;
      } else {
        xAnt = xAnt - 500;
      }
    }
    // If we press the [+]500 Button
    if ((t_x >= 284 - 48) && (t_x <= 286) && (t_y >= 140) && (t_y <= 165)) {
      xAnt = xAnt + 500;
    }

    // If we press the [-]5000 Button
    if ((t_x >= 28) && (t_x <= 78) && (t_y >= 170) && (t_y <= 190)) {
      if (xAnt < 5002) {
        xAnt = 1;
      } else {
        xAnt = xAnt - 5000;
      }
    }
    // If we press the [+]5000 Button
    if ((t_x >= 284 - 48) && (t_x <= 286) && (t_y >= 170) && (t_y <= 190)) {
      xAnt = xAnt + 5000;
    }
    if (xAnt == 0) {
      xAnt = 0;
      xR = modifiedMap(xAnt, 0, 32767, 29, 285); // Confines for the draw slider
    }  else if (xAnt >= 32767) {
      xAnt = 32767;
      xR = modifiedMap(xAnt, 0, 32767, 29, 285); // Confines for the draw slider
    }
    // curr Ant
    tft.setCursor(125, 100);
    if (xAnt == uBloxData.antCableDelay) {
      tft.setTextColor(ILI9341_YELLOW);
    }  else {
      tft.setTextColor(ILI9341_RED);
    }
    // print the new value in the slider bar
    tft.setFont(Arial_12);
    tft.fillRect(125, 100, 100, 12, ILI9341_BLACK); // Clear
    tft.print(xAnt);
    xR = modifiedMap(xAnt, 0, 32767, 29, 285);
  }

  if (Select == 39) { // freqPeriodLock, 24000000Hz ~ 1Hz
    // If we press the [-] Button
    if ((t_x >= 28) && (t_x <= 78) && (t_y >= 97) && (t_y <= 126)) {
      xFreq = xFreq - 1;
    }
    // If we press the [+] Button
    if ((t_x >= 284 - 48) && (t_x <= 286) && (t_y >= 97) && (t_y <= 126)) {
      xFreq = xFreq + 1;
    }

    // If we press the [-]500 Button
    if ((t_x >= 28) && (t_x <= 78) && (t_y >= 140) && (t_y <= 165)) {
      if (xFreq < 502) {
        xFreq = 1;
      } else {
        xFreq = xFreq - 500;
      }
    }
    // If we press the [+]500 Button
    if ((t_x >= 284 - 48) && (t_x <= 286) && (t_y >= 140) && (t_y <= 165)) {
      xFreq = xFreq + 500;
    }

    // If we press the [-]5000 Button
    if ((t_x >= 28) && (t_x <= 78) && (t_y >= 170) && (t_y <= 190)) {
      if (xFreq < 5002) {
        xFreq = 1;
      } else {
        xFreq = xFreq - 5000;
      }
    }
    // If we press the [+]5000 Button
    if ((t_x >= 284 - 48) && (t_x <= 286) && (t_y >= 170) && (t_y <= 190)) {
      xFreq = xFreq + 5000;
    }
    if (xFreq == 0) {
      xFreq = 1;
      xR = modifiedMap(xFreq, 1, 24000000, 29, 285); // Confines for the draw slider
    }  else if (xFreq >= 24000000) {
      xFreq = 24000000;
      xR = modifiedMap(xFreq, 1, 24000000, 29, 285); // Confines for the draw slider
    }
    // curr Freq
    tft.setCursor(125, 115);
    if (xFreq == uBloxData.freqPeriodL) {
      tft.setTextColor(ILI9341_YELLOW);
    }  else {
      tft.setTextColor(ILI9341_RED);
    }
    // print the new value in the slider bar
    tft.setFont(Arial_12);
    tft.fillRect(125, 115, 100, 12, ILI9341_BLACK); // Clear
    tft.print(xFreq);
    xR = modifiedMap(xFreq, 1, 24000000, 29, 285);
  }

  if (Select == 55) { // Duty, 100% 4294967295
    // If we press the [-] Button
    if ((t_x >= 28) && (t_x <= 78) && (t_y >= 97) && (t_y <= 126)) {
      if (xDuty < 0.0001) {
        xDuty = 0;
      } else {
        xDuty = xDuty - 0.0001;
      }
    }
    // If we press the [+] Button
    if ((t_x >= 284 - 48) && (t_x <= 286) && (t_y >= 97) && (t_y <= 126)) {
      xDuty = xDuty + 0.0001;
    }

    // If we press the [-]500 Button
    if ((t_x >= 28) && (t_x <= 78) && (t_y >= 140) && (t_y <= 165)) {
      if (xDuty < 0.5) {
        xDuty = 0;
      } else {
        xDuty = xDuty - 0.0500;
      }
    }
    // If we press the [+]500 Button
    if ((t_x >= 284 - 48) && (t_x <= 286) && (t_y >= 140) && (t_y <= 165)) {
      xDuty = xDuty + 0.0500;
    }

    // If we press the [-]5000 Button
    if ((t_x >= 28) && (t_x <= 78) && (t_y >= 170) && (t_y <= 190)) {
      if (xDuty < 0.5001) {
        xDuty = 0;
      } else {
        xDuty = xDuty - 0.5000;
      }
    }
    // If we press the [+]5000 Button
    if ((t_x >= 284 - 48) && (t_x <= 286) && (t_y >= 170) && (t_y <= 190)) {
      xDuty = xDuty + 0.5000;
    }

    if (xDuty <= 0) {
      xDuty = 0;
      xR = modifiedMap(xDuty, 0 , 100, 29, 285); // Confines for the draw slider //(xDuty, (0 - 0.125), (100 - 0.125), 29, 285);
    }  else if (xDuty >= 100) {
      xDuty = 100;
      xR = modifiedMap(xDuty, 0 , 100, 29, 285); // Confines for the draw slider
    }
    // curr Duty
    tft.setCursor(125, 130);
    if (xDuty == uBloxData.dutycycleL) {
      tft.setTextColor(ILI9341_YELLOW);
    }  else {
      tft.setTextColor(ILI9341_RED);
    }
    // print the new value in the slider bar
    tft.setFont(Arial_12);
    tft.fillRect(125, 130, 100, 12, ILI9341_BLACK); // Clear
    tft.print(xDuty, 4);
    xR = map(xDuty, 0 , 100, 29, 285);
  }
  // Draws the positioners
  tft.fillRoundRect(29, 80, xR - 28 , 15, 1, ILI9341_BLUE);
  tft.fillRoundRect(xR + 2 , 80, 285 - xR , 15, 1, ILI9341_BLACK);
  tft.fillRoundRect(xR - 1, 80, 4, 15, 3, ILI9341_RED);
  // Draws the positioner outside box
  tft.drawRoundRect(28, 79, 285 - 25, 17, 1, ILI9341_GREEN);
  tft.drawRoundRect(27, 78, 285 - 25, 19, 3, ILI9341_CYAN);
}

// ***********************************************************************************************************
// *
// *                            Modified Map
// * ARDUINO "map" function have problems with large numbers, rolling my own "Modified Map"
// ***********************************************************************************************************
double modifiedMap(double x, double in_min, double in_max, double out_min, double out_max)
{
  double temp = (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
  temp = (double) (4 * temp + .5);
  return (double) temp / 4;
}

// ***********************************************************************************************************
// *
// *                                TFT Touch Calibration ()
// * based on http://cyaninfinite.com/tutorials/2-8-tft-lcd-touchscreen-shield/
// ***********************************************************************************************************
#ifdef TFTCalibration
void TFTCali ()
{
  byte count = 0;
  bool tft_y = false;

  tft.fillScreen(ILI9341_BLACK);
  Serial.println("TFT Calibration");
  //Splash
  tft.setCursor(30, (tft.height() / 2) - 20);
  //tft.setTextSize(2);
  tft.setFont(Arial_18);
  tft.println("TFT Calibration v1.1");
  tft.setCursor(30, tft.height() / 2 + 10);
  tft.setFont(Arial_9);
  tft.setTextColor(ILI9341_WHITE);
  tft.print("Screen size:");
  tft.print(tft.width());
  tft.print("x");
  tft.println(tft.height());
  tft.setCursor(30, (tft.height() / 2) + 30);
  tft.println("Test wil begin in 2s...");
  delay(2000);
  tft.fillScreen(ILI9341_BLACK);
  //TFT Calibration
  tft.setCursor(30, (tft.height() / 2) - 20);
  tft.setFont(Arial_14);
  tft.println("TFT Calibration");
  tft.setCursor(30, (tft.height() / 2));
  tft.setFont(Arial_9);
  tft.setTextColor(ILI9341_WHITE);
  tft.print("Click on screen to begin...");
  tft_y = true;

  tft.setTextColor(ILI9341_WHITE);
  tft.setFont(Arial_9);

  while (count < 5) {
    // Retrieve a point
    TS_Point p = ts.getPoint();
    Tx = 0;
    Ty = 0;

    if (tft_y == true) {
      delay(200);
      if (p.z > MINPRESSURE && p.z < MAXPRESSURE) {
        TS_Point p = ts.getPoint();
        Tx = p.x;
        Ty = p.y;
        Touchrot();
        switch (count) {
          case 0:
            tft.fillRect(30, (tft.height() / 2), 180, (tft.height() / 2) + 10, ILI9341_BLACK);
            tft.setCursor(30, (tft.height() / 2));
            tft.print("Press the dots on the corners of the screen.");
            //drawCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color);
            tft.setCursor(tft.width() / 2, 10);
            tft.print(count);
            tft.fillCircle(0, 0, 16, ILI9341_YELLOW);
            getMinMax(Tx, Ty);
            count++;
            break;
          case 1:
            tft.fillCircle(tft.width(), 0, 16, ILI9341_YELLOW);
            tft.fillRect(tft.width() / 2, 10, 10, 10, ILI9341_BLACK);
            tft.setCursor(tft.width() / 2, 10);
            tft.print(count);
            getMinMax(Tx, Ty);
            count++;
            break;
          case 2:
            tft.fillCircle(tft.width(), tft.height(), 16, ILI9341_YELLOW);
            tft.fillRect(tft.width() / 2, 10, 10, 10, ILI9341_BLACK);
            tft.setCursor(tft.width() / 2, 10);
            tft.print(count);
            getMinMax(Tx, Ty);
            count++;
            break;
          case 3:
            tft.fillCircle(0, tft.height(), 16, ILI9341_YELLOW);
            tft.fillRect(tft.width() / 2, 10, 10, 10, ILI9341_BLACK);
            tft.setCursor(tft.width() / 2, 10);
            tft.print(count);
            getMinMax(Tx, Ty);
            count++;
            break;
          case 4:
            tft.fillRect(tft.width() / 2, 10, 10, 10, ILI9341_BLACK);
            tft.setCursor(tft.width() / 2, 10);
            tft.print(count);
            tft.fillRect(30, (tft.height() / 2), 300, (tft.height() / 2) + 10, ILI9341_BLACK);
            tft.setCursor(30, tft.height() / 2);
            tft.print("Calibration completed!");
            tft.setCursor(30, (tft.height() / 2) + 20);
            tft.print("TS_MINX:");
            tft.print(TS_MINX);
            tft.setCursor(130, (tft.height() / 2) + 20);
            tft.print("TS_MINY:");
            tft.print(TS_MINY);
            tft.setCursor(30, (tft.height() / 2) + 40);
            tft.print("TS_MAXX:");
            tft.print(TS_MAXX);
            tft.setCursor(130, (tft.height() / 2) + 40);
            tft.print("TS_MAXY:");
            tft.print(TS_MAXY);
            tft.setCursor(30, (tft.height() / 2) + 75);
            tft.setTextColor(ILI9341_OLIVE);
            tft.print("Press Try Again or Exit...");
            tft.setCursor(30, (tft.height() / 2) + 60);
            tft.print("Click on screen to draw Pixel");
            tft.setTextColor(ILI9341_WHITE);

            tft.drawRoundRect(270, 200, 50, 40, 3, ILI9341_ORANGE);
            tft.setCursor(285, 208);
            tft.print("Try");
            tft.setCursor(278, 222);
            tft.print("Again");

            tft.drawRoundRect(270, 140, 50, 40, 3, ILI9341_ORANGE);
            tft.setCursor(283, 155);
            tft.print("EXIT");
            tft_y = false;
            break;
        }
        delay(200);
      }
    } else {
      //tft.setRotation(0);

      if (p.z > MINPRESSURE && p.z < MAXPRESSURE) {
        TS_Point p = ts.getPoint();
        Tx = p.x;
        Ty = p.y;

        tft.fillRect(52, 50, 30, 10, ILI9341_BLACK);
        tft.setCursor(30, 50);
        tft.print("X = "); tft.print(Tx);
        tft.fillRect(52, 65, 30, 10, ILI9341_BLACK);
        tft.setCursor(30, 65);
        tft.print("Y = "); tft.print(Ty);
        tft.fillRect(97, 82, 30, 10, ILI9341_BLACK);
        tft.setCursor(30, 82);
        tft.print("Pressure = "); tft.println(p.z);

        Touchrot();

        tft.drawPixel(t_x, t_y, ILI9341_BLUE);

        tft.fillRect(132, 50, 25, 10, ILI9341_BLACK);
        tft.setCursor(100, 50);
        tft.print("t_x = "); tft.print(t_x);
        tft.fillRect(132, 65, 25, 10, ILI9341_BLACK);
        tft.setCursor(100, 65);
        tft.print("t_y = "); tft.print(t_y);

        tft.setCursor(30, tft.height() / 2);
        tft.print("Calibration completed!");
        tft.setCursor(30, (tft.height() / 2) + 20);
        tft.print("TS_MINX:");
        tft.print(TS_MINX);
        tft.setCursor(130, (tft.height() / 2) + 20);
        tft.print("TS_MINY:");
        tft.print(TS_MINY);
        tft.setCursor(30, (tft.height() / 2) + 40);
        tft.print("TS_MAXX:");
        tft.print(TS_MAXX);
        tft.setCursor(130, (tft.height() / 2) + 40);
        tft.print("TS_MAXY:");
        tft.print(TS_MAXY);


        // EXIT
        if (t_x > 270 && t_x < 320 && t_y > 140 && t_y < 180) {
          tft.fillScreen(ILI9341_BLACK);
          count = 5; // exit while()
          delay(300);
        }
        // Try Again
        if (t_x > 270 && t_x < 320 && t_y > 200 && t_y < 240) { // tft 320 x 240
          tft.fillScreen(ILI9341_BLACK);
          tft_y = true;
          count = 0; // reset
          tft.setCursor(30, (tft.height() / 2));
          //tft.setFont(Arial_9);
          tft.setTextColor(ILI9341_WHITE);
          tft.print("Click on screen to begin...");
          TS_MINX = 450;
          TS_MINY = 450;
          TS_MAXX = 3600;
          TS_MAXY = 3600;
          delay(300);
        }
      }
    }
  }
}
void getMinMax(int Tx, int Ty) {
  if (Tx < TS_MINX) {
    TS_MINX = Tx;
  }
  if (Ty < TS_MINY) {
    TS_MINY = Ty;
  }
  if (Tx > TS_MAXX) {
    TS_MAXX = Tx;
  }
  if (Ty > TS_MAXY) {
    TS_MAXY = Ty;
  }
}
#endif

void Touchrot() {
  TS_Point p = ts.getPoint();
  Tx = p.x;
  Ty = p.y;

  if (TouchRotation == 3) { // 3
    t_y = map(Ty, TS_MINY, TS_MAXY, 0, tft.height());
    t_x = map(Tx, TS_MINX, TS_MAXX, 0, tft.width());
  } else { // 1
    t_y = map(Ty, TS_MINY, TS_MAXY, tft.height(), 0);
    t_x = map(Tx, TS_MAXX, TS_MINX, 0, tft.width());
  }
  //Serial.print("X = "); Serial.print(Tx);
  //Serial.print("  Y = "); Serial.print(Ty);
  //Serial.print("  Pressure = "); Serial.println(p.z);
}
 
Thank Chris - kind of round robbing between this and the other project will give it a go as soon as I can

Mike
 
Hi Chris. Couldn't wait had to give this a try. Yes it worked for the touch (goes where its suppose to when I hit the screen) part and part of the draw part. See attached - its easier to see than describe:
2018-04-09 15.30.06.png
 
Hi Chris

Guess what - plugged it in this morning and reloaded sketch and all seems to working as advertised :) Yeah.
 
Hey Mike that's good news.;)
I'm assuming you running it with the new GPS that has the PPS pin broken out.
 
Yeah - but you don't use the pps pin that I can see :) Having a devil a time getting a good satellite lock - just loaded it up again and now its not displaying text - arrgh
 
Try uploading one more time or connecting disconnecting the USB cable?
You can only get PPS signal with satellite lock (fix type 3d), probably around 4 satellites.
One time I was waiting 10 minutes to get satellite lock.
 
Finally got a lock but nothing I plugged and replugged - got and then lost it when I unplugged to see if it would be consistent. Have to play around some more.

EDIT want to check my gps first - going to do this step by step now.
 
I also edit my serial3.c buffer size, maybe this is the start up issue?
Code:
////////////////////////////////////////////////////////////////
// Tunable parameters (relatively safe to edit these numbers)
////////////////////////////////////////////////////////////////

#ifndef SERIAL3_TX_BUFFER_SIZE
#define SERIAL3_TX_BUFFER_SIZE     255 // number of outgoing bytes to buffer
#endif
#ifndef SERIAL3_RX_BUFFER_SIZE
#define SERIAL3_RX_BUFFER_SIZE     255 // number of incoming bytes to buffer
#endif
#define RTS_HIGH_WATERMARK (SERIAL3_RX_BUFFER_SIZE-24) // RTS requests sender to pause
#define RTS_LOW_WATERMARK  (SERIAL3_RX_BUFFER_SIZE-38) // RTS allows sender to resume
#define IRQ_PRIORITY  64  // 0 = highest priority, 255 = lowest


////////////////////////////////////////////////////////////////
// changes not recommended below this point....
////////////////////////////////////////////////////////////////
 
Maybe - I forgot we changed the buffer size for the uNav program as well - have to start writing this stuff down so I remember

EDIT: Step by step I also mean double checking in ublox and then use you new library by itself and the start playing with the TP sketch :)
 
mjs513: Are you using this in conjunction with SPI_MSTransfer? Same SPI bus?

Connecting and specifying the T_IRQ pin and use the new tirqTouched(); function to test for touch to prevent lots of extra SPI hits for the Touch Test.

See :: XPT2046_Touchscreen/examples/TouchTestIRQ/TouchTestIRQ.ino

My Map function is so much cooler - and works on all 4 orientations.
 
I got to see if i can implement the T_IRQ pin that's good idea, reducing the SPI traffic.:D
Oh and the orientation for the touch might be a bit more tricky, some of this displays have the touch upside down so you almost need 8 orientations.
 
Yeah - that is a really cool feature { I'm partial to ... since I wrote it :) }

The recent update with tirqTouched(); makes it even better (for DMA case) as it used to immediately PING for data when called if touched - now it doesn't even do that if the IRQ hasn't fired indicating a touch. This was important if Display DMA was doing constant refresh. Knowing it was touched allows DMA stoppage only then and it doesn't interrupt the ongoing DMA. Without the auto refresh DMA that isn't that helpful as you then call for the actual touch values as in the noted example.
 
Tim:
Are you using this in conjunction with SPI_MSTransfer? Same SPI bus?
Nope - working on a separate T3.2. Want to experiment with Chris's new library. Edit - not 100% sure its working with the ublox 8030

See :: XPT2046_Touchscreen/examples/TouchTestIRQ/TouchTestIRQ.ino
I will have to check it out. Like Chris said that's a good idea.

My Map function is so much cooler - and works on all 4 orientations
Chris's solution worked so I didn't pursue it. But I see Chris already answered that one :) 8 orientations oh boy.
 
I got to see if i can implement the T_IRQ pin that's good idea, reducing the SPI traffic.:D
Oh and the orientation for the touch might be a bit more tricky, some of this displays have the touch upside down so you almost need 8 orientations.

Missed the note on 8 orientations - I have not seen that - in that case the MAP function I presented should be easy to have it apply the swap and the array lookup for map would still work with just an appropriate change to the rotation index.

Much more easily handles that way than a bunch of if'fy logic :)
 
Back
Top