Description
Hi, I am creating a small test programm on an Esp32s2 in combination with a small SSD13306 (128x64 monchrome) display.
Essentially, the display shows a bar and 6 numbers / labels. However, when I run a loop for increasing the bar it is very slow. In a sense that instead of going from 1 to 100 it takes a minute or more. The display code is generated by eez studio.
What MCU/Processor/Board and compiler are you using?
esp32s2 + ssd13306
What LVGL version are you using?
9.2.0
Code to reproduce
main.c
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_timer.h"
#include "esp_lcd_panel_io.h"
#include "esp_lcd_panel_ops.h"
#include "driver/i2c.h"
#include "esp_err.h"
#include "esp_log.h"
#include "lvgl.h"
#include "esp_lvgl_port.h"
#include "esp_lcd_panel_vendor.h"
#include "ui/ui.h"
static const char *TAG = "example";
#define I2C_HOST 0
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////// Please update the following configuration according to your LCD spec //////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#define LCD_PIXEL_CLOCK_HZ (400 * 1000)
// #define EXAMPLE_PIN_NUM_RST -1
// #define EXAMPLE_I2C_HW_ADDR 0x3C
// The pixel number in horizontal and vertical
#if CONFIG_EXAMPLE_LCD_CONTROLLER_SSD1306
#define EXAMPLE_LCD_H_RES 128
#define EXAMPLE_LCD_V_RES CONFIG_EXAMPLE_SSD1306_HEIGHT
#endif
// Bit number used to represent command and parameter
#define LCD_CMD_BITS 8
#define LCD_PARAM_BITS 8
void task(void *pvParameters)
{
/* Create some load in an infinite loop */
for(int i = 0; i <= 100; i++) {
if (lvgl_port_lock(0)) {
lv_bar_set_value(objects.bar, i, false);
// Release the mutex
lvgl_port_unlock();
}
printf("Task is running :)\n");
/* Delay the task for 500 milliseconds */
vTaskDelay(pdMS_TO_TICKS(50));
}
printf("Done");
vTaskDelete(NULL);
}
void app_main(void)
{
ESP_LOGI(TAG, "Initialize I2C bus");
i2c_config_t i2c_conf = {
.mode = I2C_MODE_MASTER,
.sda_io_num = CONFIG_SCREEN_I2C_MASTER_SDA,
.scl_io_num = CONFIG_SCREEN_I2C_MASTER_SCL,
.sda_pullup_en = GPIO_PULLUP_DISABLE,
.scl_pullup_en = GPIO_PULLUP_DISABLE,
.master.clk_speed = LCD_PIXEL_CLOCK_HZ,
};
ESP_ERROR_CHECK(i2c_param_config(I2C_HOST, &i2c_conf));
ESP_ERROR_CHECK(i2c_driver_install(I2C_HOST, I2C_MODE_MASTER, 0, 0, 0));
ESP_LOGI(TAG, "Install panel IO");
esp_lcd_panel_io_handle_t io_handle = NULL;
esp_lcd_panel_io_i2c_config_t io_config = {
.dev_addr = CONFIG_SCREEN_I2C_HW_ADDR,
.control_phase_bytes = 1, // According to SSD1306 datasheet
.lcd_cmd_bits = LCD_CMD_BITS, // According to SSD1306 datasheet
.lcd_param_bits = LCD_CMD_BITS, // According to SSD1306 datasheet
.dc_bit_offset = 6, // According to SSD1306 datasheet
};
ESP_ERROR_CHECK(esp_lcd_new_panel_io_i2c(I2C_HOST, &io_config, &io_handle));
ESP_LOGI(TAG, "Install SSD1306 panel driver");
esp_lcd_panel_handle_t panel_handle = NULL;
esp_lcd_panel_dev_config_t panel_config = {
.bits_per_pixel = 1,
.reset_gpio_num = CONFIG_SCREEN_PIN_NUM_RST,
#if (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5,0,0))
.color_space = ESP_LCD_COLOR_SPACE_MONOCHROME,
#endif
};
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5,3,0))
esp_lcd_panel_ssd1306_config_t ssd1306_config = {
.height = EXAMPLE_LCD_V_RES,
};
panel_config.vendor_config = &ssd1306_config;
#endif
ESP_ERROR_CHECK(esp_lcd_new_panel_ssd1306(io_handle, &panel_config, &panel_handle));
ESP_ERROR_CHECK(esp_lcd_panel_reset(panel_handle));
ESP_ERROR_CHECK(esp_lcd_panel_init(panel_handle));
ESP_ERROR_CHECK(esp_lcd_panel_disp_on_off(panel_handle, true));
ESP_LOGI(TAG, "Initialize LVGL");
const lvgl_port_cfg_t lvgl_cfg = ESP_LVGL_PORT_INIT_CONFIG();
lvgl_port_init(&lvgl_cfg);
const lvgl_port_display_cfg_t disp_cfg = {
.io_handle = io_handle,
.panel_handle = panel_handle,
.buffer_size = EXAMPLE_LCD_H_RES * EXAMPLE_LCD_V_RES,
.double_buffer = true,
.hres = EXAMPLE_LCD_H_RES,
.vres = EXAMPLE_LCD_V_RES,
.monochrome = true,
#if LVGL_VERSION_MAJOR >= 9
.color_format = LV_COLOR_FORMAT_RGB565,
#endif
.rotation = {
.swap_xy = false,
.mirror_x = false,
.mirror_y = false,
},
.flags = {
#if LVGL_VERSION_MAJOR >= 9
.swap_bytes = false,
#endif
.sw_rotate = false,
}
};
lv_disp_t *disp = lvgl_port_add_disp(&disp_cfg);
ESP_LOGI(TAG, "Display LVGL Scroll Text");
// Lock the mutex due to the LVGL APIs are not thread-safe
if (lvgl_port_lock(0)) {
lv_disp_set_rotation(disp, LV_DISPLAY_ROTATION_180);
ui_init();
// Release the mutex
lvgl_port_unlock();
}
/* Create task */
if (xTaskCreate(&task, "Task", 1024, NULL, 1, NULL) != pdPASS) {
printf("Error creating another task\n");
/* Error handling */
}
}
screens.c
#include <string.h>
#include "screens.h"
#include "images.h"
#include "fonts.h"
#include "actions.h"
#include "vars.h"
#include "styles.h"
#include "ui.h"
#include <string.h>
objects_t objects;
lv_obj_t *tick_value_change_obj;
void create_screen_main() {
lv_obj_t *obj = lv_obj_create(0);
objects.main = obj;
lv_obj_set_pos(obj, 0, 0);
lv_obj_set_size(obj, 128, 64);
{
lv_obj_t *parent_obj = obj;
{
lv_obj_t *obj = lv_obj_create(parent_obj);
lv_obj_set_pos(obj, 0, 0);
lv_obj_set_size(obj, 128, 64);
{
lv_obj_t *parent_obj = obj;
{
// pnlResults
lv_obj_t *obj = lv_obj_create(parent_obj);
objects.pnl_results = obj;
lv_obj_set_pos(obj, -15, 0);
lv_obj_set_size(obj, 128, 50);
{
lv_obj_t *parent_obj = obj;
{
// lblAohm
lv_obj_t *obj = lv_label_create(parent_obj);
objects.lbl_aohm = obj;
lv_obj_set_pos(obj, 60, -5);
lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
lv_label_set_text(obj, "4");
lv_obj_set_style_text_font(obj, &lv_font_montserrat_12, LV_PART_MAIN | LV_STATE_DEFAULT);
}
{
// lblBohm
lv_obj_t *obj = lv_label_create(parent_obj);
objects.lbl_bohm = obj;
lv_obj_set_pos(obj, 60, 5);
lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
lv_label_set_text(obj, "5");
lv_obj_set_style_text_font(obj, &lv_font_montserrat_12, LV_PART_MAIN | LV_STATE_DEFAULT);
}
{
// lblCohm
lv_obj_t *obj = lv_label_create(parent_obj);
objects.lbl_cohm = obj;
lv_obj_set_pos(obj, 60, 16);
lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
lv_label_set_text(obj, "6");
lv_obj_set_style_text_font(obj, &lv_font_montserrat_12, LV_PART_MAIN | LV_STATE_DEFAULT);
}
{
// lblApct
lv_obj_t *obj = lv_label_create(parent_obj);
objects.lbl_apct = obj;
lv_obj_set_pos(obj, 9, -5);
lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
lv_label_set_text(obj, "1");
lv_obj_set_style_max_height(obj, 14, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_text_font(obj, &lv_font_montserrat_12, LV_PART_MAIN | LV_STATE_DEFAULT);
}
{
// lblBpct
lv_obj_t *obj = lv_label_create(parent_obj);
objects.lbl_bpct = obj;
lv_obj_set_pos(obj, 9, 5);
lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
lv_label_set_text(obj, "2");
lv_obj_set_style_max_height(obj, 14, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_text_font(obj, &lv_font_montserrat_12, LV_PART_MAIN | LV_STATE_DEFAULT);
}
{
// lblCpct
lv_obj_t *obj = lv_label_create(parent_obj);
objects.lbl_cpct = obj;
lv_obj_set_pos(obj, 9, 16);
lv_obj_set_size(obj, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
lv_label_set_text(obj, "3");
lv_obj_set_style_max_height(obj, 14, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_text_font(obj, &lv_font_montserrat_12, LV_PART_MAIN | LV_STATE_DEFAULT);
}
}
}
{
// bar
lv_obj_t *obj = lv_bar_create(parent_obj);
objects.bar = obj;
lv_obj_set_pos(obj, -15, -4);
lv_obj_set_size(obj, 128, 10);
lv_bar_set_value(obj, 25, LV_ANIM_OFF);
lv_obj_clear_flag(obj, LV_OBJ_FLAG_CLICKABLE|LV_OBJ_FLAG_CLICK_FOCUSABLE);
lv_obj_set_style_border_color(obj, lv_color_hex(0xffffffff), LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_bg_color(obj, lv_color_hex(0xff000000), LV_PART_INDICATOR | LV_STATE_DEFAULT);
}
}
}
}
}
void tick_screen_main() {
}
void create_screens() {
lv_disp_t *dispp = lv_disp_get_default();
lv_theme_t *theme = lv_theme_default_init(dispp, lv_palette_main(LV_PALETTE_BLUE), lv_palette_main(LV_PALETTE_RED), false, LV_FONT_DEFAULT);
lv_disp_set_theme(dispp, theme);
create_screen_main();
}
typedef void (*tick_screen_func_t)();
tick_screen_func_t tick_screen_funcs[] = {
tick_screen_main,
};
void tick_screen(int screen_index) {
tick_screen_funcs[screen_index]();
}