ESP32 LVGL Graphics Library

For general Flowcode discussion that does not belong in the other sections.
mnfisher
Valued Contributor
Posts: 1552
http://meble-kuchenne.info.pl
Joined: Wed Dec 09, 2020 9:37 pm
Has thanked: 138 times
Been thanked: 740 times

ESP32 LVGL Graphics Library

Post by mnfisher »

Another thing for esp32 users to get involved with. Again it's an advanced project - so you'll need to be comfortable with the esp32 tools.

The LVGL component is a powerful graphics library (see https://docs.lvgl.io/master/intro/index.html) - that offers a lot of power for displays in multiple environments.

I got it to work under the Arduino IDE but it crashed attempting to run from Flowcode. So - after a fair bit of debugging and a few 'gentle' tweaks to the lvgl code (I've given up numerous times) - I finally got it to work.

If you want to play. First save the following to your drive. Note that I am using a ST7789 display and the pins used are hardcoded in supplementary code - it is really hot off the press!
lvgl_esp32_3.fcfx
(14.09 KiB) Downloaded 382 times
Attempt to compile (it will fail)

Then add the lvgl component to your project.

cd to the project folder (if you used the same name as me it need be something like cd c:\lvgl_esp32_3) in a command prompt (or use explorer and right click open in terminal)

framwork dir/export (See above :-) ) (i'm using 5.1.4)
idf.py add-dependency "lvgl/lvgl^9.1.0"
idf.py fullclean
idf.py build

You should notice it add the lvgl component as a directory

Now you need to move (rename) the managed component directory to components

Use: mv managed_components components (Note that this allows us to modify lvgl without causing issues)

Copy lv_conf_template.h (from components lvgl__lvgl) to components/lv_conf.h

idf.py menuconfig

in components (at the end of) - there is a lvgl component - remove the ignore lv_conf header

At the start change #ifdef 0 to #ifdef 1

I changed the #defines to use FREERTOS and ST7789 and removed option to compile demos (or use this...
lv_conf.h
(30.48 KiB) Downloaded 389 times
)

There is a lot of options in here - enjoy

Then - the key part :-( FC seems to use timing options which are incompatible with lvgl. However this only needs changing in one file (3 times)

In lvgl_esp32_3\components\lvgl__lvgl\src\drivers\display\lcd edit lv_lcd_generic_mipi.c

Change all 3 calls to lv_delay(time in ms); to vTaskDelay(time / portTICK_PERIOD_MS);
Note that if we leave lvgl as a managed componnent - at some point it will complain about modified files)

Phew - nearly there. Now just add "lvgl__lvgl" to CMakeLists.txt (in main)

Do a idf.py fullclean
idf.py build (or build from FC)
idf.py -p COMn -b 921600 flash

Hopefully you now have a simple display ! (as mentioned check supplementary code - I have 23 to DIN, 22 to CLK, 21 -RST, 16 -BL, 18 DC)
These should all be changed to #defines (and possibly properties)

Other areas of struggle - Using a large buffer didn't work (gave a buffer too small error). lvgl can double buffer the display.

Drawing - I got 'data transfer size too large' so I split into 1000 (or less) byte lumps - but there might be a better way to do this.

I busy wait on drawing - but lvgl can do more and transfers run in the background (left as an exercise (for Ben?))

There are many features - png /jpg decode for example. I intend to play some more....

Anyone trying this - please ask questions - it is finally working today - and in my enthusiasm to share some of the steps might not be clear?

Martin

Chadb
Posts: 73
Joined: Fri Dec 18, 2020 1:15 pm
Has thanked: 32 times
Been thanked: 1 time

Re: ESP32 LVGL Graphics Library

Post by Chadb »

I haven't tried this yet. But I am really interested in this becoming a thing. I have been playing with the LCD display manager and while useful it isn't LVGL. God Speed!

Chad

mnfisher
Valued Contributor
Posts: 1552
Joined: Wed Dec 09, 2020 9:37 pm
Has thanked: 138 times
Been thanked: 740 times

Re: ESP32 LVGL Graphics Library

Post by mnfisher »

Thanks Chad,

Just recompiled with 5.3 and found a slightly easier alternative route to build (this because I'm struggling to get LittlFS to work :-( )

As before create program directories then cd in a command prompt..

git init
git submodule add https://github.com/lvgl/lvgl.git components/lvgl

This makes your code into a git repository and adds LVGL directly to components (the download seemed rather slower?) (The directory is called lvgl rather than lvgl__lvgl)

Then (attempt to) recompile.

idf.py menuconfig (Use conf file in lvgl)

Create and edit lv_conf (note that this might not be necessary and most of the options can be set in menuconfig - but haven't tested this)

Then - keyboard example (at least works)

in a code block:

Code: Select all

    lv_obj_t * kb = lv_keyboard_create(lv_screen_active());

    /*Create a text area. The keyboard will write here*/
    lv_obj_t * ta1;
    ta1 = lv_textarea_create(lv_screen_active());
    lv_obj_align(ta1, LV_ALIGN_TOP_LEFT, 10, 10);
    //lv_obj_add_event_cb(ta1, ta_event_cb, LV_EVENT_ALL, kb);
    lv_textarea_set_placeholder_text(ta1, "Hello");
    lv_obj_set_size(ta1, 140, 80);

    lv_obj_t * ta2;
    ta2 = lv_textarea_create(lv_screen_active());
    lv_obj_align(ta2, LV_ALIGN_TOP_RIGHT, -10, 10);
    //lv_obj_add_event_cb(ta2, ta_event_cb, LV_EVENT_ALL, kb);
    lv_obj_set_size(ta2, 140, 80);
Martin

mnfisher
Valued Contributor
Posts: 1552
Joined: Wed Dec 09, 2020 9:37 pm
Has thanked: 138 times
Been thanked: 740 times

Re: ESP32 LVGL Graphics Library

Post by mnfisher »

More steps forward....

Finally managed to get littlefs up and running. I used joltwallet/littlefs which can be added to your project using

Code: Select all

idf.py add-dependency joltwallet/littlefs==1.14.8
In lvgl - I enable the option to #define LV_USE_FS_STDIO 1 (not the littlefs option - which I could only get to crash the setup)

Need to create a partition table with a spiffs partition

Code: Select all

# Name,   Type, SubType, Offset,  Size, Flags
# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap
nvs,      data, nvs,     0x9000,  0x6000,
phy_init, data, phy,     0xf000,  0x1000,
factory,  app,  factory, 0x10000, 1M,
storage,  data, spiffs,  ,        0x1F0000,
Which is saved as partitions.csv - and point to this using idf.py menuconfig (note I am using a 4MB esp32 - also set in menuconfig)

Note - one very neat feature is that by adding

Code: Select all

littlefs_create_partition_image(storage D:/Projects/Flowcode/Images FLASH_IN_PROJECT)
to main/CMakeLists.txt (where storage is the name of the partition (set in partitions.csv and the second argument is the directory to upload to the littlefs file system - it will automagically be compiled to an image and uploaded :-) Works brilliantly.

I had to 'tweak' the ST7789 code in lvgl (I'm using an ST7789V) - to set 'invert' for the display colours (although I also managed this in the SendColors - and it would also be possible for the SPI hardware to invert the data) (it took a while to fix this :-( )
I also had to increase the stack size (menuconfig component - esp32 system settings - I used 32768 which works AOK)

Then I also added tjpgd support into lvgl config.

And - decompressing a 240 x 320 jpg works very well

I'd like to say it's been easy (!) but I'm not sure that it has - a lot of frustration with the inverted colours and the compile test cycle is slow even at 921600 baud. (I managed to get 2x921600 baud working on 1 PC but not all USB ports seem to be created equal)

I didn't manage to get a sjpg to decompress but might experiment some more.

Anyone playing along with this?

Martin

BenR
Matrix Staff
Posts: 1940
Joined: Mon Dec 07, 2020 10:06 am
Has thanked: 506 times
Been thanked: 689 times

Re: ESP32 LVGL Graphics Library

Post by BenR »

Hi Martin,

Some great work here so many thanks for sharing. I must admit I've tried LVGL on Arduino IDE before and hit so many walls trying to get the examples to compile that I have repeatedly given up on it so I applaud your tanacity. No idea how other Arduino users are getting it working, maybe they know some magic I'm missing.

Thanks for the comment Chad,
I have been playing with the LCD display manager and while useful it isn't LVGL.
We're actively working on the display manager and trying to add things. Next on the list is bitmap and circular dial/gauge support. Any ideas what else we should try and add. I'm tempted to start pouring through the LVGL code and see what we can port in to run native in Flowcode. Also what is your experience with LVGL? I've seen the amazing examples that have been made but when talking to people actually using it they have struggled to acheive anything but the bare basics.

As for JPEG decompression that indeed would be a very nice thing to have as long as you have a buffer big enough to decompress it into and the ROM to store the program to do the decompression algorythms. I'd be very interested in adding more image formats as bitmaps are great but bulky. I have now properly supported 8-bit and 4-bit bitmaps at least but this is only the beginning. ESP32 has shown the way forward and PICs and AVRs are looking more and more outdated and outclassed. Maybe ARM was this good all along but it's so diverse it's hard to pick a leader to run with.

BenR
Matrix Staff
Posts: 1940
Joined: Mon Dec 07, 2020 10:06 am
Has thanked: 506 times
Been thanked: 689 times

Re: ESP32 LVGL Graphics Library

Post by BenR »

This too might be of interest in terms of Flowcode's offering and where we are going.
viewtopic.php?p=16701#p16701

mnfisher
Valued Contributor
Posts: 1552
Joined: Wed Dec 09, 2020 9:37 pm
Has thanked: 138 times
Been thanked: 740 times

Re: ESP32 LVGL Graphics Library

Post by mnfisher »

Hi Ben,

I initially tried on Flowcode - and it crashed. I then managed to get a display up and running on the Arduino IDE (I couldn't work out how to compile the examples!) - but it niggled as I couldn't see what was causing it to lock under FC (during the display initialisation) as the code looked so similar. So I added lots of printf statements and that's how I narrowed it down to the lv_delay. It now strikes that a better approach would be to rewrite lv_delay rather than replace the calls to it in the display intialisation. This is why my approach was mostly C rather than FC - I'd originally used the SPI component etc - and I wound up replacing most of the code whilst trying to find source of the crash...
It was also maybe a mistake using the latest version of lvgl too? The documentation looks good - but is lacking in details on a lot of aspects!

One of the ideas was that using the espressif approved components (not necessarily lvgl) is a useful technique - so working out the correct way to do it was maybe helpful too.
There are some very neat features - for example uploading the littlefs filesystem data magically is great.

I was quite surprised that jpeg decoding worked so well - it isn't as quick as my previous code (which used jpegdec) but should be fairly portable to MCUs with enough RAM (so ARM and maybe some of the beefier PIC32s)
I'm not sure why s(plit)jpg support doesn't work - the jpeg decoder seems to not recognise the files as in the correct format, but apart from the convertor program included with lvgl I couldn't find much detail about this format.

There are a lot of features - and the ones I have tried seem fairly easy to use (for example an on screen keyboard is a few lines of setup). The current display I have connected isn't touch enabled - but I'll try with the ILI9488 board shortly

Martin

The suggested roadmap looks great though - so this might all be unnecessary :-(

mnfisher
Valued Contributor
Posts: 1552
Joined: Wed Dec 09, 2020 9:37 pm
Has thanked: 138 times
Been thanked: 740 times

Re: ESP32 LVGL Graphics Library

Post by mnfisher »

And with a bit o' fiddling - up and running on Ben's excellent esp32_s3 display board :-)
IMG_20240815_182229.jpg
IMG_20240815_182229.jpg (207.61 KiB) Viewed 7519 times
Decoded from a 320 * 480 jpg on a littlefs partition :-)

Now for 'touch'.

This was easier - so I think I'm on the right track...

mnfisher
Valued Contributor
Posts: 1552
Joined: Wed Dec 09, 2020 9:37 pm
Has thanked: 138 times
Been thanked: 740 times

Re: ESP32 LVGL Graphics Library

Post by mnfisher »

Touch works well - just using the FC component functions as a 'callback'.

First test of a button all good - and then the keyboaard working too (though you'll need fine fingers (or a stylus))

I'll try and add a few 'demo' screens and revise the 'getting started' instructions before uploading.

Martin

mnfisher
Valued Contributor
Posts: 1552
Joined: Wed Dec 09, 2020 9:37 pm
Has thanked: 138 times
Been thanked: 740 times

Re: ESP32 LVGL Graphics Library

Post by mnfisher »

As promised: A step by step guide to setting up lvgl for use in Flowcode - with a demo that displays a 'roller' selection, a keyboard and a circular scale (as a faux clock - my attempts to connect failed so doesn't read the time :-( )
I left littlefs included and initialised - it is easy to decode images if needed.

This using Ben's esp32_s3 and ili9488 board. I'll explain (briefly) how to use other displays if needed.

1) save program as lvgl_demo
attempt to build (fails)
2) open command prompt
3) C:\Espressif\frameworks\esp-idf-v5.3\export
4) cd programs directory (cd path/lvgl_demo)
5 ) git init
6) git submodule add https://github.com/lvgl/lvgl.git components/lvgl
7) idf.py add-dependency joltwallet/littlefs==1.14.8fullclean
8) idf.py fullclean
9) idf.py build (fails)
10) idf.py menuconfig
serial flasher config (set flash size)
component config
esp system settings - set main task stack size 32768
lvgl - untick - check this to not use custom lv_conf.h
partition table - use custom partition table
11) save config
12) copy partitions.csv to directory (path\lvgl_demo)
13) in \main edit cmakelists.txt and add

Code: Select all

target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-unused-variable)
target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-unused-function)
target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-int-conversion)
target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-incompatible-pointer-types)
target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-discarded-qualifiers)
target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-unused-but-set-variable)
to the end of the file (this saves you from REAMS of warnings so is recomended)

13) copy lv_conf.h to path/components directory
14) idf.py build
15) flash with idf.py -p COM7 -b 921600 flash (change com port to suit)

Phew - you should now have a list of wireless SSIDs - select and click OK (it's not used at present)
Click the text box and then type password (end with tick)
Watch the clock

All the components displayed are 'lifted' straight from the lvgl demos. I haven't attempted to tweak their appearance very much...
partitions.csv
(316 Bytes) Downloaded 330 times
lvgl_demo.fcfx
(69.79 KiB) Downloaded 321 times
lv_conf.h
(35.32 KiB) Downloaded 322 times
It took a lot of work getting things up and running but actually it's not bad when it is... - I'm sure much of the code can be made more Flowcodian... I use ULONGs as pointers where needed. I use FCM_Macroname to add callbacks. There might be quite a bit of 'cruff' still - I experimented with various was to handle the different widgets.

I tried various bits and pieces from the examples and had good success (for example decode jpeg)

Martin

Post Reply