lovyan03 / LovyanGFX

SPI LCD graphics library for ESP32 (ESP-IDF/ArduinoESP32) / ESP8266 (ArduinoESP8266) / SAMD51(Seeed ArduinoSAMD51)
Other
1.18k stars 208 forks source link

About LVGL use #141

Closed modi12jin closed 3 years ago

modi12jin commented 3 years ago

image

#include <lvgl.h>
#include <lv_demo.h>
#include <LovyanGFX.hpp>
#include <Arduino.h>

#define LGFX_USE_V1

#define LCD_MOSI    13
#define LCD_MISO    -1
#define LCD_SCK     14
#define LCD_CS      15
#define LCD_RST     22
#define LCD_DC      21
#define LCD_BL      23  

#define LCD_WIDTH   320
#define LCD_HEIGHT  480
#define LCD_SPI_HOST HSPI_HOST

struct LGFX_Config
{
  static constexpr spi_host_device_t spi_host = HSPI_HOST;

  static constexpr int dma_channel = 1;

  static constexpr int spi_sclk = LCD_SCK;
  static constexpr int spi_mosi = LCD_MOSI;
  static constexpr int spi_miso = LCD_MISO;
};

void set_lcd();

// 将 LGFX_SPI 类中准备好的配置结构设置为模板参数并创建一个实例。
static lgfx::LGFX_SPI<LGFX_Config> tft;
static LGFX_Sprite sprite(&tft);

// 创建 Panel 类的实例。 选择适合您的面板的类。
static lgfx::Panel_ST7796 panel;

static lgfx::Touch_FT5x06 touch;// FT5206, FT5306, FT5406, FT6206, FT6236, FT6336, FT6436

/*更改为您的屏幕分辨率*/
static const uint32_t screenWidth  = 480;
static const uint32_t screenHeight = 320;

static lv_disp_draw_buf_t draw_buf;
static lv_color_t buf[ screenWidth * 10 ];

#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 my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p) {
  uint16_t c;

  tft.startWrite(); /* Start new TFT transaction */
  tft.setAddrWindow(area->x1, area->y1, (area->x2 - area->x1 + 1), (area->y2 - area->y1 + 1)); /* set the working window */
  for (int y = area->y1; y <= area->y2; y++) {
    for (int x = area->x1; x <= area->x2; x++) {
      c = color_p->full;
      tft.writeColor(c, 1);
      color_p++;
    }
  }
  tft.endWrite(); /* terminate TFT transaction */
  lv_disp_flush_ready(disp); /* tell lvgl that flushing is done */
}

/*Read the touchpad*/
void my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data) {
    uint16_t touchX, touchY;

    //bool touched = tft.getTouch(&touchX, &touchY, 600);
    bool touched = tft.getTouch(&touchX, &touchY);

    if(touchX>screenWidth || touchY > screenHeight) {
      Serial.println("Y or y outside of expected parameters..");
      Serial.print("y:");
      Serial.print(touchX);
      Serial.print(" x:");
      Serial.print(touchY);
    }
    else {
      data->state = touched ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL; 

      /*Save the state and save the pressed coordinate*/
      //if(data->state == LV_INDEV_STATE_PR) touchpad_get_xy(&last_x, &last_y);

      /*Set the coordinates (if released use the last pressed coordinates)*/
      data->point.x = touchX;
      data->point.y = touchY;

      Serial.print("Data x");
      Serial.println(touchX);

      Serial.print("Data y");
      Serial.println(touchY);

    }

}

void setup()
{
   Serial.begin( 115200 ); /* prepare for possible serial debug */
   Serial.println( "Hello Arduino! (V8.0.X)" );
   Serial.println( "I am LVGL_Arduino" );

   lv_init();

#if LV_USE_LOG != 0
   lv_log_register_print_cb( my_print ); /* register print function for debugging */
#endif

   set_lcd();
   tft.init();          /* TFT init */
   tft.setBrightness(128);
   tft.setRotation( 3 ); /* Landscape orientation, flipped */

   lv_disp_draw_buf_init( &draw_buf, buf, NULL, screenWidth * 10 );

   /*Initialize the display*/
   static lv_disp_drv_t disp_drv;
   lv_disp_drv_init( &disp_drv );
   /*Change the following line to your display resolution*/
   disp_drv.hor_res = screenWidth;
   disp_drv.ver_res = screenHeight;
   disp_drv.flush_cb = my_disp_flush;
   disp_drv.draw_buf = &draw_buf;
   lv_disp_drv_register( &disp_drv );

   /*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;
   lv_indev_drv_register( &indev_drv );

#if 0
   /* Create simple label */
   lv_obj_t *label = lv_label_create( lv_scr_act() );
   lv_label_set_text( label, "Hello Arduino! (V8.0.X)" );
   lv_obj_align( label, LV_ALIGN_CENTER, 0, 0 );
#else
   /* Try an example from the lv_examples Arduino library
      make sure to include it as written above.
   lv_example_btn_1();
   */

   // uncomment one of these demos
   // lv_demo_widgets();            // OK
   // lv_demo_benchmark();          // OK
   lv_demo_keypad_encoder();     // works, but I haven't an encoder
   // lv_demo_music();              // NOK
   // lv_demo_printer();
   // lv_demo_stress();             // seems to be OK
#endif
   Serial.println( "Setup done" );
}

void loop()
{
   lv_timer_handler(); /* let the GUI do its work */
   delay( 5 );
}

void set_lcd()
{
  // パネルクラスに各種設定値を代入していきます。
  // (LCD一体型製品のパネルクラスを選択した場合は、
  //   製品に合った初期値が設定されているので設定は不要です)

  // 通常動作時のSPIクロックを設定します。
  // ESP32のSPIは80MHzを整数で割った値のみ使用可能です。
  // 設定した値に一番近い設定可能な値が使用されます。
  panel.freq_write = 60000000;
  //panel.freq_write = 20000000;

  // 単色の塗り潰し処理時のSPIクロックを設定します。
  // 基本的にはfreq_writeと同じ値を設定しますが、
  // より高い値を設定しても動作する場合があります。
  panel.freq_fill = 60000000;
  //panel.freq_fill  = 27000000;

  // LCDから画素データを読取る際のSPIクロックを設定します。
  panel.freq_read = 16000000;

  // SPI通信モードを0~3から設定します。
  panel.spi_mode = 0;

  // データ読み取り時のSPI通信モードを0~3から設定します。
  panel.spi_mode_read = 0;

  // 画素読出し時のダミービット数を設定します。
  // 画素読出しでビットずれが起きる場合に調整してください。
  panel.len_dummy_read_pixel = 8;

  // データの読取りが可能なパネルの場合はtrueを、不可の場合はfalseを設定します。
  // 省略時はtrueになります。
  panel.spi_read = true;

  // データの読取りMOSIピンで行うパネルの場合はtrueを設定します。
  // 省略時はfalseになります。
  panel.spi_3wire = false;

  // LCDのCSを接続したピン番号を設定します。
  // 使わない場合は省略するか-1を設定します。
  panel.spi_cs = LCD_CS;

  // LCDのDCを接続したピン番号を設定します。
  panel.spi_dc = LCD_DC;

  // LCDのRSTを接続したピン番号を設定します。
  // 使わない場合は省略するか-1を設定します。
  panel.gpio_rst = LCD_RST;

  // LCDのバックライトを接続したピン番号を設定します。
  // 使わない場合は省略するか-1を設定します。
  panel.gpio_bl = LCD_BL;

  // バックライト使用時、輝度制御に使用するPWMチャンネル番号を設定します。
  // PWM輝度制御を使わない場合は省略するか-1を設定します。
  panel.pwm_ch_bl = -1;

  // バックライト点灯時の出力レベルがローかハイかを設定します。
  // 省略時は true。true=HIGHで点灯 / false=LOWで点灯になります。
  panel.backlight_level = true;

  // invertDisplayの初期値を設定します。trueを設定すると反転します。
  // 省略時は false。画面の色が反転している場合は設定を変更してください。
  panel.invert = false;

  // パネルの色順がを設定します。  RGB=true / BGR=false
  // 省略時はfalse。赤と青が入れ替わっている場合は設定を変更してください。
  panel.rgb_order = false;

  // パネルのメモリが持っているピクセル数(幅と高さ)を設定します。
  // 設定が合っていない場合、setRotationを使用した際の座標がずれます。
  // (例:ST7735は 132x162 / 128x160 / 132x132 の3通りが存在します)
  panel.memory_width = LCD_WIDTH;
  panel.memory_height = LCD_HEIGHT;

  // パネルの実際のピクセル数(幅と高さ)を設定します。
  // 省略時はパネルクラスのデフォルト値が使用されます。
  panel.panel_width = LCD_WIDTH;
  panel.panel_height = LCD_HEIGHT;

  // パネルのオフセット量を設定します。
  // 省略時はパネルクラスのデフォルト値が使用されます。
  panel.offset_x = 0;
  panel.offset_y = 0;

  // setRotationの初期化直後の値を設定します。
  panel.rotation = 0;

  // setRotationを使用した時の向きを変更したい場合、offset_rotationを設定します。
  // setRotation(0)での向きを 1の時の向きにしたい場合、 1を設定します。
  panel.offset_rotation = 0;

  // 設定を終えたら、LGFXのsetPanel関数でパネルのポインタを渡します。
  tft.setPanel(&panel);

  // for I2C setting. (FT5x06)
  // I2C接続のタッチパネルの場合
  touch.i2c_port = I2C_NUM_1;
  touch.i2c_sda  = 18;
  touch.i2c_scl  = 19;
  touch.i2c_addr = 0x38;
  touch.freq = 400000;

  // タッチパネルから得られるレンジを設定
  // (キャリブレーションを実施する場合は省略可)
  // (This can be omitted if calibration is performed.)
  touch.x_min = 0;
  touch.x_max = 319;
  touch.y_min = 0;
  touch.y_max = 479;

  tft.setTouch(&touch);
}

https://user-images.githubusercontent.com/40233017/127128554-c180d64d-8a3a-4d01-92bf-838692170f5b.mp4

lovyan03 commented 3 years ago

@modi12jin What is the purpose of this Issue?

modi12jin commented 3 years ago

Use this program to solve the touch problem, but there are color and text problems

#include <lvgl.h>
#include <lv_demo.h>
#include <LovyanGFX.hpp>
#include <Arduino.h>

#define LGFX_USE_V1

struct LGFX_Config
{
  // Select the type of I2S  (I2S_NUM_0 or I2S_NUM_1)
  // default value is I2S_NUM_0
  static constexpr i2s_port_t i2s_port = I2S_NUM_0;

  // Set the parallel pin number
  // パラレル接続の各種ピン番号を設定します。
  static constexpr int gpio_wr  =  4;
  static constexpr int gpio_rd  =  2;
  static constexpr int gpio_rs  = 15;
  static constexpr int gpio_d0  = 12;
  static constexpr int gpio_d1  = 13;
  static constexpr int gpio_d2  = 26;
  static constexpr int gpio_d3  = 25;
  static constexpr int gpio_d4  = 17;
  static constexpr int gpio_d5  = 16;
  static constexpr int gpio_d6  = 27;
  static constexpr int gpio_d7  = 14;
};

void set_lcd();

static lgfx::LGFX_PARALLEL<LGFX_Config> tft;
static LGFX_Sprite sprite(&tft);

// 创建 Panel 类的实例。 选择适合您的面板的类。
static lgfx::Panel_ILI9488 panel;

static lgfx::Touch_FT5x06 touch;// FT5206, FT5306, FT5406, FT6206, FT6236, FT6336, FT6436

/*更改为您的屏幕分辨率*/
static const uint32_t screenWidth  = 480;
static const uint32_t screenHeight = 320;

static lv_disp_draw_buf_t draw_buf;
static lv_color_t buf[ screenWidth * 10 ];

#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 my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p) {
  uint16_t c;

  tft.startWrite(); /* Start new TFT transaction */
  tft.setAddrWindow(area->x1, area->y1, (area->x2 - area->x1 + 1), (area->y2 - area->y1 + 1)); /* set the working window */
  for (int y = area->y1; y <= area->y2; y++) {
    for (int x = area->x1; x <= area->x2; x++) {
      c = color_p->full;
      tft.writeColor(c, 1);
      color_p++;
    }
  }
  tft.endWrite(); /* terminate TFT transaction */
  lv_disp_flush_ready(disp); /* tell lvgl that flushing is done */
}

/*Read the touchpad*/
void my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data) {
    uint16_t touchX, touchY;

    //bool touched = tft.getTouch(&touchX, &touchY, 600);
    bool touched = tft.getTouch(&touchX, &touchY);

    if(touchX>screenWidth || touchY > screenHeight) {
      Serial.println("Y or y outside of expected parameters..");
      Serial.print("y:");
      Serial.print(touchX);
      Serial.print(" x:");
      Serial.print(touchY);
    }
    else {
      data->state = touched ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL; 

      /*Save the state and save the pressed coordinate*/
      //if(data->state == LV_INDEV_STATE_PR) touchpad_get_xy(&last_x, &last_y);

      /*Set the coordinates (if released use the last pressed coordinates)*/
      data->point.x = touchX;
      data->point.y = touchY;

      Serial.print("Data x");
      Serial.println(touchX);

      Serial.print("Data y");
      Serial.println(touchY);

    }

}

void setup()
{
   Serial.begin( 115200 ); /* prepare for possible serial debug */
   Serial.println( "Hello Arduino! (V8.0.X)" );
   Serial.println( "I am LVGL_Arduino" );

   lv_init();

#if LV_USE_LOG != 0
   lv_log_register_print_cb( my_print ); /* register print function for debugging */
#endif

   set_lcd();
   tft.init();          /* TFT init */
   tft.setRotation( 3 ); /* Landscape orientation, flipped */

   lv_disp_draw_buf_init( &draw_buf, buf, NULL, screenWidth * 10 );

   /*Initialize the display*/
   static lv_disp_drv_t disp_drv;
   lv_disp_drv_init( &disp_drv );
   /*Change the following line to your display resolution*/
   disp_drv.hor_res = screenWidth;
   disp_drv.ver_res = screenHeight;
   disp_drv.flush_cb = my_disp_flush;
   disp_drv.draw_buf = &draw_buf;
   lv_disp_drv_register( &disp_drv );

   /*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;
   lv_indev_drv_register( &indev_drv );

#if 0
   /* Create simple label */
   lv_obj_t *label = lv_label_create( lv_scr_act() );
   lv_label_set_text( label, "Hello Arduino! (V8.0.X)" );
   lv_obj_align( label, LV_ALIGN_CENTER, 0, 0 );
#else
   /* Try an example from the lv_examples Arduino library
      make sure to include it as written above.
   lv_example_btn_1();
   */

   // uncomment one of these demos
   // lv_demo_widgets();            // OK
   // lv_demo_benchmark();          // OK
   lv_demo_keypad_encoder();     // works, but I haven't an encoder
   // lv_demo_music();              // NOK
   // lv_demo_printer();
   // lv_demo_stress();             // seems to be OK
#endif
   Serial.println( "Setup done" );
}

void loop()
{
   lv_timer_handler(); /* let the GUI do its work */
   delay( 5 );
}

void set_lcd()
{
  panel.freq_write = 20000000;

  // 设置读取像素时的虚拟位数。
  // 调整读取像素时是否发生位移。
  panel.len_dummy_read_pixel = 8;

  // 设置 LCD CS 所连接的引脚编号。
  // 如果不使用,省略它或设置-1。
  panel.spi_cs = 33;

  // 设置 LCD RST 所连接的引脚编号。
  // 如果不使用,省略它或设置-1。
  panel.gpio_rst = 32;

  // 设置 invertDisplay 的初始值。 如果设置为true,它将被反转。
  // 默认值为假。 如果屏幕颜色反转,请更改设置。
  panel.invert = false;

  // 面板集的颜色顺序。 RGB = 真 / BGR = 假
  // 默认值为假。 如果红色和蓝色交换,请更改设置。
  panel.rgb_order = false;

  panel.memory_width = 320;
  panel.memory_height = 480;

  // 设置面板的实际像素数(宽度和高度)。
  // 如果省略,则使用面板类的默认值。
  panel.panel_width = 320;
  panel.panel_height = 480;

  // パネルのオフセット量を設定します。
  // 省略時はパネルクラスのデフォルト値が使用されます。
  panel.offset_x = 0;
  panel.offset_y = 0;

  // setRotation 初始化后立即设置该值。
  panel.rotation = 0;

  // 如果要在使用 setRotation 时更改方向,请设置 offset_rotation。
  // 如果您希望 setRotation(0) 中的方向为 1 时的方向,则设置为 1。
  panel.offset_rotation = 0;

  // 設定を終えたら、LGFXのsetPanel関数でパネルのポインタを渡します。
  tft.setPanel(&panel);

  // for I2C setting. (FT5x06)
  // I2C接続のタッチパネルの場合
  touch.i2c_port = I2C_NUM_1;
  touch.i2c_sda  = 21;
  touch.i2c_scl  = 22;
  touch.i2c_addr = 0x38;
  touch.freq = 400000;

  // タッチパネルから得られるレンジを設定
  // (キャリブレーションを実施する場合は省略可)
  // (This can be omitted if calibration is performed.)
  touch.x_min = 0;
  touch.x_max = 319;
  touch.y_min = 0;
  touch.y_max = 479;

  tft.setTouch(&touch);
}

20210804181434

20210804_181227

lovyan03 commented 3 years ago

@modi12jin

First of all, LGFX_V0 has a problem in controlling the parallel port, so I solved it with LGFX_V1. In order to use LGFX_V1, you need to write #define LGFX_USE_V1 before #include <LovyanGFX.hpp> . Therefore, the program you presented uses V0. Please check the EXAMPLES for V1, as the configuration method has been changed drastically.

Next, the function my_disp_flush is slowing things down, so change it as follows

void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p) {
  int w = (area->x2 - area->x1 + 1);
  int h = (area->y2 - area->y1 + 1);

  tft.startWrite(); /* Start new TFT transaction */
  tft.setAddrWindow(area->x1, area->y1, w, h); /* set the working window */

  tft.writePixels((lgfx::rgb565_t*)&color_p->full, w*h);

  tft.endWrite(); /* terminate TFT transaction */
  lv_disp_flush_ready(disp); /* tell lvgl that flushing is done */
}

If the colors look wrong, try changing the type to cast.

  tft.writePixels((lgfx::swap565_t*)&color_p->full, w*h);
modi12jin commented 3 years ago

@lovyan03

thank you very much

20210804211352

modi12jin commented 3 years ago
// v1.0.0 を有効にします(v0からの移行期間の特別措置です。これを書かない場合は旧v0系で動作します。)
#define LGFX_USE_V1

#include <lvgl.h>
#include <lv_demo.h>
#include <LovyanGFX.hpp>
#include <Arduino.h>

class LGFX : public lgfx::LGFX_Device
{

   lgfx::Panel_ILI9488 _panel_instance;

   lgfx::Bus_Parallel8 _bus_instance;

   lgfx::Touch_FT5x06  _touch_instance; 

public:
   // コンストラクタを作成し、ここで各種設定を行います。
   // クラス名を変更した場合はコンストラクタも同じ名前を指定してください。
   LGFX(void)
   {
      {                                     // バス制御の設定を行います。
         auto cfg = _bus_instance.config(); // バス設定用の構造体を取得します。

         // 8ビットパラレルバスの設定
         cfg.i2s_port = I2S_NUM_0;  // 使用するI2Sポートを選択 (0 or 1) (ESP32のI2S LCDモードを使用します)
         cfg.freq_write = 20000000; // 送信クロック (最大20MHz, 80MHzを整数で割った値に丸められます)
         cfg.pin_wr = 40;           // WR を接続しているピン番号
         cfg.pin_rd = 42;           // RD を接続しているピン番号
         cfg.pin_rs = 41;           // RS(D/C)を接続しているピン番号
         cfg.pin_d0 = 0;            // D0を接続しているピン番号
         cfg.pin_d1 = 1;            // D1を接続しているピン番号
         cfg.pin_d2 = 2;            // D2を接続しているピン番号
         cfg.pin_d3 = 3;            // D3を接続しているピン番号
         cfg.pin_d4 = 4;            // D4を接続しているピン番号
         cfg.pin_d5 = 5;            // D5を接続しているピン番号
         cfg.pin_d6 = 6;            // D6を接続しているピン番号
         cfg.pin_d7 = 7;            // D7を接続しているピン番号

         _bus_instance.config(cfg);              // 設定値をバスに反映します。
         _panel_instance.setBus(&_bus_instance); // バスをパネルにセットします。
      }

      {                                       // 表示パネル制御の設定を行います。
         auto cfg = _panel_instance.config(); // 表示パネル設定用の構造体を取得します。

         cfg.pin_cs = -1;   // CSが接続されているピン番号   (-1 = disable)
         cfg.pin_rst = 45;  // RSTが接続されているピン番号  (-1 = disable)
         cfg.pin_busy = -1; // BUSYが接続されているピン番号 (-1 = disable)

         // ※ 以下の設定値はパネル毎に一般的な初期値が設定されていますので、不明な項目はコメントアウトして試してみてください。

         cfg.memory_width = 320;   // ドライバICがサポートしている最大の幅
         cfg.memory_height = 480;  // ドライバICがサポートしている最大の高さ
         cfg.panel_width = 320;    // 実際に表示可能な幅
         cfg.panel_height = 480;   // 実際に表示可能な高さ
         cfg.offset_x = 0;         // パネルのX方向オフセット量
         cfg.offset_y = 0;         // パネルのY方向オフセット量
         cfg.offset_rotation = 0;  // 回転方向の値のオフセット 0~7 (4~7は上下反転)
         cfg.dummy_read_pixel = 8; // ピクセル読出し前のダミーリードのビット数
         cfg.dummy_read_bits = 1;  // ピクセル以外のデータ読出し前のダミーリードのビット数
         cfg.readable = true;      // データ読出しが可能な場合 trueに設定
         cfg.invert = false;       // パネルの明暗が反転してしまう場合 trueに設定
         cfg.rgb_order = false;    // パネルの赤と青が入れ替わってしまう場合 trueに設定
         cfg.dlen_16bit = false;   // データ長を16bit単位で送信するパネルの場合 trueに設定
         cfg.bus_shared = true;    // SDカードとバスを共有している場合 trueに設定(drawJpgFile等でバス制御を行います)

         _panel_instance.config(cfg);
      }
    { // タッチスクリーン制御の設定を行います。(必要なければ削除)
      auto cfg = _touch_instance.config();

      cfg.x_min      = 0;    // タッチスクリーンから得られる最小のX値(生の値)
      cfg.x_max      = 319;  // タッチスクリーンから得られる最大のX値(生の値)
      cfg.y_min      = 0;    // タッチスクリーンから得られる最小のY値(生の値)
      cfg.y_max      = 479;  // タッチスクリーンから得られる最大のY値(生の値)
      cfg.pin_int    = -1;   // INTが接続されているピン番号
      cfg.bus_shared = false; // 画面と共通のバスを使用している場合 trueを設定
      cfg.offset_rotation = 0;// 表示とタッチの向きのが一致しない場合の調整 0~7の値で設定

// I2C接続の場合
      cfg.i2c_port = 0;      // 使用するI2Cを選択 (0 or 1)
      cfg.i2c_addr = 0x38;   // I2Cデバイスアドレス番号
      cfg.pin_sda  = 11;     // SDAが接続されているピン番号
      cfg.pin_scl  = 10;     // SCLが接続されているピン番号
      cfg.freq = 400000;     // I2Cクロックを設定

      _touch_instance.config(cfg);
      _panel_instance.setTouch(&_touch_instance);  // タッチスクリーンをパネルにセットします。
    }

      setPanel(&_panel_instance); // 使用するパネルをセットします。
   }
};

// 準備したクラスのインスタンスを作成します。
LGFX tft;

/*更改为您的屏幕分辨率*/
static const uint32_t screenWidth = 480;
static const uint32_t screenHeight = 320;

static lv_disp_draw_buf_t draw_buf;
static lv_color_t buf[screenWidth * 10];

#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 my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p)
{
   int w = (area->x2 - area->x1 + 1);
   int h = (area->y2 - area->y1 + 1);

   tft.startWrite();                            /* Start new TFT transaction */
   tft.setAddrWindow(area->x1, area->y1, w, h); /* set the working window */

   tft.writePixels((lgfx::rgb565_t *)&color_p->full, w * h);

   tft.endWrite();            /* terminate TFT transaction */
   lv_disp_flush_ready(disp); /* tell lvgl that flushing is done */
}

/*Read the touchpad*/
void my_touchpad_read(lv_indev_drv_t *indev_driver, lv_indev_data_t *data)
{
   uint16_t touchX, touchY;

   bool touched =tft.getTouch(&touchX, &touchY);

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

      /*Set the coordinates*/
      data->point.x = touchX;
      data->point.y = touchY;

      Serial.print( "Data x " );
      Serial.println( touchX );

      Serial.print( "Data y " );
      Serial.println( touchY );
   }
}

void setup()
{
   Serial.begin(115200); /* prepare for possible serial debug */
   Serial.println("Hello Arduino! (V8.0.X)");
   Serial.println("I am LVGL_Arduino");

   lv_init();

#if LV_USE_LOG != 0
   lv_log_register_print_cb(my_print); /* register print function for debugging */
#endif

   tft.init();         /* TFT init */
   tft.setRotation(3); /* Landscape orientation, flipped */

   lv_disp_draw_buf_init(&draw_buf, buf, NULL, screenWidth * 10);

   /*Initialize the display*/
   static lv_disp_drv_t disp_drv;
   lv_disp_drv_init(&disp_drv);
   /*Change the following line to your display resolution*/
   disp_drv.hor_res = screenWidth;
   disp_drv.ver_res = screenHeight;
   disp_drv.flush_cb = my_disp_flush;
   disp_drv.draw_buf = &draw_buf;
   lv_disp_drv_register(&disp_drv);

   /*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;
   lv_indev_drv_register(&indev_drv);

#if 0
   /* Create simple label */
   lv_obj_t *label = lv_label_create( lv_scr_act() );
   lv_label_set_text( label, "Hello Arduino! (V8.0.X)" );
   lv_obj_align( label, LV_ALIGN_CENTER, 0, 0 );
#else
   /* Try an example from the lv_examples Arduino library
      make sure to include it as written above.
   lv_example_btn_1();
   */

   // uncomment one of these demos
   lv_demo_widgets();            // OK
   // lv_demo_benchmark();          // OK
   // lv_demo_keypad_encoder(); 
   // works, but I haven't an encoder
   // lv_demo_music();              // NOK
   // lv_demo_printer();
   // lv_demo_stress();             // seems to be OK
#endif
   Serial.println("Setup done");
}

void loop()
{
   lv_timer_handler(); /* let the GUI do its work */
   delay(5);
}

https://user-images.githubusercontent.com/40233017/129477688-e0c3e8b3-f200-49d9-a986-cba397ca183a.mp4

@lovyan03 Thank you very much for fixing the touch error, I am working fine on ESP32 S2

Can you add support for parallel port 16?