Rotate touch points?


I am trying to run the basic Arduino examples (in this case the ‘lv_example_btn_2’) after doing some modifications to the base Arduino example ino file to incorporate the FT6206 touch driver. So far, everything is almost working. I am able to get the button example displayed correctly. I am able to capture the touch points and have verified that the touchpoint reported by FT6206 and LVGL are aligned. That said, it seems like the touchpoints associated with the button example are not lining up with the button that is rendered on the screen (i.e. when I press the button which is centered on the screen, I see that the touchpoint coordinates are (120, 160) but nothing happens. Now if I touch a different portion of the screen (140, 110 as an example), the touch event is recognized. It seems as if the coordinates that are expected by the button widget are not aligned to the rendered screen.

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

ESP32-S3-DevKitC-1-N32R8V along with the Adafruit 2.8 capacitive touch screen mentioned here

What LVGL version are you using?


What do you want to achieve?

When I press the lvgl widget on the screen, the touch event should be recognized in the same coordinates of where the widget is rendered.

What have you tried so far?

I have tried rotating the display, various touchpoint mappings, etc. with no luck

Code to reproduce

Add a code snippet which can run in the simulator. It should contain only the relevant code that compiles without errors when separated from your main code base.

The code block(s) should be formatted like:

#include "/Documents/Arduino/libraries/lvgl/examples/lv_examples.h"
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include "lvgl.h"
#include <TFT_eSPI.h>
#include <Adafruit_FT6206.h>

/*Change to your screen resolution*/
/*Change to your screen resolution*/
static const uint16_t screenWidth  = 320;
static const uint16_t screenHeight = 240;

static lv_disp_draw_buf_t disp_buf;
static lv_color_t buf[ screenWidth * screenHeight / 10 ];

// The FT6206 uses hardware I2C (SCL/SDA)
Adafruit_FT6206 touch = Adafruit_FT6206();
TFT_eSPI tft = TFT_eSPI(screenWidth,screenHeight); /* TFT instance */

void my_disp_flush( lv_disp_drv_t *disp_drv, 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.setAddrWindow( area->x1, area->y1, w, h );
    tft.pushColors( ( uint16_t * )&color_p->full, w * h, true );

    lv_disp_flush_ready( disp_drv );

void my_touchpad_read(lv_indev_drv_t * drv, lv_indev_data_t * data)
    bool touched = touch.touched();
    if (touched)
        TS_Point point = touch.getPoint();

        // Print raw touch coordinates
        Serial.print("Raw X: ");
        Serial.print(", Y: ");

        // Map the touch coordinates to match the screen resolution and orientation
        uint16_t touchX = point.x;
        uint16_t touchY = point.y;
        //uint16_t touchX = map(point.x, 0, 320, 0, 320);
        //uint16_t touchY = map(point.y, 0, 240, 0, 240);

        data->point.x = touchX;
        data->point.y = touchY;

        Serial.print("Touched at X: ");
        Serial.print(", Y: ");

    if (!touched)
        data->state = LV_INDEV_STATE_REL;
        data->state = LV_INDEV_STATE_PR;

void setup()
  Serial.begin(115200); /* prepare for possible serial debug */

  if (!touch.begin(40)) {  // pass in 'sensitivity' coefficient
    Serial.println("Couldn't start FT6206 touchscreen controller");
  } else {
    Serial.println("FT6206 touchscreen controller CONNECTED!");

  lv_disp_draw_buf_init(&disp_buf, buf, NULL, screenWidth*10);
  //lv_disp_draw_buf_init(&disp_buf, buf, NULL, screenWidth * screenHeight / 10);

  static lv_disp_drv_t disp_drv;          /*A variable to hold the drivers. Must be static or global.*/
  lv_disp_drv_init(&disp_drv);            /*Basic initialization*/
  disp_drv.draw_buf = &disp_buf;          /*Set an initialized buffer*/
  disp_drv.flush_cb = my_disp_flush;        /*Set a flush callback to draw to the display*/
  disp_drv.hor_res = screenWidth;                 /*Set the horizontal resolution in pixels*/
  disp_drv.ver_res = screenHeight;                 /*Set the vertical resolution in pixels*/
  lv_disp_t * disp;
  disp = lv_disp_drv_register(&disp_drv); /*Register the driver and save the created display objects*/

  static lv_indev_drv_t indev_drv;
  lv_indev_drv_init(&indev_drv);      /*Basic initialization*/
  indev_drv.type = LV_INDEV_TYPE_POINTER;                 /*See below.*/
  indev_drv.read_cb = my_touchpad_read;              /*See below.*/
  /*Register the driver in LVGL and save the created input device object*/
  lv_indev_t * my_indev = lv_indev_drv_register(&indev_drv);
//Check vertical and horizontal resolution of what lvgl sees
  lv_coord_t hor_res = lv_disp_get_hor_res(NULL);
  Serial.print("LVGL Horizontal Resolution: ");

  //Check vertical and horizontal resolution of what lvgl sees
  lv_coord_t ver_res = lv_disp_get_ver_res(NULL);
  Serial.print("LVGL Vertical Resolution: ");

  lv_coord_t disp_dpi = lv_disp_get_dpi(NULL);
  Serial.print("LVGL Display DPI: ");


void loop()
    lv_task_handler(); /* let the GUI do its work */
    delay( 5 );

Screenshot and/or video

As you can see, the touchpoint for the button in the lv_example_bt_2 are off. The drawn box is where the button press it being recognized.

Similarly, when I try lv_example_bt_1, it has a similar issue.