Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem with ESP32s3 and 480x272 RGB display (module ESP32-4827S043) #374

Closed
Emmanuele75 opened this issue Mar 21, 2023 · 45 comments
Closed
Labels
stale Inactive issues

Comments

@Emmanuele75
Copy link

Emmanuele75 commented Mar 21, 2023

Carefully written Issues are more likely to be given priority.
丁寧に記述された報告は優先して対応される可能性が高くなります。

Environment ( 実行環境 )

  • MCU or Board name: ESP32-4827S043) [ESP32s3 + 4.3" RGB display]
  • Panel Driver IC: ILI6485
  • Bus type: RGB
  • LovyanGFX version: 1.1.5
  • FrameWork version: ArduinoESP32 v2.0.6
  • Build Environment : ArduinoIDE
  • Operating System: Windows

Problem Description ( 問題の内容 )

I encountered a serious bug with the ESP32-4827S043 module, which houses an ESP32S3 and a 4.3" RGB display.
In particular there seems to be problems with the LVGL library, under some conditions the display is not drawn completely.
This happens when there are few animations, on the contrary it seems to work well with complex drawings and lots of active animations.
From what I understand the problem lies with writePixels.
I tried changing the flush_cb from:

void my_disp_flush( 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.writePixels((lgfx::rgb565_t *)&color_p->full, w * h);
   tft.endWrite();
   lv_disp_flush_ready(disp);
}

to:

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

Now the display works fine but it's terribly slow and the animations aren't smooth.
How to solve this problem?
Thanks!
s3

@tobozo
Copy link
Collaborator

tobozo commented Mar 21, 2023

hi, thanks for your feedback 👍

this is untested code, but this loop may be slightly faster:

  for (int y = area->y1; y <= area->y2; y++) {
    tft.setAddrWindow(area->x1, y, w, 1);
    tft.writePixels((lgfx::rgb565_t *)&color_p->full[y*w], w);
  }

@Emmanuele75
Copy link
Author

`I can't compile, I get this error:

C:\Users\emman\Desktop\KEY\COD\LvglWidgets\LvglWidgets.ino: In function 'void my_disp_flush(lv_disp_drv_t*, const lv_area_t*, lv_color_t*)':
LvglWidgets:78:57: error: invalid types 'uint16_t {aka short unsigned int}[int]' for array subscript
tft.writePixels((lgfx::rgb565_t )&color_p->full[yw], w);
^
exit status 1
invalid types 'uint16_t {aka short unsigned int}[int]' for array subscript

`

@tobozo
Copy link
Collaborator

tobozo commented Mar 21, 2023

yep, untested code means it probably has errors you have to fix

I can't check now but the idea is to improve the performance by using writePixels() to send a full line instead of one pixel per iteration.

maybe try one of these:

    tft.writePixels((lgfx::rgb565_t*)(&color_p->full)[y*w], w);
    uint16_t* framebufptr = (uint16_t*)&color_p->full;
    uint16_t* scanlineptr = framebufptr + (y*w);
    tft.writePixels((lgfx::rgb565_t*)scanlineptr, w);

@Emmanuele75
Copy link
Author

okay. I'll try)

@Emmanuele75
Copy link
Author

Emmanuele75 commented Mar 21, 2023

Following your suggestion I compiled this code:

void my_disp_flush( lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p ){
  int c = 0;
  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);
  for (int y = area->y1; y <= area->y2; y++) {
    uint16_t* framebufptr = (uint16_t*)&color_p->full;
    uint16_t* scanlineptr = framebufptr + (c*w);
    tft.writePixels((lgfx::rgb565_t*)scanlineptr, w);
    c++;
  }     
   tft.endWrite();
   lv_disp_flush_ready(disp);
}

Unfortunately the result does not change, the display is not drawn well.
So at the moment the only solution is to draw point by point.
Do you have any other suggestions for me to get rid of this bug?
Thanks!

@tobozo
Copy link
Collaborator

tobozo commented Mar 21, 2023

Do you have any other suggestions for me to get rid of this bug?

not without seeing your LGFX configuration

@Emmanuele75
Copy link
Author

My lgfx_4827S043.h:

#define LGFX_USE_V1
#include <LovyanGFX.hpp>
#include <lgfx/v1/platforms/esp32s3/Panel_RGB.hpp>
#include <lgfx/v1/platforms/esp32s3/Bus_RGB.hpp>

class LGFX : public lgfx::LGFX_Device{
  lgfx::Bus_RGB     _bus_instance;
  lgfx::Panel_RGB   _panel_instance;
  lgfx::Light_PWM   _light_instance;
  lgfx::Touch_XPT2046 _touch_instance;

public:LGFX(void){
  auto cfg    = _bus_instance.config();
  cfg.panel   = &_panel_instance;
  cfg.pin_d0  = GPIO_NUM_8;  // B0
  cfg.pin_d1  = GPIO_NUM_3;  // B1
  cfg.pin_d2  = GPIO_NUM_46; // B2
  cfg.pin_d3  = GPIO_NUM_9;  // B3
  cfg.pin_d4  = GPIO_NUM_1;  // B4
  cfg.pin_d5  = GPIO_NUM_5;  // G0
  cfg.pin_d6  = GPIO_NUM_6;  // G1
  cfg.pin_d7  = GPIO_NUM_7;  // G2
  cfg.pin_d8  = GPIO_NUM_15; // G3
  cfg.pin_d9  = GPIO_NUM_16; // G4
  cfg.pin_d10 = GPIO_NUM_4;  // G5
  cfg.pin_d11 = GPIO_NUM_45; // R0
  cfg.pin_d12 = GPIO_NUM_48; // R1
  cfg.pin_d13 = GPIO_NUM_47; // R2
  cfg.pin_d14 = GPIO_NUM_21; // R3
  cfg.pin_d15 = GPIO_NUM_14; // R4
  cfg.pin_henable       = GPIO_NUM_40;
  cfg.pin_vsync         = GPIO_NUM_41;
  cfg.pin_hsync         = GPIO_NUM_39;
  cfg.pin_pclk          = GPIO_NUM_42;
  cfg.freq_write        = 9000000;   //16000000
  cfg.hsync_polarity    = 0; //0
  cfg.hsync_front_porch = 8; //8
  cfg.hsync_pulse_width = 1; //4
  cfg.hsync_back_porch  = 43; //43
  cfg.vsync_polarity    = 0;  //0
  cfg.vsync_front_porch = 8; //8
  cfg.vsync_pulse_width = 4; //4
  cfg.vsync_back_porch  = 12; //12
  cfg.pclk_idle_high    = 1; //1
  _bus_instance.config(cfg);
  _panel_instance.setBus(&_bus_instance);
  
  { auto cfg = _panel_instance.config();
  cfg.memory_width  = 480;
  cfg.memory_height = 272;
  cfg.panel_width   = 480;
  cfg.panel_height  = 272;
  cfg.offset_x      = 0;
  cfg.offset_y      = 0;
  _panel_instance.config(cfg);
  }
  
  { auto cfg = _panel_instance.config_detail();
  cfg.use_psram = 1;
  _panel_instance.config_detail(cfg);
  }

  { auto cfg = _light_instance.config();
  cfg.pin_bl = GPIO_NUM_2;
  _light_instance.config(cfg);
  }
  _panel_instance.light(&_light_instance);

{ 
      auto cfg = _touch_instance.config();
      cfg.x_min      = 100;    
      cfg.x_max      = 4000;   
      cfg.y_min      = 100;     
      cfg.y_max      = 4000;    
      cfg.pin_int    = -1;    
      cfg.bus_shared = true;  
      cfg.offset_rotation = 0;// 0-7
      cfg.spi_host = 1; // 
      cfg.freq = 1000000;    
      cfg.pin_sclk = 12;     
      cfg.pin_mosi = 11;     
      cfg.pin_miso = 13;     
      cfg.pin_cs   = 38;     
      _touch_instance.config(cfg);
      _panel_instance.setTouch(&_touch_instance);  
    }
  setPanel(&_panel_instance); 
  }
};
static LGFX tft; 

@tobozo
Copy link
Collaborator

tobozo commented Mar 21, 2023

cfg.freq_write = 9000000; seems strange, did you try other values ? 2MHz should be a reasonable start

also I'm not sure about cfg.bus_shared = true; as it doesn't seem like panel and touch are using the same bus

@Emmanuele75
Copy link
Author

Emmanuele75 commented Mar 21, 2023

As for cfg.freq_write it works from 8MHz to 12MHz other values cause the display to flicker and not solve the problem.
For cfg.bus_shared = true or false nothing changes, touch works fine.

@tobozo
Copy link
Collaborator

tobozo commented Mar 21, 2023

another detail: the documentation specifies hsync_polarity and vsync_polarity as negative, so maybe those need to be set to 1 in the LGFX config ?

image

@Emmanuele75
Copy link
Author

I just did the test by changing the parameters hsync_polarity and vsync_polarity with 1, the result doesn't change.
0 or 1 the display is also drawn badly

@tobozo
Copy link
Collaborator

tobozo commented Mar 21, 2023

hsync_pulse_width = 1 seems under the minimal value

image

@Emmanuele75
Copy link
Author

I will do the tests with the new parameters and I will send you the photos.

@Emmanuele75
Copy link
Author

a1
Image 1 with the new parameters, without CPU and memory usage.
Image 2 is about point to point display draw.

@Emmanuele75
Copy link
Author

I tried the library Arduino_GFX_Library.h and the display seems to work fine, it draws everything and fast...the problem is that the display flickers :(

@tobozo
Copy link
Collaborator

tobozo commented Mar 21, 2023

comparing image1 with the image in the first post shows that it had some effect, so maybe it's worth poking with the values.

It would be interesting to know if that glitch always happens at the same line (e.g is that 240th or 256th?).

If so then it could be possible to just split the buffer in two separate writes, e.g. write the first chunk, use tft.endWrite() + tft.startWrite() and write the second chunk?

again, this is untested pseudo-code:

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

  uint32_t max_height = 240; // adjust this

  tft.setAddrWindow(area->x1, area->y1, w, h);

  tft.startWrite();

  if( h > max_height ) {
      tft.writePixels((lgfx::rgb565_t*)&color_p->full, w*max_height); // write first chunk
      tft.endWrite();
      tft.startWrite();
      uint16_t* framebufptr = (uint16_t*)&color_p->full;
      uint16_t* scanlineptr = framebufptr + (max_height*w);
      tft.writePixels((lgfx::rgb565_t*)scanlineptr, w*(h%max_height)); // write second chunk
  } else {
     tft.writePixels((lgfx::rgb565_t*)&color_p->full, w*h);  // write full buffer
  }

  tft.endWrite();
  lv_disp_flush_ready(disp);
}

@Emmanuele75
Copy link
Author

I tried the new code, nothing changes, 240/256 same result.
As for the images I sent you, the difference between the first and last is that the CPU USAGE is activated in the first.

@Emmanuele75
Copy link
Author

With active cpu usage the display works better!

@Emmanuele75
Copy link
Author

Video

14.mp4

@Emmanuele75
Copy link
Author

draw point to point:

15.mp4

@lovyan03
Copy link
Owner

@Emmanuele75 @tobozo
Sorry, I have an idea of the cause and will now work on a fix in the develop branch.
The cause is that you are not calling the write back function properly when writing to PSRAM.

@lovyan03
Copy link
Owner

Incidentally, the following settings on the user side would improve performance and solve the problem.

  • Enable byte swap in LVGL settings

lv_conf.h

#define LV_COLOR_16_SWAP 1
  • Make the output function as follows
void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p){
  tft.pushImageDMA( area->x1
                  , area->y1
                  , area->x2 - area->x1 + 1
                  , area->y2 - area->y1 + 1
                  , ( lgfx::swap565_t* )&color_p->full );
  lv_disp_flush_ready(disp); 
}

@Emmanuele75
Copy link
Author

I did as you said, but unfortunately nothing changes!

@lovyan03
Copy link
Owner

@Emmanuele75
umm, ok... Please try using the develop branch version...

@Emmanuele75
Copy link
Author

ok, i will let you know soon

@Emmanuele75
Copy link
Author

Now everything works fine!!!
My final configuration:

Development branch version
 #define LV_COLOR_16_SWAP 1
void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p){
  tft.pushImageDMA( area->x1
                  , area->y1
                  , area->x2 - area->x1 + 1
                  , area->y2 - area->y1 + 1
                  , ( lgfx::swap565_t* )&color_p->full );
  lv_disp_flush_ready(disp); 
}

Thank you very much!!!

@Emmanuele75
Copy link
Author

I forgot... This is my display configuration:

#define LGFX_USE_V1
#include <LovyanGFX.hpp>
#include <lgfx/v1/platforms/esp32s3/Panel_RGB.hpp>
#include <lgfx/v1/platforms/esp32s3/Bus_RGB.hpp>

class LGFX : public lgfx::LGFX_Device{
  lgfx::Bus_RGB     _bus_instance;
  lgfx::Panel_RGB   _panel_instance;
  lgfx::Light_PWM   _light_instance;
  lgfx::Touch_XPT2046 _touch_instance;

public:LGFX(void){
  auto cfg    = _bus_instance.config();
  cfg.panel   = &_panel_instance;
  cfg.pin_d0  = GPIO_NUM_8;  // B0
  cfg.pin_d1  = GPIO_NUM_3;  // B1
  cfg.pin_d2  = GPIO_NUM_46; // B2
  cfg.pin_d3  = GPIO_NUM_9;  // B3
  cfg.pin_d4  = GPIO_NUM_1;  // B4
  cfg.pin_d5  = GPIO_NUM_5;  // G0
  cfg.pin_d6  = GPIO_NUM_6;  // G1
  cfg.pin_d7  = GPIO_NUM_7;  // G2
  cfg.pin_d8  = GPIO_NUM_15; // G3
  cfg.pin_d9  = GPIO_NUM_16; // G4
  cfg.pin_d10 = GPIO_NUM_4;  // G5
  cfg.pin_d11 = GPIO_NUM_45; // R0
  cfg.pin_d12 = GPIO_NUM_48; // R1
  cfg.pin_d13 = GPIO_NUM_47; // R2
  cfg.pin_d14 = GPIO_NUM_21; // R3
  cfg.pin_d15 = GPIO_NUM_14; // R4
  cfg.pin_henable       = GPIO_NUM_40;
  cfg.pin_vsync         = GPIO_NUM_41;
  cfg.pin_hsync         = GPIO_NUM_39;
  cfg.pin_pclk          = GPIO_NUM_42;
  cfg.freq_write        = 9000000;   //16000000
  cfg.hsync_polarity    = 0; //0
  cfg.hsync_front_porch = 8; //8
  cfg.hsync_pulse_width = 4; //4
  cfg.hsync_back_porch  = 43; //43
  cfg.vsync_polarity    = 0;  //0
  cfg.vsync_front_porch = 8; //8
  cfg.vsync_pulse_width = 4; //4
  cfg.vsync_back_porch  = 12; //12
  cfg.pclk_idle_high    = 1; //1
  _bus_instance.config(cfg);
  _panel_instance.setBus(&_bus_instance);
  
  { auto cfg = _panel_instance.config();
  cfg.memory_width  = 480;
  cfg.memory_height = 272;
  cfg.panel_width   = 480;
  cfg.panel_height  = 272;
  cfg.offset_x      = 0;
  cfg.offset_y      = 0;
  _panel_instance.config(cfg);
  }
  
  { auto cfg = _panel_instance.config_detail();
  cfg.use_psram = 1;
  _panel_instance.config_detail(cfg);
  }

  { auto cfg = _light_instance.config();
  cfg.pin_bl = GPIO_NUM_2;
  _light_instance.config(cfg);
  }
  _panel_instance.light(&_light_instance);

{ 
      auto cfg = _touch_instance.config();
      cfg.x_min      = 100;    
      cfg.x_max      = 4000;   
      cfg.y_min      = 100;     
      cfg.y_max      = 4000;    
      cfg.pin_int    = -1;    
      cfg.bus_shared = true;  
      cfg.offset_rotation = 0;// 0-7
      cfg.spi_host = 1; // 
      cfg.freq = 1000000;    
      cfg.pin_sclk = 12;     
      cfg.pin_mosi = 11;     
      cfg.pin_miso = 13;     
      cfg.pin_cs   = 38;     
      _touch_instance.config(cfg);
      _panel_instance.setTouch(&_touch_instance);  
    }
  setPanel(&_panel_instance); 
  }
};
static LGFX tft; 

@ruihe1117
Copy link

ruihe1117 commented Mar 26, 2023

@Emmanuele75
Hi, I am trying to drive the RGB565 screen with ESP32-S3, but I am not familiar with the GFX library and do not know how to use the LVGL example, can you share a copy of your just fixed lvgl example code? I would like to learn an example of how gfx uses lvgl.

my email rui_he1117📧163.com

thank you very much!

@Emmanuele75
Copy link
Author

@ruihe1117

#pragma GCC optimize ("Ofast")
#include <arduino.h>
#include <lvgl.h>
#define LGFX_USE_V1
#include <LovyanGFX.h>
#include "ui.h"

#include "lgfx_4827S043C.h"
//#include "lgfx_4827S043R.h"


/*Change to your screen resolution*/
static const uint32_t screenWidth  = 480;
static const uint32_t screenHeight = 272;
static lv_disp_draw_buf_t draw_buf;
static lv_color_t disp_draw_buf[screenWidth * 10];

void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p){
  tft.pushImageDMA( area->x1
                  , area->y1
                  , area->x2 - area->x1 + 1
                  , area->y2 - area->y1 + 1
                  , ( lgfx::swap565_t* )&color_p->full );
  lv_disp_flush_ready(disp); 
}

/*Read the touchpad*/
void my_touchpad_read(lv_indev_drv_t *indev_driver, lv_indev_data_t *data){
  int32_t x, y; 
  if (tft.getTouch(&x, &y)) {
      data->state = LV_INDEV_STATE_PR;
      data->point.x = x;
      data->point.y = y;
  }else{
    data->state = LV_INDEV_STATE_REL;
  }
}

void setup(){
  Serial.begin(115200);  
  tft.begin();        
  tft.setRotation(0);
  tft.setBrightness(255);  
  lv_init(); 

  lv_disp_draw_buf_init(&draw_buf, disp_draw_buf, NULL, screenWidth * 10);
  static lv_disp_drv_t disp_drv;

/* Initialize the display */
  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);

  ui_init(); 
}

void loop(){     
  lv_timer_handler();  
  delay(5); 
}

@tobozo
Copy link
Collaborator

tobozo commented Mar 26, 2023

@ruihe1117 I've edited the email address (changed @ to 📧) in your post to avoid drawing attention from spambots

@gamma2
Copy link

gamma2 commented Mar 26, 2023

i just bought the esp32-4827S043 board and i am trying to test your code can you share the ui.h and ui.c files?

Thanks

@Emmanuele75
Copy link
Author

download squareline studio and export the sample file to your project folder and you're done.

@ruihe1117
Copy link

@Emmanuele75 @lovyan03

First of all, I really feel your help;

The screen I am using is an 800x480RGB screen. With the help of the above, I can already display it normally and have enabled "dual buffering full pixel refresh" (when not enabled, the display is blocked). "But my screen is only half displayed, everything else is normal, and I tested it on two screens with completely different hardware designs, and the results were only half displayed.".

Have you ever encountered a situation where only half of the display is displayed? Or are there any possible problems?
IMG_20230327_164147_edit_408947206059994.jpg

VID_20230327_165501.mp4

@Emmanuele75
Copy link
Author

@ruihe1117
I'll do some tests with 800x480 displays and then get back to you

@Zer0-bit
Copy link

Zer0-bit commented Apr 1, 2023

I tested and everything renders fine on the 800x480 LCD variant but effects are very sluggish, feels like it's an issue only with full page rendering though as localised transitions like scrolling and swiping elements seem fine.
@lovyan03 maybe you have an idea of why is this happening ?

@Emmanuele75
Copy link
Author

@Zer0-bit
I too have experienced a lot of slowness with the 800x480 display, it seems that ESP32 is not up to par.

@Zer0-bit
Copy link

Zer0-bit commented Apr 1, 2023

@Emmanuele75 it's 100% not the mcu not being able to run smoother, the same LVGL code runs quite smooth and transitions look like transitions if using Arduino GFX.

@Emmanuele75
Copy link
Author

@Zer0-bit
could you post the configuration for Arduino_GFX?

@Zer0-bit
Copy link

Zer0-bit commented Apr 2, 2023

@Emmanuele75 - i mean i can, not sure if it's not against certain rules around here ?

@tobozo
Copy link
Collaborator

tobozo commented Apr 2, 2023

please share your working configurations, every GFX driver eventually benefits from the others, the more the merrier

@Zer0-bit
Copy link

Zer0-bit commented Apr 2, 2023

@tobozo sure no problems, i can add my project's working config later but just to mention the arduino gfx guys provide a working config by default for these displays on this link https://github.com/moononournation/Arduino_GFX/wiki/Dev-Device-Declaration
Look for the ESP32-4827S043 and ESP32-8048S070 displays in there.

@Zer0-bit
Copy link

Zer0-bit commented Apr 3, 2023

Okay so here's the behaviour using the standard widgets demo and LovyanGFX:

lgfx-lgvl-widgets-demo.mp4

LGFX_ESP32S3_RGB_ESP32-8048S043.h

#define LGFX_USE_V1
#include <LovyanGFX.hpp>

#include <lgfx/v1/platforms/esp32s3/Panel_RGB.hpp>
#include <lgfx/v1/platforms/esp32s3/Bus_RGB.hpp>

class LGFX : public lgfx::LGFX_Device{
  lgfx::Bus_RGB     _bus_instance;
  lgfx::Panel_RGB   _panel_instance;
  lgfx::Light_PWM   _light_instance;
  lgfx::Touch_GT911 _touch_instance;

public:LGFX(void){
  auto cfg              = _bus_instance.config();
  cfg.panel             = &_panel_instance;
  cfg.pin_d0            = 8;  // B0
  cfg.pin_d1            = 3;  // B1
  cfg.pin_d2            = 46; // B2
  cfg.pin_d3            = 9;  // B3
  cfg.pin_d4            = 1;  // B4
  cfg.pin_d5            = 5;  // G0
  cfg.pin_d6            = 6;  // G1
  cfg.pin_d7            = 7;  // G2
  cfg.pin_d8            = 15; // G3
  cfg.pin_d9            = 16; // G4
  cfg.pin_d10           = 4;  // G5
  cfg.pin_d11           = 45; // R0
  cfg.pin_d12           = 48; // R1
  cfg.pin_d13           = 47; // R2
  cfg.pin_d14           = 21; // R3
  cfg.pin_d15           = 14; // R4
  cfg.pin_henable       = 40;
  cfg.pin_vsync         = 41;
  cfg.pin_hsync         = 39;
  cfg.pin_pclk          = 42;
  cfg.freq_write        = 14000000;
  cfg.hsync_polarity    = 0;
  cfg.hsync_front_porch = 8;
  cfg.hsync_pulse_width = 4;
  cfg.hsync_back_porch  = 43;
  cfg.vsync_polarity    = 0;
  cfg.vsync_front_porch = 8;
  cfg.vsync_pulse_width = 4;
  cfg.vsync_back_porch  = 12;
  cfg.pclk_idle_high    = 1;
  _bus_instance.config(cfg);
  _panel_instance.setBus(&_bus_instance);

  { auto cfg = _panel_instance.config();
  cfg.memory_width      = 800;
  cfg.memory_height     = 480;
  cfg.panel_width       = 800;
  cfg.panel_height      = 480;
  cfg.offset_x          = 0;
  cfg.offset_y          = 0;
  _panel_instance.config(cfg);
  }

  { auto cfg = _panel_instance.config_detail();
  cfg.use_psram         = 1;
  _panel_instance.config_detail(cfg);
  }

  { auto cfg = _light_instance.config();
  cfg.pin_bl            = 2;
  cfg.freq              = 44100;
  cfg.pwm_channel       = 7;
  _light_instance.config(cfg);
  }
  _panel_instance.light(&_light_instance);

{
  auto cfg = _touch_instance.config();
  cfg.x_min = 25;
  cfg.x_max = 473;
  cfg.y_min = 14;
  cfg.y_max = 264;
  cfg.pin_int = -1;
  cfg.bus_shared = true;
  cfg.offset_rotation = 0;
  // I2C接続
  cfg.i2c_port = 1;
  cfg.pin_sda = 19;
  cfg.pin_scl = 20;
  cfg.pin_rst = 38;
  cfg.freq = 400000;
  cfg.i2c_addr = 0x5D;  // 0x5D , 0x14
  _touch_instance.config(cfg);
  _panel_instance.setTouch(&_touch_instance);
}
  setPanel(&_panel_instance); // 使用するパネルをセットします。
  }
};

lvgl_widgets.ino

#include "lvgl.h"
#include "demos/lv_demos.h"

#include "LGFX_ESP32S3_RGB_ESP32-8048S043.h"

// #pragma GCC optimize ("Ofast")
///////////////////// LCD INIT ////////////////////
static LGFX lcd;                 // LGFXのインスタンスを作成。

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


void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p){
  lcd.pushImageDMA( area->x1
                  , area->y1
                  , area->x2 - area->x1 + 1
                  , area->y2 - area->y1 + 1
                  , ( lgfx::rgb565_t* )&color_p->full );
  lv_disp_flush_ready(disp);
}

void my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data) {
    uint16_t touchX, touchY;
    bool touched;
    touched = lcd.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;
    }
}

/////////////// LCD INIT////////////////
void lcd_init(void) {
    lcd.begin();          /* TFT init */
    lcd.setRotation(0); /* Landscape orientation, flipped */
    lcd.setBrightness(128);

    lv_init();
    lv_disp_draw_buf_init( &draw_buf, buf, NULL, 800 * 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 = 800;
    disp_drv.ver_res = 480;
    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 );
}

void setup() {
  Serial.begin( 115200 );
  lcd_init();

  // Init LCD objects
  lv_demo_widgets();
}

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

And here's the same demo but running under Arduino GFX:

agfx-lgvl-widgets-demo.mp4
#pragma GCC optimize ("Ofast")
#include <lvgl.h>
#include <demos/lv_demos.h>
/*******************************************************************************
 ******************************************************************************/
#include <Wire.h>
#include <Arduino_GFX_Library.h>
#define TFT_BL 2

Arduino_ESP32RGBPanel *rgbpanel = new Arduino_ESP32RGBPanel(
  40 /* DE */, 41 /* VSYNC */, 39 /* HSYNC */, 42 /* PCLK */,
  45 /* R0 */, 48 /* R1 */, 47 /* R2 */, 21 /* R3 */, 14 /* R4 */,
  5 /* G0 */, 6 /* G1 */, 7 /* G2 */, 15 /* G3 */, 16 /* G4 */, 4 /* G5 */,
  8 /* B0 */, 3 /* B1 */, 46 /* B2 */, 9 /* B3 */, 1 /* B4 */,
  0 /* hsync_polarity */, 8 /* hsync_front_porch */, 4 /* hsync_pulse_width */, 43 /* hsync_back_porch */,
  0 /* vsync_polarity */, 8 /* vsync_front_porch */, 4 /* vsync_pulse_width */, 12 /* vsync_back_porch */,
  1 /* pclk_active_neg */, 16000000 /* prefer_speed */,
  0 /* de_idle_high */, 0 /* pclk_idle_high */
);

Arduino_RGB_Display *gfx = new Arduino_RGB_Display(
  800 /* width */, 480 /* height */, rgbpanel
);

#include "touch.h"
/* Change to your screen resolution */
static uint32_t screenWidth;
static uint32_t screenHeight;
static lv_disp_draw_buf_t draw_buf;
static lv_color_t *disp_draw_buf;
static lv_disp_drv_t disp_drv;

/* Display flushing */
void my_disp_flush(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);

#if (LV_COLOR_16_SWAP != 0)
  gfx->draw16bitBeRGBBitmap(area->x1, area->y1, (uint16_t *)&color_p->full, w, h);
#else
  gfx->draw16bitRGBBitmap(area->x1, area->y1, (uint16_t *)&color_p->full, w, h);
#endif

  lv_disp_flush_ready(disp);
}

void my_touchpad_read(lv_indev_drv_t *indev_driver, lv_indev_data_t *data)
{
  if (touch_has_signal())
  {
    if (touch_touched())
    {
      data->state = LV_INDEV_STATE_PR;

      /*Set the coordinates*/
      data->point.x = touch_last_x;
      data->point.y = touch_last_y;
    }
    else if (touch_released())
    {
      data->state = LV_INDEV_STATE_REL;
    }
  }
  else
  {
    data->state = LV_INDEV_STATE_REL;
  }
}

void setup()
{
  Serial.begin(115200);
  // while (!Serial);
  Serial.println("LVGL Widgets Demo");

  // Init touch device
  

  // Init Display
  gfx->begin();
#ifdef TFT_BL
  pinMode(TFT_BL, OUTPUT);
  digitalWrite(TFT_BL, HIGH);
#endif
  gfx->fillScreen(RED);
  delay(500);
  gfx->fillScreen(GREEN);
  delay(500);
  gfx->fillScreen(BLUE);
  delay(500);
  gfx->fillScreen(BLACK);
  delay(500);
  lv_init();
  delay(10);
  touch_init();
  screenWidth = gfx->width();
  screenHeight = gfx->height();
#ifdef ESP32
  disp_draw_buf = (lv_color_t *)heap_caps_malloc(sizeof(lv_color_t) * screenWidth * screenHeight/4 , MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
#else
  disp_draw_buf = (lv_color_t *)malloc(sizeof(lv_color_t) * screenWidth * screenHeight/4);
#endif
  if (!disp_draw_buf)
  {
    Serial.println("LVGL disp_draw_buf allocate failed!");
  }
  else
  {
    lv_disp_draw_buf_init(&draw_buf, disp_draw_buf, NULL, screenWidth * screenHeight/4);

    /* Initialize the display */
    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);

    Serial.println("Setup done");
  }
  lv_demo_widgets();
}

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

@lovyan03 @tobozo above you can see the configs and the result in those videos.

Alternatively i created a platformio ready repo that can be pulled and built.
https://github.com/Zer0-bit/lvgl-widgets/tree/master
P.S. Might require to copy the demos folder under this path .pio/libdeps/s3-lcd-lgfx-high-dpi/lvgl/ to the .pio/libdeps/s3-lcd-lgfx-high-dpi/lvgl/src

@gamma2
Copy link

gamma2 commented Apr 4, 2023

God morning, i need help and i apologize if i'm not expert in this thing, but when i try to compile emmanuele75's example i get the following errors and the compilation aborts:


PLATFORM: Espressif 32 (6.1.0) > Espressif ESP32-S3-DevKitC-1-N16R8V (16 MB QD, 8MB PSRAM)
HARDWARE: ESP32S3 240MHz, 320KB RAM, 16MB Flash
DEBUG: Current (esp-builtin) On-board (esp-builtin) External (cmsis-dap, esp-bridge, esp-prog, iot-bus-jtag, jlink, minimodule, olimex-arm-usb-ocd, olimex-arm-usb-ocd-h, olimex-arm-usb-tiny-h, olimex-jtag-tiny, tumpa)
PACKAGES:

  • framework-arduinoespressif32 @ 3.20007.0 (2.0.7)
  • tool-esptoolpy @ 1.40500.0 (4.5.0)
  • toolchain-riscv32-esp @ 8.4.0+2021r2-patch5
  • toolchain-xtensa-esp32s3 @ 8.4.0+2021r2-patch5
    LDF: Library Dependency Finder -> https://bit.ly/configure-pio-ldf
    LDF Modes: Finder ~ chain, Compatibility ~ soft
    Found 38 compatible libraries
    Scanning dependencies...
    ................................................................................................... other lines
    src/ui/ui.c: In function 'Particle1_Animation':
    src/ui/ui.c:189:5: warning: implicit declaration of function 'lv_anim_set_deleted_cb'; did you mean 'lv_anim_set_exec_cb'? [-Wimplicit-function-declaration]
    lv_anim_set_deleted_cb(&PropertyAnimation_0, _ui_anim_callback_free_user_data);
    ^~~~~~~~~~~~~~~~~~~~~~
    lv_anim_set_exec_cb

My platformio.ini is :

[env:esp32-s3-devkitc-1-n16r8v]
platform = espressif32
board = esp32-s3-devkitc-1-n16r8v
framework = arduino
build_type = debug
build_flags = -D CONFIG_ESP32_SPIRAM_SUPPORT=y
-D CORE_DEBUG_LEVEL=5
monitor_speed = 115200
monitor_filters = log2file, esp32_exception_decoder, default
monitor_raw = yes

ENVIRONMENT

MCU or Board name: ESP32-4827S043) [ESP32s3 + 4.3" RGB display]
Panel Driver IC: ILI6485
Bus type: RGB
LovyanGFX version: 1.1.5
lvgl version: 8.0.3-dev
FrameWork version: ArduinoESP32 v2.0.7
Build Environment : Platformio (framework = Arduino)
Operating System: Windows 10

Tanks in advance for the help

@github-actions
Copy link

github-actions bot commented May 6, 2023

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@github-actions github-actions bot added the stale Inactive issues label May 6, 2023
@github-actions
Copy link

This issue has been automatically closed because it has not had recent activity. Thank you for your contributions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
stale Inactive issues
Projects
None yet
Development

No branches or pull requests

6 participants