ODD TFT touch behavior with Utouch - Due - 5in SainSmart

Ok i’ve been experiencing an odd behavior of my touchscreen lately… I was told it’s a SainSmart so I wouldn’t be surprised it’s a faulty hardware, eventho, I can’t say!

I’m using a basic Utouch Calibration code (as seen below) to get the touch calibrated correctly. I had some problems with the orientation of the screen and the max values outputted by the getX(); and getY(); fcts. Origin of Utouch (0,0) was in a different corner than the origin of UTFT… I believed it was because I did the calibration in PORTRAIT mode and then switched to LANDSCAPE, plus my UTFT origin is on the far side of the connector… but that’s an other issue…

So yesterday, everything was working fine. I admit i’ve been playing a bit with libraries of UTFT and UTOUCH as I deleted everything I didn’t need such as the other screen #define and some stuff for other controller than the SSD1963, so my code would start with something like UTFT myGLCD(SSD1963_800, pin def).
I believe Utouch Calibration code uses that “all other stuff” so when I saw that the calibration wouldn’t work, I superseded all of the libraries with brand new one (my untouched backup) in Arduino’s library folder.

That said, here’s what is happening:
My own code which uses only the SSD1963 variables works fine (except the issue I had with orientation)
When I upload the Utouch calibration, only the first time I touch the screen will work and then, any subsequent touch is invisible to the Arduino. Even a reboot won’t set the touch back to working mode. At that time, if I upload my own code (which was working) the touch still disabled.
The only way I can get it back to working, is to completely disconnect the screen from the Arduino and wait few seconds before I connect it back.

does anyone know if there is some capacitor on the screen which can freak out only because of the calibration code? any clue?

Here’s my calibration code (my own below)

// UTouch_Calibration (C)2013-2014 Henning Karlsen


#include <UTFT.h>
#include <UTouch.h>

// Define the orientation of the touch screen. Further 
// information can be found in the instructions.
#define TOUCH_ORIENTATION  LANDSCAPE


UTFT    myGLCD(CTE50,25,26,27,28);


UTouch  myTouch( 6, 5, 4, 3, 2);


// Declare which fonts we will be using
extern uint8_t SmallFont[];

uint32_t cx, cy;
uint32_t rx[8], ry[8];
uint32_t clx, crx, cty, cby;
float px, py;
int dispx, dispy, text_y_center;
uint32_t calx, caly, cals;
char buf[13];

void setup()
{
  myGLCD.InitLCD();
  myGLCD.clrScr();
  myGLCD.setFont(SmallFont);

  myTouch.InitTouch(TOUCH_ORIENTATION);
  dispx=myGLCD.getDisplayXSize();
  dispy=myGLCD.getDisplayYSize();
  text_y_center=(dispy/2)-6;
}

void drawCrossHair(int x, int y)
{
  myGLCD.drawRect(x-10, y-10, x+10, y+10);
  myGLCD.drawLine(x-5, y, x+5, y);
  myGLCD.drawLine(x, y-5, x, y+5);
}

void readCoordinates()
{
  int iter = 5000;
  int failcount = 0;
  int cnt = 0;
  uint32_t tx=0;
  uint32_t ty=0;
  boolean OK = false;
  
  while (OK == false)
  {
    myGLCD.setColor(255, 255, 255);
    myGLCD.print("*  PRESS  *", CENTER, text_y_center);
    while (myTouch.dataAvailable() == false) {}
    myGLCD.print("*  HOLD!  *", CENTER, text_y_center);
    while ((myTouch.dataAvailable() == true) && (cnt<iter) && (failcount<10000))
    {
      myTouch.calibrateRead();
      if (!((myTouch.TP_X==65535) || (myTouch.TP_Y==65535)))
      {
        tx += myTouch.TP_X;
        ty += myTouch.TP_Y;
        cnt++;
      }
      else
        failcount++;
    }
    if (cnt>=iter)
    {
      OK = true;
    }
    else
    {
      tx = 0;
      ty = 0;
      cnt = 0;
    }
    if (failcount>=10000)
      fail();
  }

  cx = tx / iter;
  cy = ty / iter;
}

void calibrate(int x, int y, int i)
{
  myGLCD.setColor(255, 255, 255);
  drawCrossHair(x,y);
  myGLCD.setBackColor(255, 0, 0);
  readCoordinates();
  myGLCD.setColor(255, 255, 255);
  myGLCD.print("* RELEASE *", CENTER, text_y_center);
  myGLCD.setColor(80, 80, 80);
  drawCrossHair(x,y);
  rx[i]=cx;
  ry[i]=cy;
  while (myTouch.dataAvailable() == true) {}
}

void waitForTouch()
{
  while (myTouch.dataAvailable() == true) {}
  while (myTouch.dataAvailable() == false) {}
  while (myTouch.dataAvailable() == true) {}
}

void toHex(uint32_t num)
{
  buf[0] = '0';
  buf[1] = 'x';
  buf[10] = 'U';
  buf[11] = 'L';
  buf[12] = 0;
  for (int zz=9; zz>1; zz--)
  {
    if ((num & 0xF) > 9)
      buf[zz] = (num & 0xF) + 55;
    else
      buf[zz] = (num & 0xF) + 48;
    num=num>>4;
  }
}

void startup()
{
  myGLCD.setColor(255, 0, 0);
  myGLCD.fillRect(0, 0, dispx-1, 13);
  myGLCD.setColor(255, 255, 255);
  myGLCD.setBackColor(255, 0, 0);
  myGLCD.drawLine(0, 14, dispx-1, 14);
  myGLCD.print("UTouch Calibration", CENTER, 1);
  myGLCD.setBackColor(0, 0, 0);

  if (dispx==220)
  {  
    myGLCD.print("Use a stylus or something", LEFT, 30);
    myGLCD.print("similar to touch as close", LEFT, 42);
    myGLCD.print("to the center of the", LEFT, 54);
    myGLCD.print("highlighted crosshair as", LEFT, 66);
    myGLCD.print("possible. Keep as still as", LEFT, 78);
    myGLCD.print("possible and keep holding", LEFT, 90);
    myGLCD.print("until the highlight is", LEFT, 102);
    myGLCD.print("removed. Repeat for all", LEFT, 114);
    myGLCD.print("crosshairs in sequence.", LEFT, 126);
    myGLCD.print("Touch screen to continue", CENTER, 162);
  }
  else
  {
    myGLCD.print("INSTRUCTIONS", CENTER, 30);
    myGLCD.print("Use a stylus or something similar to", LEFT, 50);
    myGLCD.print("touch as close to the center of the", LEFT, 62);
    myGLCD.print("highlighted crosshair as possible. Keep", LEFT, 74);
    myGLCD.print("as still as possible and keep holding", LEFT, 86);
    myGLCD.print("until the highlight is removed. Repeat", LEFT, 98);
    myGLCD.print("for all crosshairs in sequence.", LEFT, 110);

    myGLCD.print("Further instructions will be displayed", LEFT, 134);
    myGLCD.print("when the calibration is complete.", LEFT, 146);

    myGLCD.print("Do NOT use your finger as a calibration", LEFT, 170);
    myGLCD.print("stylus or the result WILL BE imprecise.", LEFT, 182);

    myGLCD.print("Touch screen to continue", CENTER, 226);
  }

  waitForTouch();
  myGLCD.clrScr();
}

void done()
{
  myGLCD.clrScr();
  myGLCD.setColor(255, 0, 0);
  myGLCD.fillRect(0, 0, dispx-1, 13);
  myGLCD.setColor(255, 255, 255);
  myGLCD.setBackColor(255, 0, 0);
  myGLCD.drawLine(0, 14, dispx-1, 14);
  myGLCD.print("UTouch Calibration", CENTER, 1);
  myGLCD.setBackColor(0, 0, 0);
  
  if (dispx==220)
  {  
    myGLCD.print("To use the new calibration", LEFT, 30);
    myGLCD.print("settings you must edit the", LEFT, 42);
    myGLCD.setColor(160, 160, 255);
    myGLCD.print("UTouchCD.h", LEFT, 54);
    myGLCD.setColor(255, 255, 255);
    myGLCD.print("file and change", 88, 54);
    myGLCD.print("the following values. The", LEFT, 66);
    myGLCD.print("values are located right", LEFT, 78);
    myGLCD.print("below the opening comment.", LEFT, 90);
    myGLCD.print("CAL_X", LEFT, 110);
    myGLCD.print("CAL_Y", LEFT, 122);
    myGLCD.print("CAL_S", LEFT, 134);
    toHex(calx);
    myGLCD.print(buf, 75, 110);
    toHex(caly);
    myGLCD.print(buf, 75, 122);
    toHex(cals);
    myGLCD.print(buf, 75, 134);
  }
  else
  {  
    myGLCD.print("CALIBRATION COMPLETE", CENTER, 30);
    myGLCD.print("To use the new calibration", LEFT, 50);
    myGLCD.print("settings you must edit the", LEFT, 62);
    myGLCD.setColor(160, 160, 255);
    myGLCD.print("UTouchCD.h", LEFT, 74);
    myGLCD.setColor(255, 255, 255);
    myGLCD.print("file and change", 88, 74);
    myGLCD.print("the following values.", LEFT, 86);
    myGLCD.print("The values are located right", LEFT, 98);
    myGLCD.print("below the opening comment in", LEFT, 110);
    myGLCD.print("the file.", LEFT, 122);
    myGLCD.print("CAL_X", LEFT, 150);
    myGLCD.print("CAL_Y", LEFT, 162);
    myGLCD.print("CAL_S", LEFT, 174);

    toHex(calx);
    myGLCD.print(buf, 75, 150);
    toHex(caly);
    myGLCD.print(buf, 75, 162);
    toHex(cals);
    myGLCD.print(buf, 75, 174);
  }
  
}

void fail()
{
  myGLCD.clrScr();
  myGLCD.setColor(255, 0, 0);
  myGLCD.fillRect(0, 0, dispx-1, 13);
  myGLCD.setColor(255, 255, 255);
  myGLCD.setBackColor(255, 0, 0);
  myGLCD.drawLine(0, 14, dispx-1, 14);
  myGLCD.print("UTouch Calibration FAILED", CENTER, 1);
  myGLCD.setBackColor(0, 0, 0);
  
  myGLCD.print("Unable to read the position", LEFT, 30);
  myGLCD.print("of the press. This is a", LEFT, 42);
  myGLCD.print("hardware issue and can", 88, 54);
  myGLCD.print("not be corrected in", LEFT, 66);
  myGLCD.print("software.", LEFT, 78);
  
  while(true) {};
}

void loop()
{
  startup();
  
  myGLCD.setColor(80, 80, 80);
  drawCrossHair(dispx-11, 10);
  drawCrossHair(dispx/2, 10);
  drawCrossHair(10, 10);
  drawCrossHair(dispx-11, dispy/2);
  drawCrossHair(10, dispy/2);
  drawCrossHair(dispx-11, dispy-11);
  drawCrossHair(dispx/2, dispy-11);
  drawCrossHair(10, dispy-11);
  myGLCD.setColor(255, 255, 255);
  myGLCD.setBackColor(255, 0, 0);
  myGLCD.print("***********", CENTER, text_y_center-12);
  myGLCD.print("***********", CENTER, text_y_center+12);

  calibrate(10, 10, 0);
  calibrate(10, dispy/2, 1);
  calibrate(10, dispy-11, 2);
  calibrate(dispx/2, 10, 3);
  calibrate(dispx/2, dispy-11, 4);
  calibrate(dispx-11, 10, 5);
  calibrate(dispx-11, dispy/2, 6);
  calibrate(dispx-11, dispy-11, 7);

}

continued…

  if (TOUCH_ORIENTATION == LANDSCAPE)
    cals=(long(dispx-1)<<12)+(dispy-1);
  else
    cals=(long(dispy-1)<<12)+(dispx-1);

  if (TOUCH_ORIENTATION == PORTRAIT)
    px = abs(((float(rx[2]+rx[4]+rx[7])/3)-(float(rx[0]+rx[3]+rx[5])/3))/(dispy-20));  // PORTRAIT
  else
    px = abs(((float(rx[5]+rx[6]+rx[7])/3)-(float(rx[0]+rx[1]+rx[2])/3))/(dispy-20));  // LANDSCAPE

  if (TOUCH_ORIENTATION == PORTRAIT)
  {
    clx = (((rx[0]+rx[3]+rx[5])/3));  // PORTRAIT
    crx = (((rx[2]+rx[4]+rx[7])/3));  // PORTRAIT
  }
  else
  {
    clx = (((rx[0]+rx[1]+rx[2])/3));  // LANDSCAPE
    crx = (((rx[5]+rx[6]+rx[7])/3));  // LANDSCAPE
  }
  if (clx<crx)
  {
    clx = clx - (px*10);
    crx = crx + (px*10);
  }
  else
  {
    clx = clx + (px*10);
    crx = crx - (px*10);
  }
  
  if (TOUCH_ORIENTATION == PORTRAIT)
    py = abs(((float(ry[5]+ry[6]+ry[7])/3)-(float(ry[0]+ry[1]+ry[2])/3))/(dispx-20));  // PORTRAIT
  else
    py = abs(((float(ry[0]+ry[3]+ry[5])/3)-(float(ry[2]+ry[4]+ry[7])/3))/(dispx-20));  // LANDSCAPE

  if (TOUCH_ORIENTATION == PORTRAIT)
  {
    cty = (((ry[5]+ry[6]+ry[7])/3));  // PORTRAIT
    cby = (((ry[0]+ry[1]+ry[2])/3));  // PORTRAIT
  }
  else
  {
    cty = (((ry[0]+ry[3]+ry[5])/3));  // LANDSCAPE
    cby = (((ry[2]+ry[4]+ry[7])/3));  // LANDSCAPE
  }
  if (cty<cby)
  {
    cty = cty - (py*10);
    cby = cby + (py*10);
  }
  else
  {
    cty = cty + (py*10);
    cby = cby - (py*10);
  }
  
  calx = (long(clx)<<14) + long(crx);
  caly = (long(cty)<<14) + long(cby);
  if (TOUCH_ORIENTATION == LANDSCAPE)
    cals = cals + (1L<<31);

  done();
  while(true) {}

And the working one

// UTFT_Demo_800x480 (C)2013 Henning Karlsen

#include <UTFT.h>
#include <UTouch.h>
byte orientation = LANDSCAPE;
// Declare which fonts we will be using
extern uint8_t SmallFont[];
extern uint8_t BigFont[];
int dispx, dispy, Pix_X , Pix_Y, Head_Hgt, Footer_Hgt, charHGT, Main_L_Y, countour, activ_Wdt1, Wdt1,
    Limx, center_x, center_y, Ltopy, Lboty, Limy, LimyT, LimyB, Ltopx, Lbotx;


UTFT myGLCD(SSD1963_800, 25, 26, 27, 28); // Remember to change the model parameter to suit your display module!
UTouch  myTouch( 6, 5, 4, 3, 2);
void setup()
{
  randomSeed(analogRead(0));

  // Setup the LCD
  myGLCD.InitLCD(orientation);
  myTouch.InitTouch(orientation);
  dispx = myGLCD.getDisplayXSize();
  dispy = myGLCD.getDisplayYSize();
  Pix_X = dispx - 1;
  Pix_Y = dispy - 1;
  Head_Hgt = 25;
  Footer_Hgt = 120;
  charHGT = 11;
  Main_L_Y = Pix_Y - Footer_Hgt;
  countour = 20;
  activ_Wdt1 = Pix_X - countour;
  Wdt1 = activ_Wdt1 / 5;
  Limx = 10;
  center_x = (Pix_X) / 2;
  center_y = (Pix_Y - Footer_Hgt - Head_Hgt) / 2 + Head_Hgt;
  Ltopy = center_y - 3;
  Lboty = center_y + 3;
  Limy = 10;
  LimyT = Head_Hgt + Limy;
  LimyB = Main_L_Y - Limy;
  Ltopx = center_x - 3;
  Lbotx = center_x + 3;
}

void loop()
{
  int buf[798];
  int x, x2;
  int y, y2;
  int r;
  DrawHome();
  myGLCD.setColor(0, 0, 255); //Blue
  myGLCD.drawRect(0, Head_Hgt, Pix_X, Main_L_Y);
  // Draw crosshairs
  myGLCD.setColor(0, 0, 255);
  myGLCD.setBackColor(0, 0, 0);
  myGLCD.drawLine(center_x, Head_Hgt + 1, center_x, Main_L_Y);
  myGLCD.drawLine(1, center_y, Pix_X - 1, center_y);
  for (int i = Limx - 1; i <= Pix_Y - Limx; i += Limx)
  {
    myGLCD.drawLine(i, Ltopy, i, Lboty);
  }
  for (int i = LimyT; i < LimyB; i += Limy)
  {
    myGLCD.drawLine(Ltopx, i, Lbotx, i);
  }

  // Draw sin-, cos- and tan-lines
  myGLCD.setColor(0, 255, 255);
  myGLCD.print("Sin", 5, Head_Hgt + 1);
  int extremums = (Main_L_Y - Head_Hgt) / 2 - 50;

  bool witness = false;
  while (myTouch.dataAvailable() == false && witness == false)
  {

    x = 1;
    for (int i = 1; i < ((Pix_X - 1) * 20); i++)
    {
      x++;
      if (x == Pix_X)
        x = 1;
      if (i > Pix_X)
      {
        if ((x == 399) || (buf[x - 1] == center_y))
          myGLCD.setColor(0, 0, 255);
        else
          myGLCD.setColor(0, 0, 0);
        myGLCD.drawPixel(x, buf[x - 1]);
      }
      myGLCD.setColor(0, 255, 255);
      y = center_y + (sin(((i * 1.65) * 3.14) / 180) * (extremums - (i / 100)));
      myGLCD.drawPixel(x, y);
      buf[x - 1] = y;
      if (myTouch.dataAvailable() == true ) {
        witness = true;
        i = 20 * Pix_X;
      }
    }
  }
  if (myTouch.dataAvailable() == true && witness == true)
  {
    for (int i = 1; i < Pix_X - 1; i++)
    {
      myGLCD.drawPixel(i, center_y + (sin(((i * 1.13) * 3.14) / 180)*extremums));
    }

    myGLCD.setColor(255, 0, 0);
    myGLCD.print("Cos", 5, Head_Hgt + charHGT + 1);
    for (int i = 1; i < Pix_X; i++)
    {
      myGLCD.drawPixel(i, center_y + (cos(((i * 1.13) * 3.14) / 180)*extremums));
    }

    myGLCD.setColor(255, 255, 0);
    myGLCD.print("Tan", 5, Head_Hgt + 2 * charHGT + 1);
    for (int i = 1; i < Pix_X; i++)
    {
      myGLCD.drawPixel(i, center_y + (tan(((i * 0.9) * 3.14) / 180)));
    }
    myTouch.read();
    char X_val[20];
    itoa(myTouch.getX(), X_val, 10);
    char* X_str = "X = ";
    strcat(X_str, X_val);
    myGLCD.print(X_val, CENTER, center_y);
    
    char Y_val[4];
    itoa(myTouch.getY(), Y_val, 10);
    char* Y_str = "Y = ";
    strcat(Y_str, Y_val);
    myGLCD.print(Y_val, CENTER, center_y + charHGT);
    
    /*char str[80];
    strcpy (str, "these ");
    strcat (str, "strings ");
    strcat (str, "are ");
    strcat (str, "concatenated.");
    myGLCD.print(str, CENTER, center_y + charHGT);
    
     int X_Val =myTouch.getX();
     if (X_Val >160)
       myGLCD.print("Left", CENTER, center_y);
       else if (X_Val<160 && !(X_Val==0))
       myGLCD.print("Right", CENTER, center_y);
       else if (X_Val==0)
       myGLCD.print("Zero", CENTER, center_y);
       int Y_Val =myTouch.getY();
         if (Y_Val >120)
       myGLCD.print("Bottom", CENTER, center_y+charHGT);
       else if (Y_Val <120 && !(Y_Val==0))
       myGLCD.print("Top", CENTER, center_y+charHGT);
       else if (Y_Val==0)
       myGLCD.print("Zero", CENTER, center_y+charHGT);*/
  }
  while (myTouch.dataAvailable() == true && witness == true)
  {
    if (myTouch.dataAvailable() == false)
      witness == false;
  }

  myGLCD.fillScr(0, 0, 255);
  myGLCD.setColor(255, 0, 0);
  myGLCD.fillRoundRect(320, 190, 479, 289);

  myGLCD.setColor(255, 255, 255);
  myGLCD.setBackColor(255, 0, 0);
  myGLCD.print("That's it!", CENTER, 213);
  myGLCD.print("Restarting in a", CENTER, 239);
  myGLCD.print("few seconds...", CENTER, 252);

  myGLCD.setColor(0, 255, 0);
  myGLCD.setBackColor(0, 0, 255);
  myGLCD.print("Runtime: (msecs)", CENTER, 450);
  myGLCD.printNumI(millis(), CENTER, 465);

  delay (1000);
}

With it’s little bro

void DrawHome()
{
    myGLCD.clrScr();
  // Defines dimentions of header/footer
  myGLCD.setColor(255, 0, 0); // Red 
  myGLCD.fillRect(0, 0, Pix_X, Head_Hgt-1); // Header fill
  myGLCD.setColor(64, 64, 64); // Grey
  myGLCD.fillRect(0, Main_L_Y, Pix_X, dispy-1); // Footer fill
  myGLCD.setColor(0,50,222);
  for (int i=countour; i<activ_Wdt1; i+=Wdt1)
  {
     myGLCD.fillRoundRect(i,Main_L_Y+countour,i+Wdt1-countour,Pix_Y-countour);
  }
  myGLCD.setColor(255, 255, 255); // White
  myGLCD.setBackColor(255, 0, 0); // Red
  myGLCD.setFont(BigFont);
  myGLCD.print("PROGRAMME DE CONTROLE D'HABITACLE", CENTER, 1);
  myGLCD.setBackColor(0,50,222);
  myGLCD.setColor(255,255,0);
  myGLCD.setFont(SmallFont);
  myGLCD.print("P1_800X480", CENTER, Main_L_Y+countour+2);
}

void waitForTouch()
{
  while (myTouch.dataAvailable() == true) {}
  while (myTouch.dataAvailable() == false) {}
  while (myTouch.dataAvailable() == true) {}
}

everything works randomly fine now…

SORRY top drag up old topic but what does it do with the calibrated settings? (not expert code reader) I ran the first one on a SSD1963 and it worked with only having to change the model and pins, but it just goes back to the start after its finished and does not appear to "calibrate" or store or change anything.

Think about it. The TFT may be orientated in any direction. Ok, most have 0,0 at top left hand corner and the ribbon cable at the bottom edge of Portrait.

Likewise, the Touch screen often has its ribbon cable at the bottom left hand edge. But any combinations of TFT and Touch can appear. Often the Touch has some printed Icons at the bottom edge that are outside the TFT display area.

Then the actual wiring of the X and Y lines from the Touch screen can be swapped on the Touch controller chip.

When you run the calibration program, it can determine the exact correlation of the Touch and Display. Principally, it gets the X and Y directions correct. And it will give you the right values for any postion in the display area. Follow the instructions in the UTouch calibration program.

When you run the Paint program the drawing will follow your stylus exactly. With an uncalibrated Touch, the drawing may drift away at the bottom of the screen. Or even draw in the wrong direction!

David.

Nope. Running calibration sketch and updating the UtouchCD file makes its worse. (Does nothing) But the supplier has just emailed me some other library to try so will and see how that goes. I am thinking the Henning UTFT library is not compatible for both my screens (5 inch sainsmart with sainsmart adapter on mega R3, and a 7 inch sainsmart screen with a sainsmart adapter on a Due.)

Well, you have to declare which pins are connected to the Touch controller.

Life is a lot easier if you post a link to your actual screen. Make sure that any photos on this link correspond exactly with the screen on your bench. Paste the constructor statements that you are using for both the UTFT and UTOUCH objects.

You would probably get an answer within the day.

David.

its fixed. pins were ok, it was just the sainsmart was assembled with x plane somehow configured mirrored. I just programmed it out, with

x = myTouch.getX();
    y = myTouch.getY();
    if ((x!=-1) and (y!=-1))
    {
      myGLCD.drawPixel ((800-x), y);"

Just calibrated "backwards" and the calibrator checker on hennings site was thumbs up, so entered it in and added the x = (800-x) bit and presto, working like new:)

cheers.