TFT Display Help with LVGL

Hi all,
I have been able to program my ST7789 display (Cheap Yellow Display) with some code. However the look of it is appalling. The display is portrait, and the text is only slightly readable

I have programmed this with ESP-IDF. I’m finding it really hard to include this within IDF, im finding that the support is not very supporting lol. If anyone could help would be much appreciated.
It is supposed to say Hello, LVGL!

#include "lvgl.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_lcd_panel_io.h"
#include "esp_lcd_panel_ops.h"
#include "esp_lcd_panel_vendor.h"
#include "driver/spi_master.h"
#include "driver/gpio.h"

#define PIN_NUM_MOSI 13
#define PIN_NUM_CLK  14
#define PIN_NUM_CS   15
#define PIN_NUM_DC   2
#define PIN_NUM_RST  -1
#define PIN_NUM_BL   21 // Backlight control pin

esp_lcd_panel_handle_t panel_handle = NULL; // Global panel handle

void lvgl_flush_cb(lv_display_t *disp, const lv_area_t *area, uint8_t *px_map) {
    esp_lcd_panel_draw_bitmap(panel_handle, area->x1, area->y1, area->x2 + 1, area->y2 + 1, px_map);
    lv_disp_flush_ready(disp);
}

void lvgl_init_display(void) {
    static uint8_t lvBuffer[240 * 10]; // Buffer for 10 rows

    // Initialize the SPI bus
    spi_bus_config_t buscfg = {
        .sclk_io_num = PIN_NUM_CLK,
        .mosi_io_num = PIN_NUM_MOSI,
        .miso_io_num = -1,
        .quadwp_io_num = -1,
        .quadhd_io_num = -1,
        .max_transfer_sz = 240 * 320 * 2 + 8
    };
    spi_bus_initialize(SPI2_HOST, &buscfg, SPI_DMA_CH_AUTO);

    // Initialize panel IO
    esp_lcd_panel_io_handle_t io_handle = NULL;
    esp_lcd_panel_io_spi_config_t io_config = {
        .dc_gpio_num = PIN_NUM_DC,
        .cs_gpio_num = PIN_NUM_CS,
        .pclk_hz = 40 * 1000 * 1000, // Use 40 MHz for stability
        .spi_mode = 0,
        .trans_queue_depth = 10,
        .lcd_cmd_bits = 8,
        .lcd_param_bits = 8
    };
    esp_lcd_new_panel_io_spi(SPI2_HOST, &io_config, &io_handle);

    // Initialize the display panel
    esp_lcd_panel_dev_config_t panel_config = {
        .reset_gpio_num = PIN_NUM_RST,
        .color_space = ESP_LCD_COLOR_SPACE_BGR, // Use BGR color space
        .bits_per_pixel = 16
    };
    esp_lcd_new_panel_st7789(io_handle, &panel_config, &panel_handle);

    // Reset and initialize the panel
    esp_lcd_panel_reset(panel_handle);
    esp_lcd_panel_init(panel_handle);
    esp_lcd_panel_disp_on_off(panel_handle, true);
    esp_lcd_panel_invert_color(panel_handle, false); // Disable color inversion

    // Initialize backlight
    gpio_reset_pin(PIN_NUM_BL);
    gpio_set_direction(PIN_NUM_BL, GPIO_MODE_OUTPUT);
    gpio_set_level(PIN_NUM_BL, 1); // Turn on backlight

    // Create LVGL display
    lv_display_t *lvDisplay = lv_display_create(240, 320);
    lv_display_set_color_format(lvDisplay, LV_COLOR_FORMAT_RGB565); // Use RGB565
    lv_display_set_flush_cb(lvDisplay, lvgl_flush_cb);
    lv_display_set_buffers(lvDisplay, lvBuffer, NULL, 240 * 10, LV_DISPLAY_RENDER_MODE_PARTIAL);
}

void app_main(void) {
    // Initialize LVGL
    lv_init();

    // Initialize the display
    lvgl_init_display();

    // Create a simple label
    lv_obj_t *label = lv_label_create(lv_scr_act());
    lv_label_set_text(label, "Hello, LVGL!");
    lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);

    // Main loop
    while (1) {
        lv_timer_handler(); // Handle LVGL tasks
        vTaskDelay(pdMS_TO_TICKS(10));
    }
}

I can’t answer the rest of your question, but I’m pretty sure the Cheap Yellow Display requires the ILI9341 driver not the ST7789.

The first problem is “Cheap Yellow Display”… it’s a cheap display and as such I would not expect it to have a high quality image that is displayed.

The display is displaying so any issues so I would guess that you may need to make changes to the config parameters that are sent to the display. Drivers that are typically bundled with another library or program is going to have config settings that will get the thing running. The config parameters that are sent are not going to be dialed in specifically for the display that is attached to the display IC. So you may need to make adjustments to those parameters to get it looking optimal. Look at the code for the driver you are using and you will be able to locate the config parameters. grab a copy of the datasheet for the display IC and do some reading as to what the different parameters do and make adjustments to ones that may provide a better image for the display that is attached to the IC.

There is a writeup on how to get that display IC working using the ESP-IDF located here. Near the end of that topic is where you will find code on how to do it. You can also ask the OP for a copy of the code he is using that is known to be working.

When output is muffled, probably a color-scheme or resolution thing. I noted ESP_LCD_COLOR_SPACE_BGR i one place, and LV_COLOR_FORMAT_RGB565 in another. Are you sure, that is correct? Blue-Green-Red order in one place, and Red-Green-Blue the other. I dont know the display, but it seems wrong.

The BGR is simply the byte order the color is transmitted in. the RGB565 is the color format/colorspace. That denotes 16 bit color. It’s a bit easier to understand if I say it like this…

RGB888 is 24 bit color, one byte for red, another for green and another for blue. the BGR instead of transmitting the colors as R…G…B… it does B…G…R… You have to keep in mind that the driver in the ESP-IDF is simply a driver and not what is rendering the data to the frame buffer. so all it needs to be told is what order to send the data in.

That being said depending on the display that is attached to the IC is going to dictate the order as well. What I tell people is if the colors are wrong with RGB then try BGR and if they are still wrong which can happen if you are using RGB565 then set it to RGB and you will need to call a function in LVGL to swap the bytes around. When using SPI interface with RGB565 end up having the data sent incorrectly, it’s something to do with the SPI that causes an issue. There is a function in LVGL that corrects this issue. I am pretty sure the function is being used in a code example I wrote in the topic I linked to in my last post.

I dont see a solution

That screen uses the ILI934 driver, so you must use this function esp_lcd_new_panel_ili9341() and also change the command LV_USE_ILI9341 in the lv_conf.h file