Usage of LittlevGL tasks in Micropython

Dear all,

I’m currently working on a small project, where a LittlevGL GUI in micropython should continuously refresh position data acquired by a UART GPS module (u-blox Neo-6m). My guess is that calling the “UART read” functions (which can take up to 400ms) would cause the GUI to be blocked during that time.
To circumvent this, I’ve tried to put the “UART read” (here: a dummy) function into a LittlevGL task, but haven’t had a success so far…
My (extremely basic) code looks like that:

#----------------------------- import packages -------------------------------

import lvgl as lv
import lvesp32
from time import sleep_ms

#------------- define a task that would, in a loop, block the GUI ------------

def some_blocking_function(data=None):
    print("Hello, I'll be blocking your GUI...")
    sleep_ms(300)

lv.init()
lv.task_core_init()
some_blocking_task = lv.task_create(some_blocking_function, 500, lv.TASK_PRIO.HIGH, None)
lv.task_enable(some_blocking_task)

#try:
while True:
    print("I'm not busy...")
    lv.task_handler()
    sleep_ms(100)

Does anyone have an idea what I’m doing wrong? It seems that my “some_blocking_task” is never called…
Thanks a lot for your help!

A couple of issues I see:

  • Do not sleep in some_blocking_function. That will block the GUI for 300ms.
  • You do not need to call lv.task_core_init (as lv.init initializes everything for you here).
  • 100ms is a pretty slow period to call lv.task_handler in. I would suggest calling it every 5-10 ms.
  • I don’t think calling lv.task_enable is needed either.

Thanks for your suggestions! With them, the code executes both the loop and the task.
However, I’m afraid that achieving a responsive GUI that doesn’t block even if some readout function requires ~400 ms would require multithreading / something like freeRTOS…

EDIT: By the way, is it possible to implement features of the “uasyncio” library into the LittlevGL bindings? I really don’t have any idea how complicated this would be…

Did you try running your blocking readout function from another thread?

Under the hoods, a new micropython thread is actually a new FreeRTOS task:

Example of LVGL + uasyncio: