DFR0669 + ESP32 + LVGL + LGFX touchscreen not working help needed
Hi, i'm trying to use the touchscreen with lvgl and lgfx but i can't seem to make it work
i use this screen: https://wiki.dfrobot.com/3.5inches_480_320_TFT_LCD_Capacitive_Touchscreen_SKU_DFR0669
My setup is as follow:
[env:esp32dev] platform = espressif32 board = esp32-s3-devkitc-1 framework = arduino monitor_speed = 9600 lib_deps = lvgl/lvgl@^8.3.4 lovyan03/LovyanGFX@^1.1.5 miguelbalboa/MFRC522@^1.4.10 bblanchon/ArduinoJson@^6.21.2 SPI Wire
The pins are connected as follows:
sclk: 14
mosi: 13
miso: 12
dc: 16
cs: 15
rst: 17
bl: 21
scl: 38
sda: 39
int: 40
The code for the hpp:
```
#pragma once
#define LGFX_USE_V1
#include <LovyanGFX.hpp>
#include <driver/i2c.h>
#define LANDSCAPE
#ifdef LANDSCAPE
extern const uint16_t screenWidth = 480;
extern const uint16_t screenHeight = 320;
#else
static const uint16_t screenWidth = 320;
static const uint16_t screenHeight = 480;
#endif
class LGFX : public lgfx::LGFX_Device
{
static constexpr int I2C_PORT_NUM = I2C_NUM_0;
static constexpr int I2C_PIN_SDA = 39;
static constexpr int I2C_PIN_SCL = 38;
static constexpr int I2C_PIN_INT = 40;
lgfx::Panel_ILI9488 _panel_instance;
lgfx::Bus_SPI _bus_instance;
lgfx::Light_PWM _light_instance;
// lgfx::Touch_GT911 _touch_instance;
lgfx::ITouch* _touch_instance_ptr = nullptr;
bool init_impl(bool use_reset, bool use_clear) override
{
if (_touch_instance_ptr == nullptr) {
lgfx::ITouch::config_t cfg;
lgfx::i2c::init(I2C_PORT_NUM, I2C_PIN_SDA, I2C_PIN_SCL);
if (lgfx::i2c::beginTransaction(I2C_PORT_NUM, 0x38, 400000, false).has_value()
&& lgfx::i2c::endTransaction(I2C_PORT_NUM).has_value())
{
_touch_instance_ptr = new lgfx::Touch_FT5x06();
cfg = _touch_instance_ptr->config();
cfg.i2c_addr = 0x38;
cfg.x_max = screenWidth;
cfg.y_max = screenHeight;
}
else
if (lgfx::i2c::beginTransaction(I2C_PORT_NUM, 0x48, 400000, false).has_value()
&& lgfx::i2c::endTransaction(I2C_PORT_NUM).has_value())
{
_touch_instance_ptr = new lgfx::Touch_NS2009();
cfg = _touch_instance_ptr->config();
cfg.i2c_addr = 0x48;
cfg.x_min = 0;
cfg.y_min = 0;
cfg.x_max = screenWidth;
cfg.y_max = screenHeight;
}
if (_touch_instance_ptr != nullptr)
{
cfg.i2c_port = I2C_PORT_NUM;
cfg.pin_sda = I2C_PIN_SDA;
cfg.pin_scl = I2C_PIN_SCL;
cfg.pin_int = I2C_PIN_INT;
cfg.freq = 400000;
cfg.bus_shared = false;
_touch_instance_ptr->config(cfg);
_panel_instance.touch(_touch_instance_ptr);
}
}
return lgfx::LGFX_Device::init_impl(use_reset, use_clear);
}
public:
LGFX(void)
{
{
auto cfg = _bus_instance.config();
//cfg.spi_host = SPI3_HOST;
//cfg.spi_mode = 0;
cfg.freq_write = 40000000;
cfg.freq_read = 16000000;
cfg.spi_3wire = false;
cfg.use_lock = true;
cfg.dma_channel = SPI_DMA_CH_AUTO;
cfg.pin_sclk = 14;
cfg.pin_mosi = 13;
cfg.pin_miso = 12;
cfg.pin_dc = 16;
_bus_instance.config(cfg);
_panel_instance.setBus(&_bus_instance);
}
{
auto cfg = _panel_instance.config();
cfg.pin_cs = 15;
cfg.pin_rst = 17;
cfg.pin_busy = -1;
cfg.offset_x = 0;
cfg.offset_y = 0;
cfg.offset_rotation = 0;
cfg.dummy_read_pixel = 8;
cfg.dummy_read_bits = 1;
cfg.readable = true;
cfg.invert = false;
cfg.rgb_order = false;
cfg.dlen_16bit = false;
cfg.bus_shared = false;
_panel_instance.config(cfg);
}
{
auto cfg = _light_instance.config();
cfg.pin_bl = 21;
cfg.invert = false;
cfg.freq = 44100;
cfg.pwm_channel = 7;
_light_instance.config(cfg);
_panel_instance.setLight(&_light_instance);
}
setPanel(&_panel_instance);
}
};
```
The code for the cpp:
```
#include <MFRC522.h>
#include <WiFi.h>
#include <LovyanGFX.hpp>
#define SS_PIN 5
#define RST_PIN 27
#define TASK_SLEEP_PERIOD_MS 4
#define LV_TICK_PERIOD_MS 4
#define LV_DOUBLE_BUFFER
#define TAG "Demo"
#if CONFIG_IDF_TARGET_ESP32S3
#include "LGFX_S3.hpp"
#ifdef LANDSCAPE
#define LV_BUFFER_SIZE 80
#else
#define LV_BUFFER_SIZE 120
#endif
#else
#error Only esp32s3 defined
#endif
#if defined(DISABLE_FLUSH_DURING_BENCHMARK) && !CONFIG_LV_USE_LOG
#error You will need to enable LVGL logging (and probably set log to printf) in the menuconfig to get results.
#endif
LGFX display;
#include <lvgl.h>
#include <demos/lv_demos.h>
static lv_disp_draw_buf_t draw_buf;
#ifdef LV_DOUBLE_BUFFER
static lv_color_t buf[ screenWidth * LV_BUFFER_SIZE ];
static lv_color_t buf2[screenWidth * LV_BUFFER_SIZE];
#else
static lv_color_t buf[screenWidth * 2];
#endif
typedef void (*function_pointer_t)(void);
typedef struct btn {
const char *const name;
function_pointer_t function;
} btn_t;
static bool disable_flush = false;
static void display_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p);
static void touchpad_read(lv_indev_drv_t *indev_driver, lv_indev_data_t *data);
static void lv_tick_task(void *arg);
static void button_event_handler(lv_event_t *e) {
lv_event_code_t code = lv_event_get_code(e);
lv_obj_t *btn = lv_event_get_target(e);
//Serial.println("In btn event handler");
Serial.println("code is"+code);
if (code == LV_EVENT_CLICKED) {
Serial.println("Btn pressed");
function_pointer_t dm_func = (function_pointer_t)lv_event_get_user_data(e);
if (dm_func) {
lv_obj_t *label = lv_obj_get_child(btn, 0);
ESP_LOGI(TAG, "Starting %s", lv_label_get_text(label));
#ifdef DISABLE_FLUSH_DURING_BENCHMARK
if (dm_func == lv_demo_benchmark) {
ESP_LOGI(TAG, "Stating benhmark with flush");
disable_flush = true;
}
#endif
dm_func();
//lv_obj_del(dm_selection_panel);
}
}
}
static void display_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p) {
#ifdef DISABLE_FLUSH_DURING_BENCHMARK
if (disable_flush) {
lv_disp_flush_ready(disp);
return;
}
#endif
uint32_t w = (area->x2 - area->x1 + 1);
uint32_t h = (area->y2 - area->y1 + 1);
display.startWrite();
display.setAddrWindow(area->x1, area->y1, w, h);
display.writePixels((uint16_t *)&color_p->full, w * h, true);
display.endWrite();
lv_disp_flush_ready(disp);
}
static void touchpad_read(lv_indev_drv_t *indev_driver, lv_indev_data_t *data) {
uint16_t touchX, touchY;
bool touched = display.getTouch(&touchX, &touchY);
//
if (!touched) {
data->state = LV_INDEV_STATE_REL;
//Serial.println("screen touched state rel" + touched);
} else {
Serial.println("screen touched state pr" + touched);
data->state = LV_INDEV_STATE_PR;
data->point.x = touchX;
data->point.y = touchY;
}
}
static void lv_tick_task(void *arg) {
(void)arg;
lv_tick_inc(LV_TICK_PERIOD_MS);
}
void initLvglLgfx() {
display.begin();
#ifdef LANDSCAPE
display.setRotation( 1 );
#endif
display.setBrightness(255);
lv_init();
#ifdef LV_DOUBLE_BUFFER
lv_disp_draw_buf_init(&draw_buf, buf, buf2, screenWidth * LV_BUFFER_SIZE);
#else
lv_disp_draw_buf_init(&draw_buf, buf, NULL, screenWidth * LV_BUFFER_SIZE * 2);
#endif
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 = display_flush;
disp_drv.draw_buf = &draw_buf;
lv_disp_drv_register( &disp_drv );
// Input device driver
static lv_indev_drv_t indev_drv;
lv_indev_drv_init( &indev_drv );
indev_drv.type = LV_INDEV_TYPE_POINTER;
indev_drv.read_cb = touchpad_read;
lv_indev_drv_register( &indev_drv );
// periodic timer interrupt
const esp_timer_create_args_t periodic_timer_args = {
.callback = &lv_tick_task, .name = "periodic_gui"
};
esp_timer_handle_t periodic_timer;
ESP_ERROR_CHECK(esp_timer_create(&periodic_timer_args, &periodic_timer));
ESP_ERROR_CHECK(esp_timer_start_periodic(periodic_timer, LV_TICK_PERIOD_MS * 1000));
/// OBJSSS
lv_obj_t * label;
static lv_style_t style;
lv_style_init(&style);
lv_style_set_bg_color(&style, lv_palette_main(LV_PALETTE_CYAN));
lv_obj_t * btn1 = lv_btn_create(lv_scr_act());
lv_obj_align(btn1, LV_ALIGN_CENTER, 0, -40);
lv_obj_add_style(btn1, &style, 0);
label = lv_label_create(btn1);
lv_label_set_text(label, "Entree");
lv_obj_center(label);
lv_obj_add_event_cb(btn1, button_event_handler, LV_EVENT_PRESSED, NULL);
lv_obj_t * btn2 = lv_btn_create(lv_scr_act());
// lv_obj_add_event(btn2, event_handler, LV_EVENT_ALL, NUllolololoLL);
lv_obj_align(btn2, LV_ALIGN_CENTER, 0, 0);
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, "Sortie");
lv_obj_center(label);
lv_obj_add_event_cb(btn2, button_event_handler, LV_EVENT_PRESSED, NULL);
}
void setup() {
Serial.begin(9600);
// INIT RFID
SPI.begin();
initLvglLgfx();
}
}
void loop()
{
lv_timer_handler();
vTaskDelay(pdMS_TO_TICKS(TASK_SLEEP_PERIOD_MS));
}
```
What am i doing wrong ?
Regards
It is recommended to use the DFRobot_GDL library in the wiki, which is a small graphics library written by ourselves. We don't have LVGL + LGFX related tests, sorry.
jenna