Color 320x240 TFT Touchscreen - Touch Help

Status
Not open for further replies.

rfresh737

Well-known member
I'm having trouble getting the Color 320x240 TFT Touchscreen I purchased from here, to recognize touch.

I had this working on a 3.2 and now I trying to use a 3.6 I recently purchased. I'm thinking it has something to do with the 3.6 board, but I don't know for sure.

I've stripped down my code to just the touch function to keep it simple.

I'm hoping someone can see what I'm doing wrong.

Thank you...

Code:
#include <XPT2046_Touchscreen.h>
#include "SPI.h"
#include "ILI9341_t3.h"
#include "font_Georgia.h"
#include "font_CourierNew.h"

#define CS_PIN  8
#define TFT_DC  9
#define TFT_CS 10
 
// Use hardware SPI (on Uno, #13, #12, #11) and the above for CS/DC
ILI9341_t3 tft = ILI9341_t3(TFT_CS, TFT_DC);

XPT2046_Touchscreen ts(CS_PIN);
TS_Point p;

int intPaintSplashScreen = 0;

void setup()
{
	tft.begin();
	tft.setRotation(1);
	tft.fillScreen(ILI9341_BLACK);

	Serial.begin(9600);
	while (!Serial & millis() <4000)
	{
	}
	Serial.println("ILI9341 Test");
}

void loop(void)
{
	if (intPaintSplashScreen == 0)
	{
		paint_Splash_Screen();
		intPaintSplashScreen++;
		delay(250);
	}
	TS_Point p = ts.getPoint();
	//      value, fromLow, fromHigh, toLow, toHigh
	p.x = map(p.x, 204, 948, 0, 320);
	p.y = map(p.y, 195, 910, 0, 240);
	if (p.x > 0 && p.x < 100 && p.y > 0 && p.y < 100)
	{
		Serial.print("touched!");
		delay(250);
	}
} // end Loop()

void paint_Splash_Screen()
{
	tft.setRotation(1);  
	tft.setTextColor(ILI9341_GREEN);
	tft.setFont(CourierNew_14);
	tft.setCursor(106, 110);
	tft.print("Touch Screen");  
}
 
I have not that touchscreen at hand, so my help could only be theoretical. But for that, I'd have to know what exactly does not work... Are there compiler errors, or doesn't the splash screen paint, or...
 
Sorry, I should know better.

When I touch the screen, I don't get a response in the code "Touch Screen". I touch the screen all over the face and nothing seems to happen to trigger the serial message "Touch Screen".
 
Last edited:
I don't see a begin in your code for the Touch Screen.

For example my Touch paint that I did for my ILI9341_t3n library starts off like:
Code:
void setup(void) {
  while (!Serial && (millis() <= 1000));

  Serial.begin(9600);
  Serial.println(F("Touch Paint!"));

  tft.begin();

  if (!ts.begin()) {
    Serial.println("Couldn't start touchscreen controller");
    while (1);
  }
  Serial.println("Touchscreen started");

  tft.fillScreen(ILI9341_BLACK);
...
 
Tft.begin sets up the display and gets the display going.

Ts.begin sets up the separate touchscreen controller ic on the display board and gets the touchscreen hardware also going.

You will not get any response from the touchscreen controller until you initialize it.

Have you tried going back to the basics and running the basic touchscreen example from the examples included with the standard install ?
 
Last edited:
>Have you tried going back to the basics and running the basic touchscreen example from the examples included with the standard install ?

No...which one should I use to test, with my 3.6 setup?

I added your ts.begin code block and I see the "Touchscreen started" line, but there is still no "touched!" in the serial monitor when I touch the screen.

Code:
#include <XPT2046_Touchscreen.h>
#include "SPI.h"
#include "ILI9341_t3.h"
#include "font_Georgia.h"
#include "font_CourierNew.h"

#define CS_PIN  8
#define TFT_DC  9
#define TFT_CS 10
 
// Use hardware SPI (on Uno, #13, #12, #11) and the above for CS/DC
ILI9341_t3 tft = ILI9341_t3(TFT_CS, TFT_DC);

XPT2046_Touchscreen ts(CS_PIN);
TS_Point p;

int intPaintSplashScreen = 0;

void setup()
{
	tft.begin();
	tft.setRotation(1);
	tft.fillScreen(ILI9341_BLACK);

	Serial.begin(9600);
	while (!Serial & millis() <4000)
	{
	}
	Serial.println("ILI9341 Test");
	if (!ts.begin())
	{
		Serial.println("Couldn't start touchscreen controller");
		while (1);
	}
	Serial.println("Touchscreen started");
}

void loop(void)
{
	if (intPaintSplashScreen == 0)
	{
		paint_Splash_Screen();
		intPaintSplashScreen++;
		delay(250);
	}
	TS_Point p = ts.getPoint();
	//      value, fromLow, fromHigh, toLow, toHigh
	p.x = map(p.x, 204, 948, 0, 320);
	p.y = map(p.y, 195, 910, 0, 240);
	if (p.x > 0 && p.x < 200 && p.y > 0 && p.y < 200)
	{
		Serial.print("touched!");
		delay(250);
	}
} // end Loop()

void paint_Splash_Screen()
{
	tft.setRotation(1);  
	tft.setTextColor(ILI9341_GREEN);
	tft.setFont(CourierNew_14);
	tft.setCursor(106, 110);
	tft.print("Touch Screen");  
}
 
First you can try, the Example code that comes with the XPT2046 library: Some name like ILI9341 test.

Second you should check your map functions as I don't have an idea where your bounds are from? You can first play using ts.touched() to see if the touch screen is touched and then see where there values are. Note: the Touch screen outputs values something like 0-4000 so your range like 204-908 is some small subset.


My code was simply based off values I saw there have been a couple of other posts about this recently.
Code:
...
// This is calibration data for the raw touch data to the screen coordinates
// Warning, These are values I did from observing one of my own screens, so your milage may differ
#define TS_MINX 337
#define TS_MINY 529
#define TS_MAXX 3729
#define TS_MAXY 3711
...


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

  // p is in ILI9341_t3 setOrientation 1 settings. so we need to map x and y differently.
/*
  Serial.print("X = "); Serial.print(p.x);
  Serial.print("\tY = "); Serial.print(p.y);
  Serial.print("\tPressure = "); Serial.print(p.z);
*/

  // Scale from ~0->4000 to tft.width using the calibration #'s
#ifdef SCREEN_ORIENTATION_1
  p.x = map(p.x, TS_MINX, TS_MAXX, 0, tft.width());
  p.y = map(p.y, TS_MINY, TS_MAXY, 0, tft.height());
#else
  
  uint16_t px = map(p.y, TS_MAXY, TS_MINY, 0, tft.width());
  p.y = map(p.x, TS_MINX, TS_MAXX, 0, tft.height());
  p.x = px;
#endif
/*  
    Serial.print(" ("); Serial.print(p.x);
    Serial.print(", "); Serial.print(p.y);
    Serial.println(")");
*/  
#endif
You will see I have some Serial.prints commented out, but this is what I used to get an idea of what the touch screen was doing.
 
Here is what I see in my serial window:

Code:
X = 0	Y = 0	Pressure = 4095 (-31, -39)
X = 0	Y = 0	Pressure = 4095 (-31, -39)
X = 0	Y = 0	Pressure = 4095 (-31, -39)
X = 0	Y = 0	Pressure = 4095 (-31, -39)
X = 0	Y = 0	Pressure = 4095 (-31, -39)
X = 0	Y = 0	Pressure = 4095 (-31, -39)
X = 0	Y = 0	Pressure = 4095 (-31, -39)
X = 0	Y = 0	Pressure = 4095 (-31, -39)
X = 0	Y = 0	Pressure = 4095 (-31, -39)
X = 0	Y = 0	Pressure = 4095 (-31, -39)
X = 0	Y = 0	Pressure = 4095 (-31, -39)
X = 0	Y = 0	Pressure = 4095 (-31, -39)
X = 0	Y = 0	Pressure = 4095 (-31, -39)

And here is current code with some of your code snippets:

Code:
#include <XPT2046_Touchscreen.h>
#include "SPI.h"
#include "ILI9341_t3.h"
#include "font_Georgia.h"
#include "font_CourierNew.h"

#define TS_MINX 337
#define TS_MINY 529
#define TS_MAXX 3729
#define TS_MAXY 3711

#define CS_PIN  8
#define TFT_DC  9
#define TFT_CS 10
 
// Use hardware SPI (on Uno, #13, #12, #11) and the above for CS/DC
ILI9341_t3 tft = ILI9341_t3(TFT_CS, TFT_DC);

XPT2046_Touchscreen ts(CS_PIN);
TS_Point p;

int intPaintSplashScreen = 0;

void setup()
{
	tft.begin();
	tft.setRotation(1);
	tft.fillScreen(ILI9341_BLACK);

	Serial.begin(9600);
	while (!Serial & millis() <4000)
	{
	}
	Serial.println("ILI9341 Test");
	if (!ts.begin())
	{
		Serial.println("Couldn't start touchscreen controller");
		while (1);
	}
	Serial.println("Touchscreen started");
}

void loop(void)
{
	if (intPaintSplashScreen == 0)
	{
		paint_Splash_Screen();
		intPaintSplashScreen++;
		delay(250);
	}
	TS_Point p = ts.getPoint();
	Serial.print("X = "); Serial.print(p.x);
	Serial.print("\tY = "); Serial.print(p.y);
	Serial.print("\tPressure = "); Serial.print(p.z);
	//      value, fromLow, fromHigh, toLow, toHigh
	p.x = map(p.x, TS_MINX, TS_MAXX, 0, tft.width());
	p.y = map(p.y, TS_MINY, TS_MAXY, 0, tft.height());
	Serial.print(" ("); Serial.print(p.x);
	Serial.print(", "); Serial.print(p.y);
	Serial.println(")");
	delay(1000);
	if (p.x > 0 && p.x < 200 && p.y > 0 && p.y < 200)
	{
		Serial.print("touched!");
		delay(250);
	}
} // end Loop()

void paint_Splash_Screen()
{
	tft.setRotation(1);  
	tft.setTextColor(ILI9341_GREEN);
	tft.setFont(CourierNew_14);
	tft.setCursor(106, 110);
	tft.print("Touch Screen");  
}
 
What happens if you, add:
if (! ts.touched()) {
return;
}

In loop right after your test for if (intPaintSplashScreen) code, ie right before the getPoint... I usually have this when I am doing printing as to not get a bunch of not pressed...

Kurt

Edit: Again forgot to mention my loop starts off by checking to see if there is any TS data available:
Code:
void loop()
{
  // See if there's any  touch data for us
  if (ts.bufferEmpty()) {
    return;
  }



Edit: The complete example one is up on my github, but is setup for my ILI9241_t3n library which uses SPIN to work on different SPI buses. https://github.com/KurtE/ILI9341_t3n/tree/master/examples/touchpaint_xpt2046
 
Last edited:
Please see attachment.

I added both of your suggested blocks of code.

The x y pressure serial print code is still getting executed.

Code:
#include <XPT2046_Touchscreen.h>
#include "SPI.h"
#include "ILI9341_t3.h"
#include "font_Georgia.h"
#include "font_CourierNew.h"

#define TS_MINX 337
#define TS_MINY 529
#define TS_MAXX 3729
#define TS_MAXY 3711

#define CS_PIN  8
#define TFT_DC  9
#define TFT_CS 10
 
// Use hardware SPI (on Uno, #13, #12, #11) and the above for CS/DC
ILI9341_t3 tft = ILI9341_t3(TFT_CS, TFT_DC);

XPT2046_Touchscreen ts(CS_PIN);
TS_Point p;

int intPaintSplashScreen = 0;

void setup()
{
	tft.begin();
	tft.setRotation(1);
	tft.fillScreen(ILI9341_BLACK);

	Serial.begin(9600);
	while (!Serial & millis() <4000)
	{
	}
	Serial.println("ILI9341 Test");
	if (!ts.begin())
	{
		Serial.println("Couldn't start touchscreen controller");
		while (1);
	}
	Serial.println("Touchscreen started");
}

void loop(void)
{
	if (intPaintSplashScreen == 0)
	{
		paint_Splash_Screen();
		intPaintSplashScreen++;
		delay(250);
	}
	TS_Point p = ts.getPoint();
	if (ts.bufferEmpty())
	{
		return;
	}
	if (!ts.touched())
	{
		return;
	}
	Serial.print("X = "); Serial.print(p.x);
	Serial.print("\tY = "); Serial.print(p.y);
	Serial.print("\tPressure = "); Serial.print(p.z);
	//      value, fromLow, fromHigh, toLow, toHigh
	p.x = map(p.x, TS_MINX, TS_MAXX, 0, tft.width());
	p.y = map(p.y, TS_MINY, TS_MAXY, 0, tft.height());
	Serial.print(" ("); Serial.print(p.x);
	Serial.print(", "); Serial.print(p.y);
	Serial.println(")");
	delay(1000);
	if (p.x > 0 && p.x < 200 && p.y > 0 && p.y < 200)
	{
		Serial.print("touched!");
		delay(250);
	}
} // end Loop()

void paint_Splash_Screen()
{
	tft.setRotation(1);  
	tft.setTextColor(ILI9341_GREEN);
	tft.setFont(CourierNew_14);
	tft.setCursor(106, 110);
	tft.print("Touch Screen");  
}
 

Attachments

  • 2016-12-16_121111.jpg
    2016-12-16_121111.jpg
    133.7 KB · Views: 190
I ran the Adafruit touchpaint example sketch.

The serial window displays:
Touch Paint!
Couldn't start touchscreen controller

Here is that code.
Code:
/***************************************************
  This is our touchscreen painting example for the Adafruit ILI9341 Shield
  ----> http://www.adafruit.com/products/1651

  Check out the links above for our tutorials and wiring diagrams
  These displays use SPI to communicate, 4 or 5 pins are required to
  interface (RST is optional)
  Adafruit invests time and resources providing this open source code,
  please support Adafruit and open-source hardware by purchasing
  products from Adafruit!

  Written by Limor Fried/Ladyada for Adafruit Industries.
  MIT license, all text above must be included in any redistribution
 ****************************************************/


#include <Adafruit_GFX.h>    // Core graphics library
#include <SPI.h>
#include <Wire.h>      // this is needed even tho we aren't using it
#include <Adafruit_ILI9341.h>
#include <Adafruit_STMPE610.h>

// This is calibration data for the raw touch data to the screen coordinates
#define TS_MINX 150
#define TS_MINY 130
#define TS_MAXX 3800
#define TS_MAXY 4000

// The STMPE610 uses hardware SPI on the shield, and #8
#define STMPE_CS 8
Adafruit_STMPE610 ts = Adafruit_STMPE610(STMPE_CS);

// The display also uses hardware SPI, plus #9 & #10
#define TFT_CS 10
#define TFT_DC 9
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);

// Size of the color selection boxes and the paintbrush size
#define BOXSIZE 40
#define PENRADIUS 3
int oldcolor, currentcolor;

void setup(void) {
 // while (!Serial);     // used for leonardo debugging
 
  Serial.begin(9600);
  while (!Serial & millis() <4000)
  {
  }

  Serial.println(F("Touch Paint!"));
  
  tft.begin();

  if (!ts.begin()) {
    Serial.println("Couldn't start touchscreen controller");
    while (1);
  }
  Serial.println("Touchscreen started");
  
  tft.fillScreen(ILI9341_BLACK);
  
  // make the color selection boxes
  tft.fillRect(0, 0, BOXSIZE, BOXSIZE, ILI9341_RED);
  tft.fillRect(BOXSIZE, 0, BOXSIZE, BOXSIZE, ILI9341_YELLOW);
  tft.fillRect(BOXSIZE*2, 0, BOXSIZE, BOXSIZE, ILI9341_GREEN);
  tft.fillRect(BOXSIZE*3, 0, BOXSIZE, BOXSIZE, ILI9341_CYAN);
  tft.fillRect(BOXSIZE*4, 0, BOXSIZE, BOXSIZE, ILI9341_BLUE);
  tft.fillRect(BOXSIZE*5, 0, BOXSIZE, BOXSIZE, ILI9341_MAGENTA);
 
  // select the current color 'red'
  tft.drawRect(0, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
  currentcolor = ILI9341_RED;
}


void loop()
{
  // See if there's any  touch data for us
  if (ts.bufferEmpty()) {
    return;
  }
  /*
  // You can also wait for a touch
  if (! ts.touched()) {
    return;
  }
  */

  // Retrieve a point  
  TS_Point p = ts.getPoint();
  
 /*
  Serial.print("X = "); Serial.print(p.x);
  Serial.print("\tY = "); Serial.print(p.y);
  Serial.print("\tPressure = "); Serial.println(p.z);  
 */
 
  // Scale from ~0->4000 to tft.width using the calibration #'s
  p.x = map(p.x, TS_MINX, TS_MAXX, 0, tft.width());
  p.y = map(p.y, TS_MINY, TS_MAXY, 0, tft.height());

  /*
  Serial.print("("); Serial.print(p.x);
  Serial.print(", "); Serial.print(p.y);
  Serial.println(")");
  */

  if (p.y < BOXSIZE) {
     oldcolor = currentcolor;

     if (p.x < BOXSIZE) { 
       currentcolor = ILI9341_RED; 
       tft.drawRect(0, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
     } else if (p.x < BOXSIZE*2) {
       currentcolor = ILI9341_YELLOW;
       tft.drawRect(BOXSIZE, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
     } else if (p.x < BOXSIZE*3) {
       currentcolor = ILI9341_GREEN;
       tft.drawRect(BOXSIZE*2, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
     } else if (p.x < BOXSIZE*4) {
       currentcolor = ILI9341_CYAN;
       tft.drawRect(BOXSIZE*3, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
     } else if (p.x < BOXSIZE*5) {
       currentcolor = ILI9341_BLUE;
       tft.drawRect(BOXSIZE*4, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
     } else if (p.x < BOXSIZE*6) {
       currentcolor = ILI9341_MAGENTA;
       tft.drawRect(BOXSIZE*5, 0, BOXSIZE, BOXSIZE, ILI9341_WHITE);
     }

     if (oldcolor != currentcolor) {
        if (oldcolor == ILI9341_RED) 
          tft.fillRect(0, 0, BOXSIZE, BOXSIZE, ILI9341_RED);
        if (oldcolor == ILI9341_YELLOW) 
          tft.fillRect(BOXSIZE, 0, BOXSIZE, BOXSIZE, ILI9341_YELLOW);
        if (oldcolor == ILI9341_GREEN) 
          tft.fillRect(BOXSIZE*2, 0, BOXSIZE, BOXSIZE, ILI9341_GREEN);
        if (oldcolor == ILI9341_CYAN) 
          tft.fillRect(BOXSIZE*3, 0, BOXSIZE, BOXSIZE, ILI9341_CYAN);
        if (oldcolor == ILI9341_BLUE) 
          tft.fillRect(BOXSIZE*4, 0, BOXSIZE, BOXSIZE, ILI9341_BLUE);
        if (oldcolor == ILI9341_MAGENTA) 
          tft.fillRect(BOXSIZE*5, 0, BOXSIZE, BOXSIZE, ILI9341_MAGENTA);
     }
  }
  if (((p.y-PENRADIUS) > BOXSIZE) && ((p.y+PENRADIUS) < tft.height())) {
    tft.fillCircle(p.x, p.y, PENRADIUS, currentcolor);
  }
}
 
I ran the Adafruit touchpaint example sketch.

The serial window displays:
Touch Paint!
Couldn't start touchscreen controller

Here is that code.
Remember the Adafruit touch screen has a different controller chip for the touch screen then the PJRC one. As I mentioned in previous response would help to see picture and to make sure you actually have wire hooked up from pin 8 on your T3.6 to the appropriate pin the the PJRC touch screen.
 
These are the libraries needed to make the PJRC display/touchscreen work correctly.

Code:
#include <ILI9341_t3.h>                    // The PJRC display
#include <font_Arial.h>                    // From ILI9341_t3
#include <XPT2046_Touchscreen.h>           // Includes call to SPI.h
 
I added #include <XPT2046_Touchscreen.h> See current code block below.

I put the is empty test before the get point statement. See attachments.

I'm attaching two pictures showing T_CS (one of my yellow wires) going to pin 8 of the Teensy 3.6

Development IDE shows the serial window display.

Code:
#include <font_Arial.h>                    // From ILI9341_t3
#include <XPT2046_Touchscreen.h>           // Includes call to SPI.h

//#include "SPI.h"
#include "ILI9341_t3.h"
#include "font_Georgia.h"
#include "font_CourierNew.h"

#define TS_MINX 337
#define TS_MINY 529
#define TS_MAXX 3729
#define TS_MAXY 3711

#define CS_PIN  8
#define TFT_DC  9
#define TFT_CS 10
 
// Use hardware SPI (on Uno, #13, #12, #11) and the above for CS/DC
ILI9341_t3 tft = ILI9341_t3(TFT_CS, TFT_DC);

XPT2046_Touchscreen ts(CS_PIN);
TS_Point p;

int intPaintSplashScreen = 0;

void setup()
{
	tft.begin();
	tft.setRotation(1);
	tft.fillScreen(ILI9341_BLACK);

	Serial.begin(9600);
	while (!Serial & millis() <4000)
	{
	}
	Serial.println("ILI9341 Test");
	if (!ts.begin())
	{
		Serial.println("Couldn't start touchscreen controller");
		while (1);
	}
	Serial.println("Touchscreen started");
}

void loop(void)
{
	if (intPaintSplashScreen == 0)
	{
		paint_Splash_Screen();
		intPaintSplashScreen++;
		delay(250);
	}
	if (ts.bufferEmpty())
	{
		return;
	}
	TS_Point p = ts.getPoint();
	if (!ts.touched())
	{
		return;
	}
	Serial.print("X = "); Serial.print(p.x);
	Serial.print("\tY = "); Serial.print(p.y);
	Serial.print("\tPressure = "); Serial.print(p.z);
	//      value, fromLow, fromHigh, toLow, toHigh
	p.x = map(p.x, TS_MINX, TS_MAXX, 0, tft.width());
	p.y = map(p.y, TS_MINY, TS_MAXY, 0, tft.height());
	Serial.print(" ("); Serial.print(p.x);
	Serial.print(", "); Serial.print(p.y);
	Serial.println(")");
	delay(1000);
	if (p.x > 0 && p.x < 200 && p.y > 0 && p.y < 200)
	{
		Serial.print("touched!");
		delay(250);
	}
} // end Loop()

void paint_Splash_Screen()
{
	tft.setRotation(1);  
	tft.setTextColor(ILI9341_GREEN);
	tft.setFont(CourierNew_14);
	tft.setCursor(106, 110);
	tft.print("Touch Screen");  
}
 

Attachments

  • 2016-12-16_132106.jpg
    2016-12-16_132106.jpg
    122 KB · Views: 99
  • 2016-12-16_131828.jpg
    2016-12-16_131828.jpg
    344.7 KB · Views: 165
  • 2016-12-16_131625.jpg
    2016-12-16_131625.jpg
    338.3 KB · Views: 222
Thanks, I can not make out all of the wires, so I would double check all of the wiring of the SPI Touch.
From the PJRC Website:

Code:
_CLK	13 (SCK)	14	
T_CS	8	8	Alternate: any digital pin
T_DIN	11 (DOUT)	7	
T_DO	12 (DIN)	12	
T_IRQ	2	2	Optional: can use any digital pin
For example in you pictures I only see what appears to be one wire going to 13 for the CLK, but both the processor and the Touch require it. Again it may be there already but could not easily follow the wires
 
Success!

>For example in you pictures I only see what appears to be one wire going to 13 for the CLK, but both the processor and the Touch require it.

I kept forgetting on the 3.6 pin 13 is on the 'other side' and I didn't have both wires going to it. You saw it but I kept over looking it.

Much thanks Kurt for hanging in there with me to get this resolved!
 
Status
Not open for further replies.
Back
Top