Nos posts anteriores, preparamos nosso ambiente, fizemos a tela da WT32-SC01 Plus funcionar e até exibimos nossa primeira interface gráfica criada com o SquareLine Studio. No entanto, nossas telas ainda eram estáticas. Chegou a hora de dar vida ao nosso projeto, habilitando o recurso mais importante da placa: o toque.
Neste tutorial, vamos transformar nossa interface estática em uma aplicação interativa. Nosso objetivo é adicionar um botão na tela e, quando ele for pressionado, executar uma ação: imprimir uma mensagem no Monitor Serial. Este é o passo fundamental para criar qualquer aplicação complexa, desde calculadoras a painéis de controle.
Passo 1: Habilitando o Toque no Código Principal
Até agora, nosso código .ino
só se preocupava em desenhar na tela. Para que ele possa ler o toque, precisamos fazer duas adições importantes: configurar o hardware de toque na nossa classe LGFX
e criar a “ponte” para que o LVGL entenda os dados do toque.
Configuração do Hardware de Toque: Abra seu sketch e adicione a configuração do driver de toque à sua classe
LGFX
. ALovyanGFX
já possui um driver nativo para o chipFT6336U
da nossa placa.// Adicione esta linha junto com as outras instâncias de drivers lgfx::Touch_FT5x06 _touch_instance; // Adicione este bloco de configuração dentro da função LGFX(void) { auto cfg = _touch_instance.config(); cfg.x_min = 0; cfg.x_max = 319; cfg.y_min = 0; cfg.y_max = 479; cfg.pin_int = 7; cfg.bus_shared = true; cfg.offset_rotation = 0; cfg.i2c_port = 0; cfg.i2c_addr = 0x38; cfg.pin_sda = 6; cfg.pin_scl = 5; cfg.freq = 400000; _touch_instance.config(cfg); _panel_instance.setTouch(&_touch_instance); }
Crie a Função de Leitura do Toque: Assim como a
my_disp_flush
serve para desenhar, amy_touch_read
serve para ler o toque. Ela pega as coordenadas daLovyanGFX
e as “traduz” para o formato que o LVGL entende. Adicione esta função ao seu código:void my_touch_read(lv_indev_drv_t *indev_drv, lv_indev_data_t *data) { uint16_t touchX, touchY; bool touched = gfx.getTouch(&touchX, &touchY); if (touched) { data->point.x = touchX; data->point.y = touchY; data->state = LV_INDEV_STATE_PR; // Pressionado } else { data->state = LV_INDEV_STATE_REL; // Liberado } }
Registre o Driver de Toque no
setup()
: Por fim, precisamos dizer ao LVGL para usar a nossa funçãomy_touch_read
como fonte de entrada. Adicione este bloco ao seusetup()
:static lv_indev_drv_t indev_drv; lv_indev_drv_init(&indev_drv); indev_drv.type = LV_INDEV_TYPE_POINTER; indev_drv.read_cb = my_touch_read; lv_indev_drv_register(&indev_drv);
Passo 2: Criando a Interface Interativa no SquareLine Studio
Crie um novo projeto no SquareLine Studio (ou use o anterior).
Arraste um widget Button para a tela.
Dentro do botão, adicione um Label e altere o texto para algo como “Clique Aqui”.
Selecione o objeto Button. No painel “Inspector” à direita, role para baixo até a seção Events.
Clique em “Add Event”.
Configure o evento da seguinte forma:
- Trigger:
CLICKED
(ouPRESSED
). - Action:
Call function
. - Function: Digite o nome da função que queremos chamar quando o botão for clicado, por exemplo,
botaoPressionado
.
- Trigger:
Exporte os arquivos da UI como fizemos no post anterior.
Passo 3: A Lógica dos Eventos em ui_events.cpp
Quando você exporta, o SquareLine Studio cria dois arquivos para lidar com os eventos: ui_events.h
e ui_events.c
. É aqui que vamos escrever o que acontece quando o botão é pressionado.
Por padrão, o arquivo ui_events.c
é um arquivo C puro. No entanto, para usarmos funções do Arduino, como a Serial.println()
, precisamos que ele seja compilado como C++. A solução é simples:
Renomeie o arquivo ui_events.c
para ui_events.cpp
.
Agora, abra o seu novo ui_events.cpp
e adicione a lógica da nossa função botaoPressionado
:
/*
* ui_events.cpp
* Lógica para os eventos da interface do SquareLine Studio.
*/
#include <Arduino.h> // Essencial para usar funções do Arduino
#include "ui.h"
void botaoPressionado(lv_event_t * e)
{
// Esta função será chamada sempre que o botão for clicado
Serial.println("O botão foi pressionado!");
// Qualquer outra lógica pode ser adicionada aqui.
}
Passo 4: O Código Final e o Resultado
Juntando tudo, nosso arquivo .ino
final fica assim. Note que ele é muito parecido com o do exemplo anterior, mas agora com a configuração de toque completa.
/*
* EXEMPLO 3: BOTÃO INTERATIVO COM SQUARELINE E LOVYANGFX
* * Este sketch habilita o toque e responde a um evento de clique
* em um botão criado no SquareLine Studio.
*/
#define LGFX_USE_V1
#include <LovyanGFX.hpp>
#include <lvgl.h>
#include "ui.h"
// Classe LGFX completa com a configuração do TOQUE incluída
class LGFX : public lgfx::LGFX_Device {
lgfx::Panel_ST7796 _panel_instance;
lgfx::Bus_Parallel8 _bus_instance;
lgfx::Light_PWM _light_instance;
lgfx::Touch_FT5x06 _touch_instance; // Driver de toque
public:
LGFX(void) {
{ // BUS
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);
}
{ // PANEL
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);
}
{ // BACKLIGHT
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);
}
{ // TOUCH
auto cfg = _touch_instance.config();
cfg.x_min = 0; cfg.x_max = 319;
cfg.y_min = 0; cfg.y_max = 479;
cfg.pin_int = 7;
cfg.bus_shared = true;
cfg.offset_rotation = 0;
cfg.i2c_port = 0; cfg.i2c_addr = 0x38;
cfg.pin_sda = 6; cfg.pin_scl = 5;
cfg.freq = 400000;
_touch_instance.config(cfg);
_panel_instance.setTouch(&_touch_instance);
}
setPanel(&_panel_instance);
}
};
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];
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);
}
void my_touch_read(lv_indev_drv_t *indev_drv, lv_indev_data_t *data) {
uint16_t touchX, touchY;
bool touched = gfx.getTouch(&touchX, &touchY);
if (touched) {
data->point.x = touchX;
data->point.y = touchY;
data->state = LV_INDEV_STATE_PR;
} else {
data->state = LV_INDEV_STATE_REL;
}
}
void setup() {
Serial.begin(115200);
Serial.println("Iniciando Exemplo 3: Botão Interativo");
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);
static lv_indev_drv_t indev_drv;
lv_indev_drv_init(&indev_drv);
indev_drv.type = LV_INDEV_TYPE_POINTER;
indev_drv.read_cb = my_touch_read;
lv_indev_drv_register(&indev_drv);
ui_init();
Serial.println("Setup finalizado. A interface e o toque devem funcionar.");
}
void loop() {
lv_timer_handler();
lv_tick_inc(5);
delay(5);
}
Compile e carregue o código. Agora, ao tocar no botão na tela, você verá a mensagem “O botão foi pressionado!” aparecer no seu Monitor Serial!
Conclusão
Parabéns! Você acaba de criar sua primeira aplicação totalmente interativa na WT32-SC01 Plus. Aprendemos a habilitar o toque, a configurar eventos no SquareLine Studio e a responder a esses eventos no nosso código.
Com esta base, as possibilidades são infinitas. No próximo post, vamos usar o que aprendemos para criar algo ainda mais prático: um contador que incrementa e decrementa um valor na tela.
Até lá!