Pular para o conteúdo

LVGL vs. desenho personalizado: por que os construtores de GUI vencem na produção ​

Publicado em Lopaka.app — O construtor de GUI LVGL gratuito e baseado na web para desenvolvedores embarcados

Introdução ​

Se você está criando uma GUI para um display embarcado, está diante de uma decisão fundamental: usar um framework como o LVGL ou escrever seu próprio código de desenho?

O debate surge o tempo todo nas comunidades embarcadas. De um lado, puristas defendem que o desenho personalizado oferece controle máximo e sobrecarga mínima. Do outro, pragmáticos apontam que reinventar a roda é um péssimo uso do tempo de engenharia.

Passei o último ano construindo o Lopaka — um construtor visual de GUI para LVGL — e observando dezenas de equipes lançarem produtos com ele. Os dados são claros, mas a resposta é mais nuançada do que você pode esperar.

Neste post, vou detalhar os verdadeiros compromissos entre LVGL e desenho personalizado, compartilhar benchmarks de desempenho e dizer exatamente quando usar cada abordagem.

O que é o LVGL? ​

O LVGL (Light and Versatile Graphics Library) é a biblioteca gráfica open-source mais popular para sistemas embarcados. Ele oferece:

  • Widgets: Botões, rótulos, controles deslizantes, tabelas, medidores, teclados e mais de 35 outros
  • Mecanismos de layout: Layouts flexbox e grid (sim, como o CSS)
  • Sistema de estilos: Estilo no jeito CSS, com estados, transições e herança
  • Tratamento de entrada: Suporte a toque, encoder, teclado e botões
  • Animações: Mecanismo de animação integrado com funções de easing
  • Gerenciamento de memória: Otimizado para MCUs com apenas 32KB de RAM

Ele roda em tudo, de ESP32 a STM32 a Raspberry Pi, e tem licença MIT.

O que é desenho personalizado? ​

Desenho personalizado significa que você escreve seu próprio código para renderizar pixels no display:

c
// Custom drawing approach
tft.fillScreen(TFT_BLACK);
tft.drawString("Temperature", 10, 10);
tft.drawNumber(25, 10, 30);
tft.drawRect(10, 60, 300, 40, TFT_WHITE);
// ... repeat for every element, every frame

Você cuida de tudo: posicionamento, redesenho, detecção de entrada, gerenciamento de estado, animações.

Comparação direta ​

Tempo de desenvolvimento ​

MétricaLVGLDesenho personalizado
Tela simples (3-5 elementos)15-30 min1-2 horas
Tela complexa (10+ elementos)1-2 horas4-8 horas
App com várias telas (5 telas)4-6 horas20-40 horas
Adicionar animações10 min2-4 horas
Adicionar entrada por toque5 min1-2 horas

Vencedor: LVGL por uma margem enorme.

Com um construtor visual como o Lopaka, esses tempos caem ainda mais — a maioria das telas simples leva menos de 10 minutos para projetar e exportar.

Manutenibilidade do código ​

Abordagem LVGL:

c
// Clear, semantic code
lv_obj_t *temp_label = lv_label_create(lv_scr_act());
lv_label_set_text(temp_label, "25°C");
lv_obj_align(temp_label, LV_ALIGN_CENTER, 0, -20);

// Easy to modify
void update_temp(float value) {
    lv_label_set_text_fmt(temp_label, "%.1f°C", value);
}

Abordagem de desenho personalizado:

c
// Manual pixel management
void draw_temp(int x, int y, float value) {
    char buf[16];
    sprintf(buf, "%.1f°C", value);
    // Must clear old text first
    tft.fillRect(x-5, y-5, 80, 20, TFT_BLACK);
    tft.drawString(buf, x, y);
}

Vencedor: LVGL. O código semântico de widgets se documenta sozinho. O código de desenho personalizado exige comentários para explicar o que cada retângulo faz.

Desempenho ​

É aqui que a coisa fica interessante. Vamos fazer benchmark em um ESP32 com display ILI9341:

MétricaLVGLDesenho personalizado
Uso de RAM (UI simples)15-25 KB2-5 KB
Uso de RAM (UI complexa)40-80 KB10-20 KB
Tamanho em flash80-120 KB10-30 KB
Taxa de quadros (UI simples)30-60 fps50-60 fps
Taxa de quadros (UI complexa)20-40 fps30-50 fps
Uso de CPU (ocioso)2-5%0-1%
Uso de CPU (ativo)15-30%5-15%

Vencedor: Desenho personalizado no desempenho bruto, mas a diferença é menor do que você imagina.

Para a maioria das aplicações, o desempenho do LVGL é mais do que suficiente. Os 20-40 fps que você obtém em UIs complexas são visualmente suaves, e o uso de CPU deixa bastante margem para a lógica da sua aplicação.

Onde o desenho personalizado vence:

  • Dispositivos de consumo ultrabaixo (sensores alimentados por bateria que dormem 99% do tempo)
  • MCUs extremamente limitados em recursos (< 64KB de RAM)
  • Visualização de dados em alta velocidade (osciloscópios, gráficos em tempo real a mais de 100 fps)

Onde o LVGL vence:

  • Qualquer coisa com interação do usuário (botões, menus, formulários)
  • Aplicações com várias telas
  • Produtos que precisam parecer profissionais
  • Equipes com mais de um desenvolvedor

Experiência de desenvolvimento ​

Isso é subjetivo, mas importante. Pergunte a si mesmo:

  • Você quer passar seu tempo nos recursos exclusivos do seu produto ou desenhando retângulos?
  • Como você vai tratar a entrada por toque? Detecção de acerto? Antirrebote de botões?
  • E a navegação por teclado para acessibilidade?
  • Como você implementa transições suaves entre telas?
  • Quem mantém esse código quando você sair?

Vencedor: LVGL. Ele resolve problemas nos quais você ainda nem pensou.

A análise de custo real ​

Vamos colocar isso em termos de negócio. Suponha que um desenvolvedor embarcado custe US$ 80/hora:

AbordagemTempo de desenvolvimentoCustoManutenção contínua
Desenho personalizado (simples)40 horasUS$ 3.200US$ 400/mês
Desenho personalizado (complexo)160 horasUS$ 12.800US$ 800/mês
LVGL (codificado à mão)20 horasUS$ 1.600US$ 200/mês
LVGL + Lopaka8 horasUS$ 640US$ 100/mês

A escolha de ferramenta que mais economiza dinheiro não é a de menor binário — é a que permite à sua equipe entregar mais rápido.

Quando usar cada abordagem ​

Use desenho personalizado quando: ​

  1. Você tem restrições extremas de recursos — < 32KB de RAM, < 128KB de flash
  2. Sua UI é estática — Uma única tela que nunca muda (por exemplo, uma leitura de temperatura)
  3. Você precisa de taxa de quadros máxima — Osciloscópios, analisadores lógicos, gráficos em tempo real
  4. Você está construindo uma biblioteca, não um produto — Você precisa de zero dependências
  5. Você gosta disso — Alguns desenvolvedores realmente gostam de escrever código de renderização

Use LVGL quando: ​

  1. Sua UI tem interação do usuário — Botões, menus, formulários, telas de configurações
  2. Você tem várias telas — Navegação, abas, modais
  3. Você precisa que pareça profissional — Demos de produto, dispositivos voltados ao cliente
  4. Você está com prazo — Entregar em semanas, não em meses
  5. Você é uma equipe — Vários desenvolvedores precisam trabalhar na UI
  6. Você quer que seja sustentável — Outra pessoa vai tocar nesse código

A abordagem híbrida ​

As equipes mais inteligentes com as quais trabalho usam uma abordagem híbrida:

  1. LVGL para a UI principal — Menus, configurações, telas de configuração
  2. Desenho personalizado para visualizações especializadas — Gráficos em tempo real, visualizações personalizadas
  3. Lopaka para prototipagem rápida — Projete as partes em LVGL visualmente, itere rápido
c
// Main screens use LVGL (designed in Lopaka)
lv_obj_t *main_screen = ui_MainScreen_create();

// Specialized view uses custom drawing
lv_obj_t *graph_canvas = lv_canvas_create(lv_scr_act());
lv_canvas_fill_bg(graph_canvas, lv_color_black(), LV_OPA_COVER);
// Custom rendering code for high-speed data visualization
draw_oscilloscope_trace(graph_canvas, samples, num_samples);

Isso lhe dá o melhor dos dois mundos: desenvolvimento rápido para 90% da sua UI e controle máximo para os 10% que precisam.

Objeções comuns (e por que estão erradas) ​

“O LVGL é pesado demais” ​

A configuração mínima do LVGL roda com 32KB de RAM e 80KB de flash. Isso é menos do que a maioria dos sketches Arduino. A fama de “pesado” vem das configurações padrão que habilitam todos os recursos.

“Preciso de controle pixel a pixel” ​

O LVGL oferece controle pixel a pixel — você pode posicionar qualquer coisa exatamente onde quiser. A diferença é que você não é forçado a calcular cada coordenada manualmente.

“Código personalizado é mais eficiente” ​

Para renderização bruta, sim. Para a experiência completa do usuário (tratamento de entrada, gerenciamento de estado, animações, acessibilidade), o LVGL é dramaticamente mais eficiente porque já está escrito e testado.

“Não quero dependências externas” ​

O LVGL tem licença MIT, zero dependências e é usado em produção por milhares de empresas. É o mais próximo de “sem dependência” que você pode chegar para uma biblioteca gráfica.

A conclusão ​

CritérioVencedor
Velocidade de desenvolvimentoLVGL
Manutenibilidade do códigoLVGL
Desempenho brutoDesenho personalizado
Uso de recursosDesenho personalizado
Aparência profissionalLVGL
Colaboração em equipeLVGL
Manutenção de longo prazoLVGL
Curva de aprendizadoDesenho personalizado (no início)

Para 90% dos projetos de GUI embarcada, o LVGL é a escolha certa. O compromisso de desempenho é insignificante para a maioria das aplicações, e a economia de tempo de desenvolvimento é enorme.

Os 10% restantes — dispositivos ultra-restritos, visualizações em alta velocidade, displays estáticos — são melhor atendidos pelo desenho personalizado.

E para os projetos LVGL? Usar um construtor visual como o Lopaka torna a decisão ainda mais fácil. Você obtém o poder do LVGL com uma fração do tempo de desenvolvimento.

Recursos ​

Ainda em dúvida? Tente criar a mesma tela dos dois jeitos e cronometre. Acho que você vai se surpreender.