Interfacing LVGL and arduino library

Hi,
I used SquarelineStudio to make a UI,
basically something like last time, just more prettier.
For now 2 Screens, one Welcome screen, and main screen gauge.

I'm facing a bit of issues when I combine Elmduino Bluetooth serial library with my UI code.

My firs issue was I didn't had enough space on my ESP32 so I disabled the OTA partition.
After that I could successfully upload the code onto the ESP32

But when I added the Elmduino code I just get a black screen, my welcome screen doesn't appear nor my main screen.
On Serial monitor I get this message

rst:0x3 (SW_RESET),boot:0x17 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:1184
load:0x40078000,len:13260
load:0x40080400,len:3028
entry 0x400805e4

This would be my UI code with Elmduino

#include <lvgl.h>
#include <TFT_eSPI.h>
#include <ui.h>
#include "BluetoothSerial.h"
#include "ELMduino.h"

BluetoothSerial SerialBT;
#define ELM_PORT   SerialBT
#define DEBUG_PORT Serial
ELM327 myELM327;
uint32_t rpm = 0;

extern lv_obj_t *ui_Arc2;
extern lv_obj_t *ui_Temp;

static const uint16_t screenWidth  = 320;
static const uint16_t screenHeight = 240;
static lv_disp_draw_buf_t draw_buf;
static lv_color_t buf[ screenWidth * screenHeight / 10 ];
TFT_eSPI tft = TFT_eSPI(screenWidth, screenHeight); 

#if LV_USE_LOG != 0
void my_print(const char * buf) {
    Serial.printf(buf);
    Serial.flush();
}
#endif

void my_disp_flush(lv_disp_drv_t *disp, 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);

    tft.startWrite();
    tft.setAddrWindow(area->x1, area->y1, w, h);
    tft.pushColors((uint16_t *)&color_p->full, w * h, true);
    tft.endWrite();

    lv_disp_flush_ready(disp);
}

void my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data) {
    uint16_t touchX = 0, touchY = 0;
    bool touched = false; // Modify this to getTouch() function from your TFT library

    if (!touched) {
        data->state = LV_INDEV_STATE_REL;
    } else {
        data->state = LV_INDEV_STATE_PR;
        data->point.x = touchX;
        data->point.y = touchY;
        Serial.print("Data x ");
        Serial.println(touchX);
        Serial.print("Data y ");
        Serial.println(touchY);
    }
}

void setup() {
    Serial.begin(115200);
    String LVGL_Arduino = "Hello Arduino! ";
    LVGL_Arduino += String('V') + lv_version_major() + "." + lv_version_minor() + "." + lv_version_patch();
    Serial.println(LVGL_Arduino);
    Serial.println("I am LVGL_Arduino");
    lv_init();

#if LV_USE_LOG != 0
    lv_log_register_print_cb(my_print);
#endif

    tft.begin();
    tft.setRotation(3);
    lv_disp_draw_buf_init(&draw_buf, buf, 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_touchpad_read;
    lv_indev_drv_register(&indev_drv);

    ui_init();

    SerialBT.setPin("1234");
    ELM_PORT.begin("ArduHUD", true);
  
    if (!ELM_PORT.connect("OBDII")) {
        DEBUG_PORT.println("Couldn't connect to OBD scanner - Phase 1");
        while (1);
    }

    if (!myELM327.begin(ELM_PORT, true, 2000)) {
        Serial.println("Couldn't connect to OBD scanner - Phase 2");
        while (1);
    }

    Serial.println("Connected to ELM327");
}

void loop() {
    lv_timer_handler();
    delay(15);

    float tempRPM = myELM327.rpm();
    if (myELM327.nb_rx_state == ELM_SUCCESS) {
        rpm = (uint32_t)tempRPM;
        Serial.print("RPM: ");
        Serial.println(rpm);
    } else if (myELM327.nb_rx_state != ELM_GETTING_MSG) {
        myELM327.printError();
    }
}

Does someone know what is the issue?

Select the proper flash size and portion type. some times selecting incorrect flash size or portion type can cause this issue. To make sure its not the code it's self, just flash any example code without changing any settings. If the problem persist even with the example code you can confirm there is something wrong in your board settings.

When I delete couple of lines of code, It boots regularly ( welcome-main screen)

#include <lvgl.h>
#include <TFT_eSPI.h>
#include <ui.h>
#include "BluetoothSerial.h"
#include "ELMduino.h"

BluetoothSerial SerialBT;
#define ELM_PORT   SerialBT
#define DEBUG_PORT Serial
ELM327 myELM327;
uint32_t rpm = 0;

extern lv_obj_t *ui_Arc2;
extern lv_obj_t *ui_Temp;

static const uint16_t screenWidth  = 320;
static const uint16_t screenHeight = 240;
static lv_disp_draw_buf_t draw_buf;
static lv_color_t buf[ screenWidth * screenHeight / 10 ];
TFT_eSPI tft = TFT_eSPI(screenWidth, screenHeight); 

#if LV_USE_LOG != 0
void my_print(const char * buf) {
    Serial.printf(buf);
    Serial.flush();
}
#endif

void my_disp_flush(lv_disp_drv_t *disp, 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);

    tft.startWrite();
    tft.setAddrWindow(area->x1, area->y1, w, h);
    tft.pushColors((uint16_t *)&color_p->full, w * h, true);
    tft.endWrite();

    lv_disp_flush_ready(disp);
}

void my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data) {
    uint16_t touchX = 0, touchY = 0;
    bool touched = false; // Modify this to getTouch() function from your TFT library

    if (!touched) {
        data->state = LV_INDEV_STATE_REL;
    } else {
        data->state = LV_INDEV_STATE_PR;
        data->point.x = touchX;
        data->point.y = touchY;
        Serial.print("Data x ");
        Serial.println(touchX);
        Serial.print("Data y ");
        Serial.println(touchY);
    }
}

void setup() {
    Serial.begin(115200);
    String LVGL_Arduino = "Hello Arduino! ";
    LVGL_Arduino += String('V') + lv_version_major() + "." + lv_version_minor() + "." + lv_version_patch();
    Serial.println(LVGL_Arduino);
    Serial.println("I am LVGL_Arduino");
    lv_init();

#if LV_USE_LOG != 0
    lv_log_register_print_cb(my_print);
#endif

    tft.begin();
    tft.setRotation(3);
    lv_disp_draw_buf_init(&draw_buf, buf, 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_touchpad_read;
    lv_indev_drv_register(&indev_drv);

    ui_init();

    SerialBT.setPin("1234");
    ELM_PORT.begin("ArduHUD", true);
  
    

    Serial.println("Connected to ELM327");
}

void loop() {
    lv_timer_handler();
  
    delay(15);

   
}

The Partition is set to No OTA (Large App)

When I added the Elmduino code in void loop

void loop() {
    lv_timer_handler();
    delay(15);

    float tempRPM = myELM327.rpm();
    if (myELM327.nb_rx_state == ELM_SUCCESS) {
        rpm = (uint32_t)tempRPM;
        Serial.print("RPM: ");
        Serial.println(rpm);
    } else if (myELM327.nb_rx_state != ELM_GETTING_MSG) {
        myELM327.printError();
    }
}

it again goes into boot loop mode

It seems when I add this

if (!ELM_PORT.connect("OBDII")) {
        DEBUG_PORT.println("Couldn't connect to OBD scanner - Phase 1");
        while (1);
    }

    if (!myELM327.begin(ELM_PORT, true, 2000)) {
        Serial.println("Couldn't connect to OBD scanner - Phase 2");
        while (1);
    }

    Serial.println("Connected to ELM327");

The screen gets corrupted like those noisy horizontal lines.
This is the serial monitor

rst:0x1 (POWERON_RESET),boot:0x17 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:1184
load:0x40078000,len:13260
load:0x40080400,len:3028
entry 0x400805e4
Hello Arduino! V8.3.7
I am LVGL_Arduino
Couldn't connect to OBD scanner - Phase 1

It's trying to connect to OBD scanner ( ofc. i don't have it here so Phase 1 is OK and correct)

Maybe this is making the issue
Sketch uses 2086825 bytes (99%) of program storage space. Maximum is 2097152 bytes.
Global variables use 105280 bytes (32%) of dynamic memory, leaving 222400 bytes for local variables. Maximum is 327680 bytes.

Hmm it might be memory size.
When I remove Welcome screen. And compile it uses 88% and everything is ok in serial monitor and on the screen.

I'm having another problem.

When I compile a sketch and upload it. Everything works.
I unplug ESP32, and plug it back in the image on display gets corrupted.

This is While I'm having a No OTA partition setting
a4e1b39edd187b9627e1cf554ebaea9e68b065c5_2_690x488

do not use the "while" loop without anything within it. It can cause WDT resets. Even though your serial port output not showing it( share a few boot msgs, not just a single one). Try adding a simple delay function within the while loop to avoid WDT reset.

1 Like

try a manual reset after plugging it back.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.