LVGL
Dicas sobre o LVGL.
Dicas gerais
Dicas gerais sobre o lvgl.
float
Para poder usar o e exibir strings com float
(exemplo: lv_label_set_text_fmt(dial, "%f", freq);
) você precisa editar o arquivo de configuração lv_conf.h
do lvgl:
-# define LV_SPRINTF_USE_FLOAT 0
+# define LV_SPRINTF_USE_FLOAT 1
Orientação do LCD (landscape/ portrait)
Para alteramos a orientação do LCD de horizontal para vertical será necessário fazermos as seguintes mudanças no código do main.c
:
/*************************************************/
/* LCD / LVGL */
/*************************************************/
- #define LV_HOR_RES_MAX (320)
- #define LV_VER_RES_MAX (240)
+ #define LV_HOR_RES_MAX (240)
+ #define LV_VER_RES_MAX (320)
void my_input_read(lv_indev_drv_t * drv, lv_indev_data_t*data) {
...
...
- data->point.x = px;
- data->point.y = py;
+ data->point.x = py;
+ data->point.y = 320 - px;
}
int main(void) {
....
....
/* LCd, touch and lvgl init*/
configure_lcd();
+ ili9341_set_orientation(ILI9341_FLIP_Y | ILI9341_SWITCH_XY);
...
}
Tip
Com isso o LCD passa a ter as dimensões 240x320
e para o LVGL não existe diferença nenhuma.
Desativando scroll
Se por algum motivo na sua tela estiver aparecendo uma barra de scroll e você não quer isso, tente o seguinte comando:
lv_obj_clear_flag(lv_scr_act(), LV_OBJ_FLAG_SCROLLABLE);
A ideia do comando
Mudando a cor do fundo
Para mudarmos a cor do background basta alterarmos a cor do background da tela principal:
// configura um fundo vermelho.
lv_obj_t * screen = lv_scr_act();
lv_obj_set_style_bg_color(screen, lv_palette_main(LV_PALETTE_RED), LV_PART_MAIN );
Multiplas telas
No LVGL podemos criar multiplas telas e associar ao mesmo display, as telas podem ser exibidas conforme necessário. Os widgets são associados a uma tela, então quando a tela em questão for exibida apenas os widgets associados a ela serão ativados.
// declarar a tela como global e estática
static lv_obj_t * scr1; // screen 1
static lv_obj_t * scr2; // screen 2
static void task_lcd(void *pvParameters) {
// Criando duas telas
scr1 = lv_obj_create(NULL);
scr2 = lv_obj_create(NULL);
// ....
}
Para dizer em qual tela os widgets serão associados, basta substituir o lv_scr_act()
usado na criação dos widgets pela tela em questão:
- lv_obj_t * btn1 = lv_btn_create(lv_scr_act());
+ lv_obj_t * btn1 = lv_btn_create(scr1); // botao criado na primeira tela
Para exibir uma das telas use a função lv_scr_load(lv_obj_t * scr)
como demonstrado a seguir:
static void task_update(void *pvParameters) {
for (;;) {
lv_scr_load(scr1); // exibe tela 1
vTaskDelay(500);
lv_scr_load(scr2); // exibe tela 2
vTaskDelay(500);
}
}
Tip
Você pode modificar as funções que criam os widgets na tela para receber como parametro o screen associado a eles:
- void lv_ex_btn_1(void) {
+ void create_scr(lv_obj_t * screen) {
lv_obj_t * label;
- lv_obj_t * btn1 = lv_btn_create(lv_scr_act());
+ lv_obj_t * btn1 = lv_btn_create(screen);
lv_obj_add_event_cb(btn1, event_handler, LV_EVENT_ALL, NULL);
lv_obj_align(btn1, LV_ALIGN_CENTER, 0, -40);
label = lv_label_create(btn1);
lv_label_set_text(label, "Corsi");
lv_obj_center(label);
- lv_obj_t * btn2 = lv_btn_create(lv_scr_act());
+ lv_obj_t * btn2 = lv_btn_create(screen);
lv_obj_add_event_cb(btn2, event_handler, LV_EVENT_ALL, NULL);
lv_obj_align(btn2, LV_ALIGN_CENTER, 0, 40);
lv_obj_add_flag(btn2, LV_OBJ_FLAG_CHECKABLE);
lv_obj_set_height(btn2, LV_SIZE_CONTENT);
label = lv_label_create(btn2);
lv_label_set_text(label, "Toggle");
lv_obj_center(label);
}
static void task_lcd(void *pvParameters) {
int px, py;
+ scr1 = lv_obj_create(NULL);
- lv_ex_btn_1();
+ create_scr(scr1);
+ lv_scr_load(scr1);
...
}
Tip
Você pode fazer a transição entre telas dado um evento de um botão!
Tip
Uma alternativa para mudar de tela utilizando efeito de scroll tente usar o widget Tile view, eu testei o exemplo do site aqui e funciona bem:
https://docs.lvgl.io/master/widgets/extra/tileview.html#tileview-with-content
Exibindo uma imagem
Warning
Esse procedimento não funciona com imagens no formato PNG sem fundo, a imagem precisa ter fundo, mesmo que branco.
Exibindo uma imagem estática no LCD, sem interação.
Tip
Se quiser usar uma imagem como botão utilize o widget Image button
:
Usar o conversor online disponível em https://lvgl.io/tools/imageconverter e seguir os passos:
- No site configurar:
File names
: Nome que quer dar para imagem, exemplo:img1
True Color
: OnOutput Format
: C Array
Clicar em Convert
e salvar o arquivo no computador (fora da pasta do projeto);
-
Mudar a extensão do arquivo baixo de
.c
para.h
-
Abrir o arquivo e editar a primeira linha:
- #include "lvgl/lvgl.h"
+ #include "lvgl.h"
-
Adicionar o arquivo da imagem no projeto do MicrochipStudio (pode arrastar)
-
No
main.c
incluir o.h
da imagem.
#include "img1.h"
- Agora basta executar as linhas de código a seguir para exibir a imagem:
lv_obj_t * img = lv_img_create(lv_scr_act());
lv_img_set_src(img, &img1);
lv_obj_align(img, LV_ALIGN_CENTER, 0, 0);
Info
- Para testar, incluir as linhas na
task_lcd
- No exemplo o nome da imagem utilizada no site foi
img1
- Alinhamos a imagem no centro da tela
Imagem
Se quiser usar um botão como imagem você pode usar o exemplo a seguir:
void lv_img_button(void) {
LV_IMG_DECLARE(imgBtnHome);
static lv_style_t style_def;
lv_style_init(&style_def); /*Darken the button when pressed and make it wider*/
static lv_style_t style_pr;
lv_style_init(&style_pr);
lv_style_set_img_recolor_opa(&style_pr, LV_OPA_30);
lv_style_set_img_recolor(&style_pr, lv_color_black());
lv_obj_t * btnPausePlay = lv_imgbtn_create(lv_scr_act());
lv_imgbtn_set_src(btnPausePlay, LV_IMGBTN_STATE_RELEASED, NULL, NULL, &imgBtnHome);
lv_obj_add_style(btnPausePlay, &style_def, 0);
lv_obj_add_style(btnPausePlay, &style_pr, LV_STATE_PRESSED);
lv_obj_align(btnPausePlay, LV_ALIGN_CENTER, 0, 0);
}
O imgBtnHome
eu gerei a partir da imagem a seguir: