No post anterior, demos nosso primeiro grande passo ao escrever “Hello World!” diretamente na tela da WT32-SC01 Plus usando a biblioteca LovyanGFX
. Isso provou que nosso hardware e a comunicação básica estão funcionando. Agora, vamos elevar o nível e começar a construir interfaces gráficas de verdade.
Neste tutorial, vamos introduzir duas ferramentas poderosas que transformarão a maneira como criamos projetos visuais: a biblioteca LVGL e a ferramenta de design SquareLine Studio. Nosso objetivo será recriar o “Hello World!”, mas desta vez, a interface será desenhada em um software visual e depois integrada ao nosso código Arduino.
As Ferramentas do Ofício: LVGL e SquareLine Studio
- LVGL (Light and Versatile Graphics Library): É uma biblioteca de código aberto extremamente popular para a criação de interfaces gráficas em sistemas embarcados. Ela oferece um conjunto rico de “widgets” (botões, sliders, gráficos, etc.) e gerencia todo o trabalho pesado de renderização e eventos.
- SquareLine Studio: É um software de design visual que permite arrastar e soltar elementos para criar interfaces complexas. Embora seja uma ferramenta comercial, ela oferece uma licença gratuita para uso pessoal e de hobby com algumas limitações (como o número de telas e widgets), que é perfeita para os nossos projetos. Ao final, ele exporta um projeto C completo que podemos integrar diretamente ao nosso código.
Passo 1: Preparando o Ambiente para LVGL
Além da LovyanGFX
e do pacote de placas ESP32 que já instalamos, agora precisamos adicionar a biblioteca LVGL.
- No Arduino IDE, vá em Ferramentas > Gerenciar Bibliotecas….
- Pesquise por
lvgl
e instale a versão 8.3.11. É importante usar esta versão para garantir a compatibilidade com os arquivos que o SquareLine Studio exporta. - Crie o arquivo
lv_conf.h
: Este é um passo crucial. a. Encontre o arquivolv_conf_template.h
na pasta da biblioteca LVGL. b. Copie-o para a sua pasta raizlibraries
(ex:Documentos/Arduino/libraries
). c. Renomeie a cópia paralv_conf.h
. d. Abra o arquivo e garanta que a linha#define LV_COLOR_DEPTH
esteja definida como16
.
Passo 2: Criando a Interface no SquareLine Studio
- Abra o SquareLine Studio e clique em “Create” para um novo projeto.
- Na tela de seleção de templates, clique na aba “Arduino”.
- Selecione o template “Arduino with TFT_eSPI”. É muito importante escolher este, pois ele gera a estrutura de arquivos correta para a IDE do Arduino, mesmo que estejamos usando a
LovyanGFX
no nosso código final. - Na aba “Project Settings”, configure a resolução da tela para 480x320 e clique em “Create”.
- Arraste um widget “Label” para a tela.
- No painel “Inspector” à direita, altere o texto do label para “Hello World!” e ajuste a fonte e o alinhamento como desejar.
- Antes de exportar, vá ao menu File > Project Settings. Na janela que abrir, na seção “FILE EXPORT”, configure os campos “Project Export Root” e “UI Files Export Path” para uma pasta de sua escolha (por exemplo, você pode criar uma pasta “exports” dentro do seu projeto do SquareLine). Isso evita erros durante a exportação.
- Vá em Export > Export UI Files para gerar os arquivos do projeto.
Passo 3: O Código de Integração
Importante:
- Coloque todos os arquivos exportados pelo SquareLine Studio (que estarão na pasta que você configurou no item 7 do Passo 2) na mesma pasta do seu sketch
.ino
. - No arquivo
ui.c
que o SquareLine gerou, encontre o blocoTEST LVGL SETTINGS
e comente a verificação deLV_COLOR_DEPTH
, deixando-o assim:///////////////////// TEST LVGL SETTINGS //////////////////// // #if LV_COLOR_DEPTH != 32 // #error "LV_COLOR_DEPTH should be 32bit to match SquareLine Studio's settings" // #endif #if LV_COLOR_16_SWAP !=0 #error "LV_COLOR_16_SWAP should be 0 to match SquareLine Studio's settings" #endif
Agora, vamos ao código que une tudo. Ele usa a mesma base da LovyanGFX
do exemplo anterior, mas adiciona toda a inicialização e o loop necessários para que o LVGL funcione.
/*
* EXEMPLO 2: HELLO WORLD COM SQUARELINE STUDIO E LOVYANGFX
* * Este sketch demonstra como integrar uma interface gráfica simples,
* criada no SquareLine Studio, com a biblioteca LovyanGFX.
*/
#define LGFX_USE_V1 // Define que estamos usando a Versão 1 da LovyanGFX
#include <LovyanGFX.hpp>
#include <lvgl.h>
#include "ui.h" // O header principal da sua interface gráfica gerada pelo SquareLine
// ======================================================================================
// === 1. CONFIGURAÇÃO DE HARDWARE (LOVYANGFX) ==========================================
// ======================================================================================
// Esta classe descreve o hardware da tela para a biblioteca LovyanGFX.
class LGFX : public lgfx::LGFX_Device
{
lgfx::Panel_ST7796 _panel_instance;
lgfx::Bus_Parallel8 _bus_instance;
lgfx::Light_PWM _light_instance;
public:
LGFX(void)
{
{
auto cfg = _bus_instance.config();
cfg.port = 0; cfg.freq_write = 20000000;
cfg.pin_wr = 47; cfg.pin_rd = -1; cfg.pin_rs = 0;
cfg.pin_d0 = 9; cfg.pin_d1 = 46; cfg.pin_d2 = 3; cfg.pin_d3 = 8;
cfg.pin_d4 = 18; cfg.pin_d5 = 17; cfg.pin_d6 = 16; cfg.pin_d7 = 15;
_bus_instance.config(cfg);
_panel_instance.setBus(&_bus_instance);
}
{
auto cfg = _panel_instance.config();
cfg.pin_cs = -1; cfg.pin_rst = 4; cfg.pin_busy = -1;
cfg.memory_width = 320; cfg.memory_height = 480;
cfg.panel_width = 320; cfg.panel_height = 480;
cfg.offset_x = 0; cfg.offset_y = 0;
cfg.invert = true; cfg.rgb_order = false;
_panel_instance.config(cfg);
}
{
auto cfg = _light_instance.config();
cfg.pin_bl = 45; cfg.invert = false; cfg.freq = 44100; cfg.pwm_channel = 7;
_light_instance.config(cfg);
_panel_instance.setLight(&_light_instance);
}
setPanel(&_panel_instance);
}
};
// --- Instâncias e Buffers ---
LGFX gfx;
static const uint16_t screenWidth = 480;
static const uint16_t screenHeight = 320;
static lv_disp_draw_buf_t draw_buf;
static lv_color_t buf1[screenWidth * screenHeight / 10];
// --- Funções de Interface (Ponte LVGL <-> LovyanGFX) ---
void my_disp_flush(lv_disp_drv_t *disp_drv, 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);
gfx.startWrite();
gfx.setAddrWindow(area->x1, area->y1, w, h);
gfx.pushPixels((uint16_t *)color_p, w * h, true);
gfx.endWrite();
lv_disp_flush_ready(disp_drv);
}
// --- Setup e Loop ---
void setup() {
Serial.begin(115200);
Serial.println("Iniciando Exemplo 2: SquareLine Studio com LovyanGFX");
gfx.begin();
gfx.setRotation(1);
gfx.setBrightness(255);
lv_init();
lv_disp_draw_buf_init(&draw_buf, buf1, NULL, screenWidth * screenHeight / 10);
static lv_disp_drv_t disp_drv;
lv_disp_drv_init(&disp_drv);
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);
ui_init(); // Carrega a interface do SquareLine
Serial.println("Setup finalizado. A interface do SquareLine deve aparecer.");
}
void loop() {
lv_timer_handler();
lv_tick_inc(5);
delay(5);
}
Entendendo as Novidades no Código
- Includes: Agora temos
#include <lvgl.h>
para a biblioteca gráfica e#include "ui.h"
para carregar todos os arquivos da interface que o SquareLine Studio gerou. - Buffers do LVGL: As variáveis
draw_buf
ebuf1
são áreas de memória que o LVGL usa para renderizar a interface antes de enviá-la para a tela. my_disp_flush
: Esta é a função “ponte” essencial. O LVGL a chama quando tem algo novo para desenhar, e nosso código usa aLovyanGFX
para efetivamente colocar os pixels na tela.setup()
: A inicialização agora incluilv_init()
e o registro do nosso driver de display com o LVGL. A chamada mais importante éui_init()
, que executa o código gerado pelo SquareLine para criar os widgets.loop()
: O loop agora é o coração do LVGL.lv_timer_handler()
processa todas as tarefas da interface. A funçãolv_tick_inc(5)
informa ao LVGL que o tempo está passando. Embora neste exemplo estático ela não tenha um efeito visível, é crucial para futuras animações e eventos, por isso já a incluímos como boa prática. O valor5
deve sempre corresponder aodelay(5)
para manter o relógio interno do LVGL sincronizado com o tempo real.
Conclusão
Se tudo deu certo, você agora vê na sua tela a mesma interface que desenhou no SquareLine Studio! Você acaba de dar um salto gigantesco: de desenhar texto com código para usar uma ferramenta profissional de design de UI.
No próximo post, vamos ativar o toque e fazer nossa primeira interface interativa.
Até lá!