PDQgraphicstest not working with 8 Pin screen

Touch, you say?

I might have made just a few modifications to this sketch. I believe I got the original out of the Kuman_TFTLCD library.

I know I had to do some wholesale changes in the XPT2046_Touchscreen library to get it work with a SPI connected ILI9488 on the R4, but I don't believe I made any changes to the TouchScreen library used here. I can't guarantee that I didn't; I'm rather shameless about altering libraries on the fly. :slight_smile: Anyhow, give this sketch a try and see how it does for you.

(Oh, and it should work with all rotations.)

///////////////
// Sketch: Calibrate - Calibrate TFT ILI9341 Touch
// Author: Joao Lopes F. - joaolopesf@gmail.com
//
// Versions:
//    - 0.9.0  First beta - July 2015
//    - 0.9.1  Rotation for Mega 
//    - ?.?.?  Mod'd to work on the R4
// Comments: 
//    Show the calibration parameters to put in your code
//    Please use a small like the eraser on a pencil for best results
//
//    Code for buttons, based on Adafruit arduin_o_phone example
///////////////

// library ILI9341

#include <Adafruit_GFX.h>    // Core graphics library
#include <MCUFRIEND_kbv.h>
#include <TouchScreen.h>     // Touch library

// Calibrates value
#define SENSIBILITY 300
#define MINPRESSURE 10
#define MAXPRESSURE 1000

//These are the pins for the shield!
#define YP A3  // must be an analog pin, use "An" notation!
#define XM A2  // must be an analog pin, use "An" notation!
#define YM 9   // can be a digital pin
#define XP 8   // can be a digital pin

const static short TS_MINX = 150;
const static short TS_MINY = 120;
const static short TS_MAXX = 920;
const static short TS_MAXY = 940;

const static short crosshairLng = 4;

bool portrait;

// Init TouchScreen:

TouchScreen ts = TouchScreen(XP, YP, XM, YM, SENSIBILITY);

// LCD Pin

#define LCD_CS A3
#define LCD_CD A2
#define LCD_WR A1
#define LCD_RD A0
#define LCD_RESET A4 // Optional : otherwise connect to Arduino's reset pin

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

// Init LCD

MCUFRIEND_kbv tft;

// Dimensions

uint16_t width = 0;
uint16_t height = 0;

// Buttons

#define BUTTONS 3
#define BUTTON_CLEAR 0
#define BUTTON_SHOW 1
#define BUTTON_RESET 2

Adafruit_GFX_Button buttons[BUTTONS];

uint16_t buttons_y = 0;

uint16_t tsLeft, tsRight, tsTop, tsBottom;
uint16_t pxLeft, pxRight, pxTop, pxBottom;

//-- Setup

void setup(void) {
   char buf[20];
   
   // Serial for for debug, not works if shield is plugged in arduino
   Serial.begin(115200);

   // Initialize the controller

   uint16_t identifier = tft.readID();
   if( identifier == 0x0D3D3 ) {
      identifier = 0x9481;
   }

   switch( identifier ) {
      case 0x9341:
         Serial.println(F("Found ILI9341 LCD driver"));
         tft.begin(identifier);
         break;
      case 0x9325:
         Serial.println(F("Found ILI9325 LCD driver"));
         tft.begin(identifier);
         break;
      case 0x9328:
         Serial.println(F("Found ILI9328 LCD driver"));
         tft.begin(identifier);
         break;
      case 0x4535:
         Serial.println(F("Found LGDP4535 LCD driver"));
         tft.begin(identifier);
         break;
      case 0x7575:
         Serial.println(F("Found HX8347G LCD driver"));
         tft.begin(identifier);
         break;
      case 0x8357:
         Serial.println(F("Found HX8357D LCD driver"));
         tft.begin(identifier);
         break;
      default:
         Serial.printf(F("Unknown LCD driver chip: %04X\n"), identifier);
         tft.begin(0x9341);
         break;
   }
   tft.setRotation(0); // Need for the Mega, please changed for your choice or rotation initial
   portrait = tft.getRotation() % 2 == 0;
   
   width = tft.width() - 1;
   height = tft.height() - 1;

   // Debug
   Serial.printf(F("TFT LCD calibration setup\n"));
   Serial.printf("TFT size is %ux%u\n", tft.width(), tft.height()); 

   initializeButtons();
   drawBorder();

   // Initial screen
   tft.setCursor(65, 50);
   tft.setTextSize(3);
   tft.setTextColor(RED);
   int16_t y = 10 * height / 64; 
   switch( identifier ) {
      case 0x9341:
         tft.drawCentredText(y, "ILI9341");
         break;
      case 0x9325:
         tft.drawCentredText(y, "ILI9325");
         break;
      case 0x9328:
         tft.drawCentredText(y, "ILI9328");
         break;
      case 0x4535:
         tft.drawCentredText(y, "LGDP4535");
         break;
      case 0x7575:
         tft.drawCentredText(y, "HX8347G");
         break;
      case 0x8357:
         tft.drawCentredText(y, "HX8357D");
         break;
      default:
         snprintf(buf, sizeof buf, "? %04X", identifier);
         tft.drawCentredText(y, buf);
         break;
   }
   tft.drawCentredText(10 * height / 38, "Library");
   tft.setTextSize(2);
   tft.setTextColor(BLACK);
   tft.drawCentredText( 10 * height / 21, "Calibration");

   tft.setTextSize(1);
   tft.setTextColor(BLACK);
   tft.drawCentredText( 10 * height / 13, "Touch to proceed");

   waitOneTouch();     // Wait touch
   calibrate_TS();     // Calibrate it
   waitOneTouch();     // Wait touch
   showCalibration();  // Calibration
}

// -- Loop

void loop()
{
   int16_t x,y;
   
   // Test of calibration
   TSPoint p;
   p = waitOneTouch();

   // Map of values
   x = mapXValue(p);
   y = mapYValue(p);
   
   if( y >= 10 ) {   
      tft.fillCircle(x, y, 1, BLUE);  // Draw a point
   }
   showTouched(p);  // Show touch screen point (TSPOINT)

   // Go thru all the buttons, checking if they were pressed
   for( uint8_t b=0; b<BUTTONS; ++b ) {
      if( buttons[b].contains(x, y) ) {
         switch( b ) {
           
            case BUTTON_CLEAR:
               showCalibration();              // Clear
               break;
              
            case BUTTON_SHOW:
               showResults();
               tft.printf(F("\nTouch to proceed"));
               waitOneTouch();
               showCalibration();
               break;
              
            case BUTTON_RESET:
               // New calibration
               calibrate_TS();
               waitOneTouch();
               showCalibration();
               break;
        }
      }
   }
}

// Calibration of Touch Screen (resistive)
void calibrate_TS(void) {
   // Based in code posted in https://forum.arduino.cc/index.php?topic=223769.15

   TSPoint p1, p2;
   
   pxLeft = 0;
   pxTop = 0;
   pxRight = width;
   pxBottom = height;
   
   switch( tft.getRotation() ) {
      case 0:
         tsLeft = TS_MAXX;
         tsTop = TS_MINY;
         tsRight = TS_MINX;
         tsBottom = TS_MAXY;
         break;
      case 1:
         tsLeft = TS_MINY;
         tsTop = TS_MINX;
         tsRight = TS_MAXY;
         tsBottom = TS_MAXX;
         break;
      case 2:
         tsLeft = TS_MINX;
         tsTop = TS_MAXY;
         tsRight = TS_MAXX;
         tsBottom = TS_MINY;
         break;
      case 3:
         tsLeft = TS_MAXY;
         tsTop = TS_MAXX;
         tsRight = TS_MINY;
         tsBottom = TS_MINX;
         break;
   }

   tft.fillScreen(BLACK);

   tft.drawLine(0,crosshairLng,crosshairLng*2,crosshairLng,WHITE); //show the first point
   tft.drawLine(crosshairLng,0,crosshairLng,crosshairLng*2,WHITE);
   tft.setCursor(5, 30); 
   tft.setTextColor(WHITE); 
   tft.setTextSize(1);
   tft.print(F("Touch the crosshair centre"));

   const uint16_t limit = 40;
   do {
      p1 = waitOneTouch();
   } while (!(mapXValue(p1) < limit && mapYValue(p1) < limit));
   tft.fillScreen(BLACK);

   tft.drawLine(width-crosshairLng*2,height-crosshairLng,width,height-crosshairLng,WHITE);//show the 2nd point
   tft.drawLine(width-crosshairLng,height-crosshairLng*2,width-crosshairLng,height,WHITE);
   tft.setCursor(width - 26 * 6 - 5, height - 30 - 8);
   tft.print(F("Touch the crosshair centre"));
   delay(500); // debounce
   do {
      p2 = waitOneTouch();
   } while (!(mapXValue(p2) > (width - limit) && mapYValue(p2) > (height - limit)));
   tft.fillScreen(BLACK);
   delay(300); 
   Serial.printf(F("\nRaw points: \n"));
   Serial.printf(F("Pt 1: %u : %u\n"), p1.x, p1.y);
   Serial.printf(F("Pt 2: %u : %u\n"), p2.x, p2.y);

   if( portrait ) {
      tsLeft = p1.x;
      tsTop = p1.y;
      tsRight = p2.x;
      tsBottom = p2.y;
   } else {
      tsLeft = p1.y;
      tsTop = p1.x;
      tsRight = p2.y;
      tsBottom = p2.x;
   }
   pxLeft = crosshairLng;
   pxTop = crosshairLng;
   pxRight = width - crosshairLng;
   pxBottom = height - crosshairLng;

   // Show results
   showResults();

   tft.printf(F("\nLast touched points: \n"));
   tft.printf(F("Pt 1: %d : %d\n"), mapXValue(p1), mapYValue(p1));
   tft.printf(F("Pt 2: %d : %d\n"), mapXValue(p2), mapYValue(p2));
   // Wait a touch
   tft.printf(F("\nTouch to proceed"));
   waitOneTouch();
}

// wait 1 touch to return the point 
TSPoint waitOneTouch() {
   TSPoint p;
   do {
      p= ts.getPoint(); 
      pinMode(XM, OUTPUT); //Pins configures again for TFT control
      pinMode(YP, OUTPUT);
   } while( p.z < MINPRESSURE || p.z > MAXPRESSURE );
   return p;
}

// Draw a border
void drawBorder () {
  uint8_t border = 10;
  tft.fillScreen(RED);
  tft.fillRect(border, border, (width - border * 2), (height - border * 2), WHITE);
}

// Show a screen of calibration
void showCalibration() {
   // Clear
   tft.fillScreen(BLACK);
   tft.setTextSize (1);

   // Header
   tft.fillRect(0, 0, width, 10, RED);
   tft.setTextColor(WHITE);
   tft.drawCentredText(0, "*** Test of calibration ***");

   // Footer
   TSPoint p; // Only for show initial values
   p.x=0;
   p.y=0;
   p.z=0;
   showTouched(p);

   // Buttons
   for( uint8_t i=0; i<3; ++i ) {
      buttons[i].drawButton();
   } 
}

// Show the coordinates     

void showTouched(TSPoint p) {

   uint8_t w = 40; // Width
   uint8_t h = 10; // Heigth
   uint8_t x = (width - (w*2)); // X
   uint8_t y = 11; // Y

   tft.fillRect(x, y, w*2, h, WHITE); // For cleanup

   tft.drawRect(x, y, w, h, RED); // For X
   tft.drawRect(x+w+2, y, w*2, h, RED); // For Y

   tft.setTextColor(BLACK);
   tft.setCursor(x+2, y + 1);
   tft.printf(F("X: %03u"), p.x);
   tft.setCursor(x+2+w+2, y + 1);
   tft.printf(F("Y: %03u"), p.y);
}

// Show results of calibration
void showResults() {

   tft.fillScreen(BLACK);
   // Header
   tft.fillRect(0, 0, width, 10, RED);
   tft.setCursor (40, 0);
   tft.setTextColor(WHITE);
   tft.print(F("*** Results of calibration ***"));

   // Results
   tft.setCursor(5, 30);
   tft.setTextSize(2);
   tft.println(F("After calibration: "));
   tft.printf(F("tsLeft  = %d\n"), tsLeft);
   tft.printf(F("tsTop   = %d\n\n"), tsTop);
   tft.printf(F("tsRight = %d\n"), tsRight);
   tft.printf(F("tsBottom= %d\n"), tsBottom);
}

// Initialize buttons
void initializeButtons() {

   uint16_t w = 75;
   uint16_t h = 20;
   uint16_t x;
   uint16_t y;
   uint8_t spacing_x = 5;
   uint8_t textSize = 1;

   static char buttonlabels[BUTTONS][9] = {
      "Clear", "Show", "Recalib."
   };
   static uint16_t buttoncolors[BUTTONS] = {
      RED, BLUE, RED
   };

   x = (width + 1) / 2 - spacing_x - w;
   y = height + 1 - h / 2;
   
   for( uint8_t b=0; b<BUTTONS; ++b ) {
      buttons[b].initButton(
         &tft,                               // TFT object
         x+b*(w+spacing_x),  y,              // x, y,
         w, h, WHITE, buttoncolors[b], WHITE,// w, h, outline, fill, 
         buttonlabels[b], textSize);         // text
   }
   // Save the y position to avoid draws
   buttons_y = y;
}

// Map the coordinate X
uint16_t mapXValue(TSPoint p) {
   if( portrait ) {
      return map(p.x, tsLeft, tsRight, pxLeft, pxRight );
   }
   return map(p.y, tsLeft, tsRight, pxLeft, pxRight );
}

// Map the coordinate Y
uint16_t mapYValue(TSPoint p) {
   if( portrait ) {
      return map(p.y, tsTop, tsBottom, pxTop, pxBottom );
   }
   return map(p.x, tsTop, tsBottom, pxTop, pxBottom );
}