ILI9341 & XTP2046 Touch problems

Status
Not open for further replies.
I have a 2.4" ILI9341 screen with an XPT2046 touch controller.
This is the screen: http://www.aliexpress.com/item/240x...2278769615.html?spm=2114.13010608.0.78.HIIx8v
The screen is wired up to a Teensy 3.2 exactly as per the table at https://www.pjrc.com/store/display_ili9341_touch.html and I am running Teensyduino 1.29-beta2

The screen runs graphics fine - the graphicstest and DemoSauce examples work perfectly.
However, I cannot for the life of me get the touch to work at all.

Running the standard ILI9341Test sketch from the XPT2046_Touchscreen folder, all I get is the following output
Code:
...
, x = 0, y = 0
, x = 0, y = 0
, x = 0, y = 0
, x = 0, y = 0
...

Running the TouchTest sketch from the XPT2046_Touchscreen folder I get
Code:
...
Pressure = 4095, x = 0, y = 0
Pressure = 4095, x = 0, y = 0
Pressure = 4095, x = 0, y = 0
Pressure = 4095, x = 0, y = 0
...

I have tried 3 different screens with the same result and I have tried on a couple of different breadboards again with the same result.

Does anybody have any ideas as to what I am doing wrong?!

The ILI9341Test sketch code is
Code:
#include <ILI9341_t3.h>
#include <font_Arial.h> // from ILI9341_t3
#include <XPT2046_Touchscreen.h>
#include <SPI.h>

#define CS_PIN  8
#define TFT_DC  9
#define TFT_CS 10
// MOSI=11, MISO=12, SCK=13

XPT2046_Touchscreen ts(CS_PIN);
#define TIRQ_PIN  2
//XPT2046_Touchscreen ts(CS_PIN);  // Param 2 - NULL - No interrupts
//XPT2046_Touchscreen ts(CS_PIN, 255);  // Param 2 - 255 - No interrupts
//XPT2046_Touchscreen ts(CS_PIN, TIRQ_PIN);  // Param 2 - Touch IRQ Pin - interrupt enabled polling

ILI9341_t3 tft = ILI9341_t3(TFT_CS, TFT_DC);

void setup() {
  Serial.begin(38400);
  tft.begin();
  tft.setRotation(1);
  tft.fillScreen(ILI9341_BLACK);
  ts.begin();
  while (!Serial && (millis() <= 1000));
}

boolean wastouched = true;

void loop() {
  boolean istouched = ts.touched();
  if (istouched) {
    TS_Point p = ts.getPoint();
    if (!wastouched) {
      tft.fillScreen(ILI9341_BLACK);
      tft.setTextColor(ILI9341_YELLOW);
      tft.setFont(Arial_60);
      tft.setCursor(60, 80);
      tft.print("Touch");
    }
    tft.fillRect(100, 150, 140, 60, ILI9341_BLACK);
    tft.setTextColor(ILI9341_GREEN);
    tft.setFont(Arial_24);
    tft.setCursor(100, 150);
    tft.print("X = ");
    tft.print(p.x);
    tft.setCursor(100, 180);
    tft.print("Y = ");
    tft.print(p.y);
    Serial.print(", x = ");
    Serial.print(p.x);
    Serial.print(", y = ");
    Serial.println(p.y);
  } else {
    if (wastouched) {
      tft.fillScreen(ILI9341_BLACK);
      tft.setTextColor(ILI9341_RED);
      tft.setFont(Arial_48);
      tft.setCursor(120, 50);
      tft.print("No");
      tft.setCursor(80, 120);
      tft.print("Touch");
    }
    Serial.println("no touch");
  }
  wastouched = istouched;
  delay(100);
}

The TouchTest sketch code is
Code:
#include <XPT2046_Touchscreen.h>
#include <SPI.h>

#define CS_PIN  8
// MOSI=11, MISO=12, SCK=13

//XPT2046_Touchscreen ts(CS_PIN);
#define TIRQ_PIN  2
//XPT2046_Touchscreen ts(CS_PIN);  // Param 2 - NULL - No interrupts
//XPT2046_Touchscreen ts(CS_PIN, 255);  // Param 2 - 255 - No interrupts
XPT2046_Touchscreen ts(CS_PIN, TIRQ_PIN);  // Param 2 - Touch IRQ Pin - interrupt enabled polling

void setup() {
  Serial.begin(38400);
  ts.begin();
  while (!Serial && (millis() <= 1000));
}

void loopB() {
  TS_Point p = ts.getPoint();
  Serial.print("Pressure = ");
  Serial.print(p.z);
  if (ts.touched()) {
    Serial.print(", x = ");
    Serial.print(p.x);
    Serial.print(", y = ");
    Serial.print(p.y);
  }
  Serial.println();
  //  delay(100);
  delay(30);
}

void loop() {
  if (ts.touched()) {
    TS_Point p = ts.getPoint();
    Serial.print("Pressure = ");
    Serial.print(p.z);
    Serial.print(", x = ");
    Serial.print(p.x);
    Serial.print(", y = ");
    Serial.print(p.y);
    delay(30);
    Serial.println();
  }
}
 
All I can see to suggest is - the following - or some other wire is off in the touch SPI half - or the device isn't functional?::

Is '#define TIRQ_PIN 2' physically wired? If not don't specify that pin. When provided the pin interrupt must be connected, or no touch will be reported.

Wire it up to pin 2 or the pin of your choice - and specify that - or drop the second param.
 
Behavior of note - if working hardware:: watching the Builtin_LED pin #13 - with no screen writes in the sketch::
> If you have the interrupt given in param #2 - there will be no hits on the LED unless you are making a touch on the screen - no matter how many times you call 'touched()', if that doesn't light when touched the LED the interrupt isn't properly reporting on the right pin.
> if you drop out param #2 - you should see LED activity every time you make the touched() call - and perhaps more or longer flashes when you get data back, or if polling faster on touch detected.

Does the unit's PCB look just like the linked one? There is one that doesn't have the XPT2046 SPI controller, it just puts out analog data on two pins that needs to be sampled.
 
Thank you for the replies defragster.
The unit is exactly the one linked - it has the XPT2046 controller in place.

The interrupt pin is physically wired. However in the course of trying to pin (ha!) down the problem I have also tried it without the pin wired and without the parameter but have the same result.
I have also tried using a different pin with no luck.

With no screen writes in the sketch and with or without the interrupt pin the behaviour of the teensy is the same: The LED is flashing without touching the screen. Something is making it detect a touch all the time.

I have also tried a different teensy with the same results and also at different speeds (from 24mHz up to 120mHz).

Given I've tried with different screens and different teensy's I'm sure I am the problem.
Here's the current wiring which works fine for graphics display.
IMG_0488s.jpg

But this is the result from the TouchTest sketch
img2.jpg

Any further suggestions will be very gratefully received.
 
If it were me, I would start trying to see if I could localize down the problem.

Example: Assuming you are using interrupt on pin 2. I would try something like:
Code:
void isrPin( void )
{
	XPT2046_Touchscreen *o = isrPinptr;
	o->isrWake = true;
        Serial.println("$");  // Added could be any print, made short as on interrupt... 
}
Note: this is in the CPP library file.. Then run your test and see if you get any interrupts happening.

I would then probably sprinkle debug information in the update function, to see for example if it actually gets to the point of doing SPI....

Good luck. - Keep meaning to order one of the displays from PJRC
 
Thanks for the suggetion KurtE.

Interrupts are happening (tested as you suggested) but they are being triggered by something other than a touch.
This is possibly due to the update routine which is forcing z above the threshold (and therefore acting like it's had a touch) on every read.

z1 and z2 are both being returned as 0. In the update routine, Serial.printf("z=%d :: z1=%d, z2=%d ", z, z1, z2); returns z=4095 :: z1=0, z2=0

As z is ((0 + 4095) - 0) when I'm not touching the screen that obviously is putting it above the threshold to show a reading.
But it doesn't respond to pressure anywhere on the screen so z1 and z2 are always returning 0.

Still stumped (although a bit closer to finding out what's going on!)...
 
I had same problem what you experienced.

I didn't touch the screen, but returned coordinate values(x=0,y=0,z=4095) continuously.

So I have tried several method and finally solved this problem to use utouch library.

I had set the touch pins different from pjrc instruction.

UTouch myTouch( 18, 17, 16, 15, 2); //t_sck, t_sdo, t_sdi, t_cs, t_irq
(other pins are same as pjrc instruction)

I used onoffbutton sketch(in ILI9341_t3 library) for testing. (need to sketch modify and coordinate calibrate)

I hope this method will help you .
(I'm sorry about my poor english)
 
Last edited:
Any update on this? I've been swamped and just came across this again.

The touch always worked in the end - during touch I got valid readings. There is a minimum threshold under which no touch is there. Perhaps the boards changed and the non-touch state is now on the high side - or results in the number 4096? I'd have to check but I never saw the number 4096.

I did the interrupt detect code for the driver. When that is enabled with no reported touch from the display the poll for touch code should result in no spi traffic. As noted any request for touch info results in a subsequent interrupt, so when watching that pin the software must have that pin. I can also say that when the interrupt fires during overlapping touch and reads there was nothing uniform about the state of the device that I saw.
 
FWIW, I have the exact same problem as the OP.

I have a teensy 3.1 with an audio adapter and a screen (from PJRC: https://www.pjrc.com/store/display_ili9341_touch.html ). The display part works OK (although I did give up on using writeRect() to blit my RGB656 bitmaps as I just couldn't figure out how to use it properly, and ended up rolling my own slow version with drawPixel()), but the touch part gives me the exact same issue as OP.

I just downloaded Arduino 1.6.12 and installed Teensyduino 1-31beta1 on it, went to the pre-cooked example from the menu: TouchTest and reproduced this. None of my code is there, but it does have my wiring.

Is anyone able to get this working? I'd love to hear a report of success so I know it can be achieved!
If you run TouchTest from the standard install, do you get anything that makes sense?

Also I admit I'm a bit confused by the screenshot on the PJRC page: it shows x,y readings that are way higher than the screen resolution... so what am I expecting to get into my x,y returned values?
 
The read of the Touch sensor data is unique and independent of and larger than the pixel count. There is a mapping process to associate the two. The low level code returns the raw data. Some sketches have a mapping I wrote to associate to pixels and allow changing the orientation and having it return pixel coordinates relative to that reference frame. I'm not sure if there are new controllers that return different values? Last I checked (minimally in the past couple months with new Teensy hardware beta) the code I worked with the display I had.
 
The read of the Touch sensor data is unique and independent of and larger than the pixel count. There is a mapping process to associate the two. The low level code returns the raw data. Some sketches have a mapping I wrote to associate to pixels and allow changing the orientation and having it return pixel coordinates relative to that reference frame. I'm not sure if there are new controllers that return different values? Last I checked (minimally in the past couple months with new Teensy hardware beta) the code I worked with the display I had.

OK thanks. That's something I've been missing.
The ColorButtonsMark3 sketch is working with my setup, so at least my wiring with the teensy + audio adaptor + touchscreen seems to be ok. I have a reference that works, so I should be able to move forward.

Thanks again.
 
Glad you found that example. The map function I was referring to is indeed there: ColorButtonsMark3/ButtonMap.cpp

The calibration data didn't quite match my screen (it was slightly off, but not by much: I was unable to register touches close to some edges). I was wondering if that's something that will vary for every single screen. Let's say I buy them all from PJRC here (like the one I currently have) - can I rely on the same calibration data, or is that something that will vary across production of the same units?
 
Henning Karlsen's URTouch Library contains a touchscreen calibration routine.
I used the older library successfully with an XTP2063 touch screen. It works independently of the UTFT Library.
Perhaps you could make use of that library, or develop a similar calibration routine.
 
Henning Karlsen's URTouch Library contains a touchscreen calibration routine.
I used the older library successfully with an XTP2063 touch screen. It works independently of the UTFT Library.
Perhaps you could make use of that library, or develop a similar calibration routine.

Yes definitely. I figured out the values that worked with my screen. But I was wondering, if I build another instance of my product, with the exact same components, will I have to recalibrate the screen for that specific instance?

I'm wondering that because I think defragster is also using the same screen I am (the color touchscreen from PJRC's store), and his calibration values didn't work out of the box for me...

In other words, does calibration have to happen for each product instance of the product before it gets shipped to customers?
 
My couple of units all used the same calibration values I hardcoded into the map...() code. Some from PJRC - some from eBay - and nobody ever used my code and said it wasn't right, but it could be put into the code to modify it with a calibration scheme I expect. Exception was the one prior post - and I never heard back to follow up - something may have changed with that screen and yours.

There was another thread I started on the XPT touch . . . I have been away for that a long time ... but the T_3.6 & T-3.5 have shipped now!
 
Status
Not open for further replies.
Back
Top