How to use CST816S with lvgl for gestures


How can I use the CST816S touch driver with lvgl to detect gestures like scrolling and swiping?

What MCU/Processor/Board and compiler are you using?


What LVGL version are you using?

LVGL Version 8.3.4

What do you want to achieve?

Swipe and Scroll Gestures for CST816S

What have you tried so far?

I have tried detecting the gesture and direction of the gesture but it is always 0 since lvgl uses TFT_eSPI for touch controls but I am using the CST816S driver which is not detected.
How can I use the CST816S library to detect gestures such as swiping and scrolling? I am also using a GC9A01 LCD display. The click and Long press are working perfectly. Thanks, I am a newbie at this and have no clue how I can integrate them together.

I’m also working on a project with GC9A01 display with pio and Arduino framework
Here is my experience:
Include “CST816S.h”
Initialize Class CST816S like this:
CST816S mytouch(sda,scl,rst,irq);(here is your i2c attached pin numbers)
Then tell lvgl to read i2c input:
void touchpad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
last_x = 0;
last_y = 0;
if(mytouch.available()) {
last_x =;
last_y =;
data->state = LV_INDEV_STATE_PR;
else {
data->state = LV_INDEV_STATE_REL;
data->point.x = last_x;
data->point.y = last_y;
Next, register callback:
void lv_port_indev_init(void)
static lv_indev_drv_t indev_drv;

/*Register a touchpad input device*/
indev_drv.type = LV_INDEV_TYPE_POINTER;
indev_drv.read_cb = touchpad_read;
indev_touchpad = lv_indev_drv_register(&indev_drv);


In my project,after doing this, lvgl can read my gesture input.
Hope my advice works!

Thanks. It worked I forgot to put the two lines in the function:

data->point.x = last_x;
data->point.y = last_y;

Thanks for helping

Edit: It looks like this void type is probably due to me not using an ESP I guess?

I’m using a pico trying to accomplish the same thing. Are you using the Arduino <CST816S.h> or a custom?
What are you setting the touch cs to?

I get all sorts of kickback when trying to implement your approach with the Arduino library version.
In file included from C:\Users\wimbe\Desktop\LVGL_Arduino\LVGL_Arduino.ino:6:

CST816S.h:74:10: error: variable or field ‘IRAM_ATTR’ declared void
74 | void IRAM_ATTR handleISR();
| ^~~~~~~~~
CST816S.h:74:10: error: expected ‘;’ at end of member declaration
74 | void IRAM_ATTR handleISR();
| ^~~~~~~~~
| ;
CST816S.h:74:20: error: ISO C++ forbids declaration of ‘handleISR’ with no type [-fpermissive]
74 | void IRAM_ATTR handleISR();
| ^~~~~~~~~
LVGL_Arduino.ino: In function ‘void lv_port_indev_init()’:
LVGL_Arduino:64:3: error: ‘indev_touchpad’ was not declared in this scope
64 | indev_touchpad = lv_indev_drv_register(&indev_drv);
| ^~~~~~~~~~~~~~
LVGL_Arduino.ino: In function ‘void my_touchpad_read(lv_indev_drv_t*, lv_indev_data_t*)’:
LVGL_Arduino:86:22: error: ‘class TFT_eSPI’ has no member named ‘getTouch’
86 | bool touched = tft.getTouch( &touchX, &touchY, 600 );
| ^~~~~~~~
LVGL_Arduino.ino: In function ‘void setup()’:
LVGL_Arduino:131:7: error: ‘class TFT_eSPI’ has no member named ‘setTouch’
131 | tft.setTouch( calData );
| ^~~~~~~~
exit status 1
‘indev_touchpad’ was not declared in this scope

Did you declare the User setup for TFT_eSPI? It seems like it’s not able to find the method declarations for getTouch and such but I might be wrong. I had a similar problem when I forgot to declare my pins and drivers for TFT_eSPI.

1 Like

Sorry, Yea in this screenshot I did not because I was troubleshooting the top error.