ESP32 - 3.5" TFT: NO TOUCH PROBLEM

Hello!
I’m trying to use ESP32 with a 3.5" TFT screen. So far, I have managed to make the screen display graphics using TFT_eSPI library.
However, I can’t get touch working. I have tried this TFT on Arduino MEGA with MCU_FRIEND_kbv library and works perfectly (including touch). MCU_FRIEND_kbv detects the screen (on Arduino MEGA) as ILI9486.

This is the User Setup I’m using:

// See SetupX_Template.h for all options available

#define ESP32_PARALLEL


#define ILI9486_DRIVER
////////////////////////////////////////////

// ESP32 pins used for UNO format board
#define TFT_CS   33  // Chip select control pin (library pulls permanently low
#define TFT_DC   18  //21--- Data Command control pin - must use a pin in the range 0-31
#define TFT_RST  32  // Reset pin, toggles on startup

#define TFT_WR    19  //22--- Write strobe control pin - must use a pin in the range 0-31
#define TFT_RD    23  // Read strobe control pin

#define TFT_D0   13  // Must use pins in the range 0-31 for the data bus
#define TFT_D1   12  // so a single register write sets/clears all bits.
#define TFT_D2   14  // Pins can be randomly assigned, this does not affect
#define TFT_D3   27  // TFT screen update performance.
#define TFT_D4   26
#define TFT_D5   15  //25----
#define TFT_D6   2
#define TFT_D7   4


#define LOAD_GLCD   // Font 1. Original Adafruit 8 pixel font needs ~1820 bytes in FLASH
#define LOAD_FONT2  // Font 2. Small 16 pixel high font, needs ~3534 bytes in FLASH, 96 characters
#define LOAD_FONT4  // Font 4. Medium 26 pixel high font, needs ~5848 bytes in FLASH, 96 characters
#define LOAD_FONT6  // Font 6. Large 48 pixel font, needs ~2666 bytes in FLASH, only characters 1234567890:-.apm
#define LOAD_FONT7  // Font 7. 7 segment 48 pixel font, needs ~2438 bytes in FLASH, only characters 1234567890:.
#define LOAD_FONT8  // Font 8. Large 75 pixel font needs ~3256 bytes in FLASH, only characters 1234567890:-.
#define LOAD_GFXFF  // FreeFonts. Include access to the 48 Adafruit_GFX free fonts FF1 to FF48 and custom fonts

#define SMOOTH_FONT

I have connected the pins as declared above. With this setup, all TFT_eSPI library’s examples do work, with screen displaying graphics properly, except for projects including touch, such as Touch_Controller_Demo. The latter do not compile, with this error message:

'class TFT_eSPI' has no member named 'setTouch'

After a search on the Internet, many people recommended adding this line to the setup file in order to fix this compile error:

#define TOUCH_CS   PIN_D2

After adding this line, projects that include touch functions do compile, but screen insists on not detecting touch.
I tried changing D2 to D33 at the line above so as to match the #define TFT_CS  33 line, but this returns this error message:

exit status 1
Error compiling for board DOIT ESP32 DEVKIT V1.

I would be grateful if you could provide some advice on how to make this work.
Thank you in advance

the library's documentation states

The XPT2046 touch screen controller is supported for SPI based displays only. The SPI bus for the touch controller is shared with the TFT and only an additional chip select line is needed. This support will eventually be deprecated when a suitable touch screen library is avaiable.

what touch screen controller do you have in your TFT? any link to your Screen specs you can share?

(You need a dedicated chip select for the touch controller so don't define TOUCH_CS to be the same pin as your TFT_CS and ensure you pick a 'valid' ESP32 pins - some have special roles)

did you try their calibration example?

Hello!
Thank you for your reply!

what touch screen controller do you have in your TFT? any link to your Screen specs you can share?

Unfortunately, I cannot find the exact eBay page I bought it from, since it has been time since then.
However, MCU_FRIEND_kbv detects the screen (on Arduino MEGA) as ILI9486.
My screen looks exactly like this (as appearance):

.

did you try their calibration example?

I tried the calibration example (using the setup with the #define TOUCH_CS PIN_D2 line, but it does not seem to detect touch. It tells me to touch at the corners, but before Ι touch it switches very quickly to the next corner, until it shows the "Touch screen to test!" message and stands there. Touching the screen does nothing. Serial monitor outputs this:

// Use this calibration code in setup():
  uint16_t calData[5] = { 1, 1, 1, 1, 0 };
  tft.setTouch(calData);

These values do not seem valid to me...

(You need a dedicated chip select for the touch controller so don't define TOUCH_CS to be the same pin as your TFT_CS and ensure you pick a 'valid' ESP32 pins - some have special roles)

How can I find the TOUCH_CS pin on the TFT? I can see only TFT_CS...

Thank you!

so is it 3.5 inch or 4.5 inch ?

Your image looks very much like a Kuman for Arduino UNO R3 3.5 inch TFT Touch Screen with SD Card

if that's the case I believe then this is using a resistive Touch screen overlay driven through 4 wires and there is no SPI driver, hence no Chip Select.

Can you plug the screen back to your MEGA with MCUFRIEND_kbv library and run the diagnose_Touchpins.ino example and you should get some output like

[color=purple]Diagnosing as:-
XM,XP:  (A2, D8) = 25
YP,YM:  (A3, D9) = 32[/color]

Then download this TouchScreen Library (I think it's a copy of Adafruit's work), copy the .h and .cpp in a folder and add the following .ino in the same folder modifying the #define for the pins based on what you got above:

#include <stdint.h>
#include "TouchScreen.h" // within local directory

// ***** MODIFY THIS BASED ON THE diagnose_Touchpins.ino test ***** 
#define YP A3  
#define XM A2 
#define YM 9   
#define XP 8   

TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300); // 300Ω across the X plate

void setup(void) {
  Serial.begin(115200);
}

void loop(void) {
  // a point object holds x y and z coordinates
  TSPoint p = ts.getPoint();
  
  // we have some minimum pressure we consider 'valid'
  // pressure of 0 means no pressing!
  if (p.z > ts.pressureThreshhold) {
     Serial.print("X = "); Serial.print(p.x);
     Serial.print("\tY = "); Serial.print(p.y);
     Serial.print("\tPressure = "); Serial.println(p.z);
  }

  delay(100);
}

open the Serial console at 115200 bauds and see if you are getting some sort of consistent X and Y information ==> if you do then you have your code to read the touch points. Just find where are the pins plugging directly into A2, A3, D8 and D9 (or whatever you got above) and put 4 wires to 4 pins on your ESP. Note that YP and XM must be attached to analog pins on your ESP and you'll probably need to modify the source code of the library to match the capability of an ESP32. Adafruit's version has a plug for ESP8286

#ifdef __AVR
#include <avr/pgmspace.h>
#elif defined(ESP8266)
#include <pgmspace.h>
#endif

so may be you can start from there and adjust as the ADC on your ESP32 is on 12 bits not 10, so don't do math with 1024 but 4096 for example.. would need to dive in (check everywhere there are analogRead() performed and 1023 or 1024 being used)

if you want better pressure precision, find out the resistance between X+ and X- with a multimeter. that's the 300Ω set above as a default.

so is it 3.5 inch or 4.5 inch ?

Thank you for your reply.
It's 3.5". I don't know why I wrote 4.5". :confused:
Sorry I misguided you and wasted your time.
I will try to follow your steps.

Hello!
I followed your instructions, J-M-L, and finally managed to make it detect touch, using Touchscreen.h > touchscreendemo. However, it acts weirdly. It is very sensitive on corners, but it can hardly detect touch in the middle of the screen (you have to press it too much).
Anyway, this is progress! :slight_smile:

so may be you can start from there and adjust as the ADC on your ESP32 is on 12 bits not 10, so don't do math with 1024 but 4096 for example.. would need to dive in (check everywhere there are analogRead() performed and 1023 or 1024 being used)

I really do not understand what to do with this... What maths should I do? :confused:

Thank you!

The library uses analogRead
On a standard Arduino that returns a nul beg between 0 and 1023 because those Arduinos have a 10 bit ADC
And ESP32 has a 12 bit ADC so the same read ranges from 0 to 4095
You need to take that into account in the calculations

The library uses analogRead
On a standard Arduino that returns a nul beg between 0 and 1023 because those Arduinos have a 10 bit ADC
And ESP32 has a 12 bit ADC so the same read ranges from 0 to 4095
You need to take that into account in the calculations

Thank you for your help!
I replaced every 1023 with 4095 and 1024 with 4096 in TouchScreen.cpp.
However, touch detection is still inconsistent. You have to apply much pressure for it to show sth, and at some points it does not detect touch at all. I have tried with another identical screen in case it was a hardware failure, but the same happens...

There is the 300Ω across the X plate that is just a guess too. Try playing with this