I have a ILI9341 TFT screen with a TP28017 touchpad connected to an ESP32. This screen uses an 8-bit parallel bus (not SPI)
Screen Manual
I am using the TFT_eSPI library as the screen driver which is all working just fine and looks great.
I am using the Adafruit TouchScreen library for the touchpad, which also works just fine.
My problem is getting the touchpad part to work WITH the screen.
This may be a TFT_eSPI issue but thought I’d ask here first.
Without registering the touchpad the display works perfectly, but when i do register it (lv_indev_drv_register(&indev_drv)
) the screen stops working (white and grey lines) but I am getting touch responses via serial. EDIT - I found the pin mapping of touchscreen XP and XM were backwards, I now get a pure white screen, but no text is being displayed. With lv_indev_drv_register commented out, I see the text I expect
It seems like perhaps the read of the touch pins is blocking the write to the screen bus as they share the same pins. This is just a guess though.
I am 100% positive the wiring and pin definitions are correct as both the screen and the touchpad work independently.
Anyone have any experience with this kind of setup?
main.cpp:
#include "lvgl.h"
#include "TouchScreen.h"
#include "TFT_eSPI.h"
#include "globals.h"
// touchscreen pins
#define YP 27
#define YM 4
#define XP 14
#define XM 2
// display settings
static const uint16_t screenWidth = 240;
static const uint16_t screenHeight = 320;
static lv_disp_draw_buf_t draw_buf;
static lv_disp_drv_t disp_drv; // Descriptor of a display driver
static lv_color_t buf[screenWidth * 10];
TSPoint oldPoint;
TSPoint currPoint;
// declare display elements
lv_obj_t *speedOutput;
lv_obj_t *touchPos;
TFT_eSPI tft = TFT_eSPI(screenWidth, screenHeight); // Invoke custom library
TouchScreen touchInput = TouchScreen(XP, YP, XM, YM, 340);
#if LV_USE_LOG != 0
// Serial debugging
void my_print(lv_log_level_t level, const char *file, uint32_t line, const char *fn_name, const char *dsc)
{
Serial.printf("%s(%s)@%d->%s\r\n", file, fn_name, line, dsc);
Serial.flush();
}
#endif
// Display flushing
void flushDisplay(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p)
{
uint32_t w = (area->x2 - area->x1 + 1);
uint32_t h = (area->y2 - area->y1 + 1);
tft.startWrite();
tft.setAddrWindow(area->x1, area->y1, w, h);
tft.pushColors((uint16_t *)&color_p->full, w * h, true);
tft.endWrite();
lv_disp_flush_ready(disp);
}
// read the touchpad
void getTouchInput(lv_indev_drv_t *indev_driver, lv_indev_data_t *data)
{
// a point object holds x y and z coordinates
currPoint = touchInput.getPoint();
if (currPoint.z > touchInput.pressureThreshhold)
{
data->point.x = currPoint.x;
data->point.y = currPoint.y;
data->state = LV_INDEV_STATE_PR;
Serial.print("X = ");
Serial.print(currPoint.x);
Serial.print("\tY = ");
Serial.print(currPoint.y);
Serial.print("\tPressure = ");
Serial.println(currPoint.z);
lv_label_set_text_fmt(touchPos, "X = %d : Y = %d", currPoint.x, currPoint.y);
}
else
{
data->state = LV_INDEV_STATE_REL;
}
}
void printOutput()
{
lv_label_set_text_fmt(speedOutput, "%4.1f mm/s", wheelSpeed);
}
void setup()
{
lv_init();
tft.begin();
tft.setRotation(0);
lv_disp_draw_buf_init(&draw_buf, buf, NULL, screenWidth * 10);
/*Initialize the display*/
Serial.print("Initializing display... ");
lv_disp_drv_init(&disp_drv);
disp_drv.hor_res = screenWidth;
disp_drv.ver_res = screenHeight;
disp_drv.flush_cb = flushDisplay;
disp_drv.draw_buf = &draw_buf;
lv_disp_drv_register(&disp_drv);
Serial.println("Display Initialized!");
/*Initialize the touchpad*/
Serial.print("Initializing touchpad... ");
// lv_disp_drv_register(&disp_drv);
static lv_indev_drv_t indev_drv; // Descriptor of a touch driver
lv_indev_drv_init(&indev_drv);
indev_drv.type = LV_INDEV_TYPE_POINTER;
indev_drv.read_cb = getTouchInput;
lv_indev_t *my_indev = lv_indev_drv_register(&indev_drv);
// if (my_indev == NULL)
// {
// Serial.println("my_indev is NULL");
// }
// else
// {
// Serial.println("my_indev is NOT NULL");
// }
Serial.println("Touchpad Initialized!");
// create elements
speedOutput = lv_label_create(lv_scr_act());
lv_obj_align(speedOutput, LV_ALIGN_CENTER, 0, 0);
touchPos = lv_label_create(lv_scr_act());
lv_obj_align(touchPos, LV_ALIGN_CENTER, 0, 50);
}
void loop()
{ // runs on core 1
lv_task_handler(); /* let the GUI do its work */
printOutput();
delay(50);
}