Description
I can get display and touchscreen working with eSPI.
I can get the display working with LVGL.
I cannot get the touchscreen working with XPT2046.
Hence I cannot have LVGL working with the touchscreen.
As far as I can see, LVGL only works with XPT2046 for touchscreens, or am I already wrong here?
So I basically have a XPT2046 problem, I guess, it’s only that seemingly LVGL requires it
Funny enough, I read somewhere TFT_eSPI is also working with XPT2046 under the hood…
What MCU/Processor/Board and compiler are you using?
A 3.5" no name CYD with ESP32-WROOM-32 (Board name ESP32-035). Schematic attached.
I am using VScode and Arduino Framework.
What do you want to achieve?
Either: Have Display and touchscreen handled by LVGL / XPT2046.
Or: Have LVGL recognize the inputs detected by eSPI.
What have you tried so far?
I am total noob with ESP32, only did some arduino stuff so far.
-
I tried to have display and touchscreen working with TFT_eSPI and XPT2046, but without success (LVGL not even involved here).
Touch is continously detected, random coordinates, no change when touching the screen.
I cannot fathom what settings I have to put there. -
I tried to have LVGL pick up the touch data from eSPI.
Basically i tried to create an XPT2046 touchscreen, in the hope “touchscreen_read” gets called by LVGL and I could pass the coordinates read by eSPI tft.
Unfortunately it seems “touchscreen_read” never gets called.
I think this is anyway a completely wrong approach.
Code to reproduce
This code works (Display and touchscreen handled by eSPI)
#include "FS.h"
#include <SPI.h>
#include <TFT_eSPI.h>
#define CALIBRATION_FILE "/calibrationData"
TFT_eSPI tft = TFT_eSPI();
#define RUNCALIBNOW 0
uint16_t color565 (uint8_t r, uint8_t g, uint8_t b){
return ((r)<<11) + ((g)<<6)+(b);
}
void fill()
{
for (int i = 320; i >= 0; i--) {
tft.drawFastHLine(0, i, tft.width(), color565(10,0,int((320-i)/10)));
}
}
void setup(void) {
uint16_t calibrationData[5];
uint8_t calDataOK = 0;
Serial.begin(115200);
tft.init();
tft.setRotation(3);
tft.fillScreen((0xFFFF));
tft.setCursor(20, 0, 2);
tft.setTextColor(TFT_WHITE);
tft.setTextSize(4);
tft.println("calibration run");
// check file system
if (!SPIFFS.begin()) {
SPIFFS.format();
SPIFFS.begin();
}
// check if calibration file exists
if (SPIFFS.exists(CALIBRATION_FILE)) {
File f = SPIFFS.open(CALIBRATION_FILE, "r");
if (f) {
if (f.readBytes((char *)calibrationData, 14) == 14) calDataOK = 1;
f.close();
}
}
if (calDataOK && !RUNCALIBNOW) {
// calibration data valid
tft.setTouch(calibrationData);
} else {
// data not valid. recalibrate
tft.calibrateTouch(calibrationData, TFT_WHITE, TFT_RED, 15);
// store data
File f = SPIFFS.open(CALIBRATION_FILE, "w");
if (f) {
f.write((const unsigned char *)calibrationData, 14);
f.close();
}
}
fill();
}
void loop() {
uint16_t x, y;
if (tft.getTouch(&x, &y)) {
fill();
tft.setCursor(160, 100, 2);
tft.printf("x: %i ", x);
tft.setCursor(160, 160, 2);
tft.printf("y: %i ", y);
tft.drawCircle(x,y,6,color565(31,31,31));
}
}
with following setup.h settings
#define ILI9486_DRIVER
#define ESP32_DMA
#define TFT_MISO 12
#define TFT_MOSI 13
#define TFT_SCLK 14
#define TFT_CS 15
#define TFT_DC 2
#define TFT_RST -1
#define TFT_BL 27
#define TOUCH_CS 33
This is not working (Always touch detected, random coordinates, no change whether touched or not)
#include <SPI.h>
#include <TFT_eSPI.h>
#include <XPT2046_Touchscreen.h>
TFT_eSPI tft = TFT_eSPI();
// Touchscreen pins
#define XPT2046_IRQ 36 // T_IRQ
#define XPT2046_MOSI 12 // T_DIN
#define XPT2046_MISO 13 // T_OUT
#define XPT2046_CLK 14 // T_CLK
#define XPT2046_CS 33 // T_CS
SPIClass touchscreenSPI = SPIClass(VSPI);
XPT2046_Touchscreen touchscreen(XPT2046_CS, XPT2046_IRQ);
#define SCREEN_WIDTH 480
#define SCREEN_HEIGHT 320
#define FONT_SIZE 2
// Touchscreen coordinates: (x, y) and pressure (z)
int x, y, z;
// Print Touchscreen info about X, Y and Pressure (Z) on the Serial Monitor
void printTouchToSerial(int touchX, int touchY, int touchZ) {
Serial.print("X = ");
Serial.print(touchX);
Serial.print(" | Y = ");
Serial.print(touchY);
Serial.print(" | Pressure = ");
Serial.print(touchZ);
Serial.println();
}
// Print Touchscreen info about X, Y and Pressure (Z) on the TFT Display
void printTouchToDisplay(int touchX, int touchY, int touchZ) {
// Clear TFT screen
tft.fillScreen(TFT_WHITE);
tft.setTextColor(TFT_BLACK, TFT_WHITE);
int centerX = SCREEN_WIDTH / 2;
int textY = 80;
String tempText = "X = " + String(touchX);
tft.drawCentreString(tempText, centerX, textY, FONT_SIZE);
textY += 20;
tempText = "Y = " + String(touchY);
tft.drawCentreString(tempText, centerX, textY, FONT_SIZE);
textY += 20;
tempText = "Pressure = " + String(touchZ);
tft.drawCentreString(tempText, centerX, textY, FONT_SIZE);
}
void setup() {
Serial.begin(115200);
// Start the SPI for the touchscreen and init the touchscreen
touchscreenSPI.begin(XPT2046_CLK, XPT2046_MISO, XPT2046_MOSI, XPT2046_CS);
touchscreen.begin(touchscreenSPI);
// Set the Touchscreen rotation in landscape mode
// Note: in some displays, the touchscreen might be upside down, so you might need to set the rotation to 3: touchscreen.setRotation(3);
touchscreen.setRotation(1);
// Start the tft display
tft.init();
// Set the TFT display rotation in landscape mode
tft.setRotation(1);
// Clear the screen before writing to it
tft.fillScreen(TFT_WHITE);
tft.setTextColor(TFT_BLACK, TFT_WHITE);
// Set X and Y coordinates for center of display
int centerX = SCREEN_WIDTH / 2;
int centerY = SCREEN_HEIGHT / 2;
tft.drawCentreString("Hello, world!", centerX, 30, FONT_SIZE);
tft.drawCentreString("Touch screen to test", centerX, centerY, FONT_SIZE);
}
void loop() {
// Checks if Touchscreen was touched, and prints X, Y and Pressure (Z) info on the TFT display and Serial Monitor
if (touchscreen.tirqTouched() && touchscreen.touched()) {
// Get Touchscreen points
TS_Point p = touchscreen.getPoint();
// Calibrate Touchscreen points with map function to the correct width and height
x = map(p.x, 200, 3700, 1, SCREEN_WIDTH);
y = map(p.y, 240, 3800, 1, SCREEN_HEIGHT);
z = p.z;
printTouchToSerial(x, y, z);
printTouchToDisplay(x, y, z);
delay(100);
}
}