Driving SSD1306 with LVGL

I would like to use (for testing purposes mostly) one of those cheap SSD1306-based OLED displays. Micropython provides a ssd1306 driver (micropython/ssd1306.py at master · micropython/micropython · GitHub) and I thought it would be straightforward to use with LVGL. The platform is RPi Pico, and the oled works without LVGL just fine.

I am not able to get LVGL to show anything on the screen, but it might be just my misunderstanding of how is the buffer (and its bit depth!) supposed to be configured. Do I create a separate buffer for LVGL, which will then be copied into the ssd1306 “internal” (python-side) buffer, and then flushed over i2c? I would appreciate a short working example, or a pointer how to do it.

import ssd1306
from machine import Pin, I2C
i2c=I2C(0,sda=Pin(4),scl=Pin(5),freq=50000)
oled=ssd1306.SSD1306_I2C(128,32,i2c)

import lvgl as lv

lv.init()

buf=lv.disp_draw_buf_t()
# can I use oled.buffer here? and how to specify bit depth?
buf.init(oled.buffer,None,len(oled.buffer)//4)
drv=lv.disp_drv_t()
drv.init()
drv.draw_buf=buf
drv.flush_cb=oled.show
drv.hor_res=128
drv.ver_res=32
drv.register()

scr = lv.obj()
btn = lv.btn(scr)
btn.align(lv.ALIGN.CENTER, 0, 0)
label = lv.label(btn)
label.set_text("Button")
lv.scr_load(scr)
1 Like

Micropython frame buffer driver is unrelated to LVGL display driver.
See Display interface — LVGL documentation

You can implement LVGL display driver based on that driver, but I would recommend using DMA otherwise it would be extremely slow.

You can implement LVGL display driver based on that driver, but I would recommend using DMA otherwise it would be extremely slow.

Thanks for responding. Do you think I could (as a first iteration, speed not an issue) have LVGL write into its own buffer, then have the flush callback transform and write those data (1-bit) to the micropython framebuffer driver storage, which would send them to the HW?

Sure, the simplest way is to implement an LVGL display driver, it’s pretty simply.
Basically you implement flush_cb and populate lv.disp_drv_t.

But expect a very low refresh rate if you are going to handle pixels one by one in Python code, instead of using DMA.
On monochrome displays you might be able to achieve a slightly better performance if you configure LVGL to use 1 bit color depth (see LV_COLOR_DEPTH)

I have an spi driver with dma for pico. I think would be usefull as example.
The lvgl driver side draws inside a buffer and then a cb os executed. There you simply configure the dma to send to the lcd via spi or (i2c in ur case).
RP2 DMA ST7789 XPT2046 LVGL.zip (1.0 MB)

Hi, I’m trying to do something similar on the ESP32 (lvgl and display stuff on the SSD1306), but it seems like I need to write my own driver for the SSD1306 that is capable of binding with LVGL, right?