I recently bought a Lilygo T-Display-S3 Touch module. It’s neat, it’s pretty, and it’ll be fun to play with.
I made a couple of screens in SquareLine, exported the project and UI files (for Arduino), and swapped out the LVGL and TFT_eSPI folders with the ones from the device’s GitHub. I compiled the UI files, and the screen worked. AWESOME! However, the touch did not.
I did a lot of searching to get the touch feature to work with SquareLine, and there was nada. There wasn’t a lot of support for getting touch to work on this module in general (aside from using TFT_eSPI sprites and TouchLib). I then tried to see if I could make TouchLib play nice with Squareline, but the core libraries are just too different.
I then searched CST816 (the touch chipset) and LVGL, and I found one forum where someone said they got them to play nice. Though it was for a different module, I was able to apply it to the T-Display_S3 and make it work. So without further ado, here is how to get Lilygo’s T-Display-S3 touch features to work with SquareLine.
- Follow the normal SquareLine export process, and replace the library files with the module’s libraries from the Lilygo GitHub (namely, the lvgl and TFT_eSPI folders and lv_conf.h in the main Library folder).
- Download the CST816S library from GitHub and add it to your project library. The CST816S library works for the CST816 chipset.
- Include the new library with the others at the top of the .ino file.
#include <lvgl.h>
#include <TFT_eSPI.h>
#include <ui.h>
#include "CST816S.h" //Add this
- Declare your CST816S after the TFT_eSPI declaration:
TFT_eSPI tft = TFT_eSPI(screenWidth, screenHeight); /* TFT instance */
CST816S myTouch(18, 17, 21, 16); //Add this line
- Find the “my_touchpad_read” function in ui.ino and replace it with the following
void my_touchpad_read( lv_indev_drv_t * indev_driver, lv_indev_data_t * data )
{
uint16_t touchX = 0, touchY = 0;
if (myTouch.available()) {
touchX = myTouch.data.x;
touchY = myTouch.data.y;
data->state = LV_INDEV_STATE_PR;
} else {
data->state = LV_INDEV_STATE_REL;
}
/*Set the coordinates*/
data->point.x = touchX;
data->point.y = touchY;
//I added these conditions just to keep my serial monitor from going crazy
if (touchX != 0) {
Serial.print("Data x ");
Serial.println(touchX);
}
if (touchY != 0) {
Serial.print("Data y ");
Serial.println(touchY);
}
}
- In setup(), add the following after the TFT init stuff:
tft.begin(); /* TFT init */
tft.setRotation( 0 ); /* Landscape orientation, flipped */
myTouch.begin(); //Add this after the TFT init
- The part of setup that initializes the (dummy) input device driver should be fine. Just ensure the indev.drv.read_cb part matches the aforementioned functions name:
/*Initialize the (dummy) input device driver*/
static lv_indev_drv_t indev_drv;
lv_indev_drv_init( &indev_drv );
indev_drv.type = LV_INDEV_TYPE_POINTER;
indev_drv.read_cb = my_touchpad_read; //Since the function was my_touch_read(), this should equal my_touch_read.
lv_indev_drv_register( &indev_drv );
And that should do it. Enjoy!