- Notifications
You must be signed in to change notification settings - Fork3
LVGL module for MicroPython, customized for MicroPythonOS
License
MicroPythonOS/lvgl_micropython
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
IMPORTANT READ ME FIRST
- DO NOT use any information from the official binding and try to use that when compiling this binding it is not going to work
- DO NOT add any submodule initilization commands when cloning the repo or any any point after the repo has been cloned.To clone and build this is how it's done.
git clone https://github.com/lvgl-micropython/lvgl_micropythoncd lvgl_micropythonpython3 make.py esp32 ...... - If you want to update to the current master then delete your local copy and clone it again from scratch.
This project is a spinoff of thelv_micropythonandlv_binding_micropythonprojects. The goal of this project is to make it easier to compile, create a common API soit is easy to add new drivers and to support more connection topologies to displays and input devices.
What is MicroPython?
MicroPython is just how it sounds. It is a micro version of Python. It is written to run on microcontrollersIt has a small memory footprint and small binary size as well as provides access to the hardwarerelated bits of a microcontroller.
What is LVGL?
LVGL is a graphics framework written for C99. It is also written to run on resource constrained devices.It is a feature rich framework that provides a plethora of different controls (widgets) as well as the abilityto make your owmn custom controls.
What is a binding?
A Binding is code that encapsulates code written in one programming language so it is accessable from anotherprogramming language. It is best to think of it as a translator, in the case of this project it translates Pythonto C99 and vice versa. It allows us access to the LVGL code by using the Python programming language.
I have altered how the RGBBus driver works. Due to low framerates from LVGL needing to render the whole screeneach time a small change is made and LVGL also having to keep the 2 frame buffers in sync I have decided to tryand bring a little bit of my coding ability to the show to see if I am able to overcome some of the performance issues.
This comes at the cost of additional memory but due to the buffers needing to reside in SPIRAM because of their sizeI figured what's a couple hundred K more. What I have done is this.
The 2 full frame buffers are no longer accessable to the user. These are kept tucked away in C code. The user is able toallocate partial buffers of any size they want. I have not messed about with this to see if there is a sweet spot with thesize but I would imagine that 1/10 the display size is a good starting point. I am running a task on the second core of the ESP32and in that task is where the buffer copying takes place. This is ideal because it is able to offload that work so there is nodrop in performance in the user code. MicroPython only uses one core of the ESP32 and that is what makes this an ideal thing to do.
If you use 2 partial buffers while one of being copied to the full frame buffer LVGL is able to fill the other partial buffer.Another nifty thing I have done is I am handling the rotation of the screen in that task as well. This should provide much betterperformance than having LVGL handle the rotation.
So make sure when you are creating the frame buffers for the RGB display that you make them a fraction of the size of what theyused to be.
- Supported display and touch hardware
- Build Instructions
- Python code examples
- ICs not listed below can often be handled with generic drivers like "rgb_display"
- GC9A01
- HX8357B
- HX8357D
- ILI9163
- ILI9225
- ILI9341
- ILI9481
- ILI9486
- ILI9488
- LT768x *WIP*
- R61581
- RA8876 *WIP*
- RM68120
- RM68140
- S6D02A1
- SSD1351
- SSD1963_480
- SSD1963_800
- SSD1963_800ALT
- SSD1963_800BD
- ST7701S *WIP*
- ST7735B
- ST7735R_Red
- ST7735R_Green
- ST7789
- ST7796
- CST816S
- FT5x06
- FT5x16
- FT5x26
- FT5x36
- FT5x46
- FT6x06
- FT6x36
- GT911
- STMPE610
- XPT2046
- SDL2 *Only for the unix and macOS ports*
I have changed the design of the binding so it is no longer a dependancy ofMicroPython. Instead MicroPython is now a dependency of the binding. By doingthis I have simplified the process up updating the MicroPython version. Onlysmall changes are now needed to support newer versions of MicroPython.
In order to make this all work I have written a Python script that handlesBuilding the binding. The only prerequesits are that you have a C compilerinstalled (gcc, clang, msvc) and the necessary support libs.
To compile you will need Python >= 3.10 for for all build types.
Ubuntu (Linux): you can install all of these using
apt-get install- build-essential
- cmake
- ninja-build
- python
- python3-venv
- libusb-1.0-0-dev
macOS
xcode-select -–installbrew install cmakebrew install ninjabrew install python
Ubuntu (Linux): you can install all of these using
apt-get install- build-essential
- cmake
- ninja-build
- python
- gcc-arm-none-eabi
- libnewlib-arm-none-eabi
macOS
command xcode-select–installbrew install makebrew install cmakebrew install ninjabrew install pythonbrew install armmbed/formulae/arm-none-eabi-gcc
Windows
- Not yet supported
Ubuntu (Linux): you can install all of these using
apt-get install- gcc-arm-none-eabi
- libnewlib-arm-none-eabi: maybe??
- build-essential
- ninja-build
- python
macOS
command xcode-select–installbrew install makebrew install ninjabrew install pythonbrew install armmbed/formulae/arm-none-eabi-gcc
Windows
- Not yet supported
useapt-get install {requirements} for Ubuntu like Linux variants.
- build-essential
- libffi-dev
- pkg-config
- cmake
- ninja-build
- gnome-desktop-testing
- libasound2-dev
- libpulse-dev
- libaudio-dev
- libjack-dev
- libsndio-dev
- libx11-dev
- libxext-dev
- libxrandr-dev
- libxcursor-dev
- libxfixes-dev
- libxi-dev
- libxss-dev
- libxkbcommon-dev
- libdrm-dev
- libgbm-dev
- libgl1-mesa-dev
- libgles2-mesa-dev
- libegl1-mesa-dev
- libdbus-1-dev
- libibus-1.0-dev
- libudev-dev
- fcitx-libs-dev
- libpipewire-0.3-dev
- libwayland-dev
- libdecor-0-dev
command xcode-select–installbrew install libffibrew install ninjabrew install makebrew install SDL2
- Not yet supported
python3 make.py {build target} {build options} {target options} {global options}This is a required option and it is positional. It must be the first option provided.Choices are:
esp32: Espressif ESP32 line of MCU'smacOS: Compile to run on macOSNOTE: MUST be compiled on the same computer it is going to run onstm32: ST Microprocessors line of MCU'sunix: Compile to run on unixNOTE: MUST be compiled on the same computer it is going to run onrp2: Raspberry Pi Pico 2 MCUrenesas-ra: Renesas RA line of MCU'snrf: Nordic Semiconductor MCU'smimxrt: NXP i.MX RT line of MCU'ssamd: Microchip Technology SAM D line of MCU's
This is a positoional argument and it must be the second one in the build commandif it is used. Choices are:
clean: This flat out deletes the build folder. It will only error if the user doesn't havepermission to delete the files in the folder. So if the clean fails run the build usingsudoMake is instructed to perform a clean prior to every build so this really only needs to be usedif there is some kind of an issue the make's clean is not cleaning out. This is also how you cleanmpy-cross.
Target options is broken down into 2 sections
python3 make.py {build target} {build options} {{model/variant} {model/variant specific options}} {global options}The model is the processor model being used or the build type. The build type is what isspecified when compiling to run on macOS or Unix.
When compiling for macOS or Unix you are able to specify the build type. That is done by usingtheVARIANT option. The syntax for this option isVARIANT={build type}
Here are the available build types:
coverageminimalnanboxstandard(default)
When compiling for all others you use theBOARD option. The symntax for this optionisBOARD={board name}. Some "boards" are generic and can have different variants. To specifywhat board variamnmt is being used you use the following option,BOARD_VARIANT={variant}.
This is a list of the boards that MicroPython supports. Some of these boards might not haveenough available program storage or RAM to be able to run the binding. I will at some point lookat the specs for each of them to see if they will be able to run this binding.
Any sub items listed under a board is a variant that is available for that board.
NOTE: You cannot specify a variant unless the board has been specified.
esp32:
- ARDUINO_NANO_ESP32
- ESP32_GENERIC
- D2WD
- OTA
- SPIRAM
- UNICORE
- ESP32_GENERIC_C3
- ESP32_GENERIC_S2
- ESP32_GENERIC_S3
- SPIRAM_OCT
- LILYGO_TTGO_LORA32
- LOLIN_C3_MINI
- LOLIN_S2_MINI
- LOLIN_S2_PICO
- M5STACK_ATOM
- OLIMEX_ESP32_POE
- SIL_WESP32
- UM_FEATHERS2
- UM_FEATHERS2NEO
- UM_FEATHERS3
- UM_NANOS3
- UM_PROS3
- UM_TINYPICO
- UM_TINYS2
- UM_TINYS3
- UM_TINYWATCHS3
stm32:
- ADAFRUIT_F405_EXPRESS
- ARDUINO_GIGA
- ARDUINO_NICLA_VISION
- ARDUINO_PORTENTA_H7
- B_L072Z_LRWAN1
- B_L475E_IOT01A
- CERB40
- ESPRUINO_PICO
- GARATRONIC_NADHAT_F405
- GARATRONIC_PYBSTICK26_F411
- HYDRABUS
- LEGO_HUB_NO6
- LEGO_HUB_NO7
- LIMIFROG
- MIKROE_CLICKER2_STM32
- MIKROE_QUAIL
- NETDUINO_PLUS_2
- NUCLEO_F091RC
- NUCLEO_F401RE
- NUCLEO_F411RE
- NUCLEO_F412ZG
- NUCLEO_F413ZH
- NUCLEO_F429ZI
- NUCLEO_F439ZI
- NUCLEO_F446RE
- NUCLEO_F722ZE
- NUCLEO_F746ZG
- NUCLEO_F756ZG
- NUCLEO_F767ZI
- NUCLEO_G0B1RE
- NUCLEO_G474RE
- NUCLEO_H563ZI
- NUCLEO_H723ZG
- NUCLEO_H743ZI
- NUCLEO_H743ZI2
- NUCLEO_L073RZ
- NUCLEO_L152RE
- NUCLEO_L432KC
- NUCLEO_L452RE
- NUCLEO_L476RG
- NUCLEO_L4A6ZG
- NUCLEO_WB55
- NUCLEO_WL55
- OLIMEX_E407
- OLIMEX_H407
- PYBD_SF2
- PYBD_SF3
- PYBD_SF6
- PYBLITEV10
- PYBV10
- PYBV11
- PYBV3
- PYBV4
- SPARKFUN_MICROMOD_STM32
- STM32F411DISC
- STM32F429DISC
- STM32F439
- STM32F4DISC
- STM32F769DISC
- STM32F7DISC
- STM32H573I_DK
- STM32H7B3I_DK
- STM32L476DISC
- STM32L496GDISC
- USBDONGLE_WB55
- VCC_GND_F407VE
- VCC_GND_F407ZG
- VCC_GND_H743VI
rp2:
ADAFRUIT_FEATHER_RP2040
ADAFRUIT_ITSYBITSY_RP2040
ADAFRUIT_QTPY_RP2040
ARDUINO_NANO_RP2040_CONNECT
GARATRONIC_PYBSTICK26_RP2040
NULLBITS_BIT_C_PRO
PIMORONI_PICOLIPO_16MB
PIMORONI_PICOLIPO_4MB
PIMORONI_TINY2040
POLOLU_3PI_2040_ROBOT
POLOLU_ZUMO_2040_ROBOT
RPI_PICO
RPI_PICO_W
SIL_RP2040_SHIM
SPARKFUN_PROMICRO
SPARKFUN_THINGPLUS
W5100S_EVB_PICO
W5500_EVB_PICO
WEACTSTUDIO
- FLASH_2M
- FLASH_4M
- FLASH_8M
renesas-ra:
- ARDUINO_PORTENTA_C33
- EK_RA4M1
- EK_RA4W1
- EK_RA6M1
- EK_RA6M2
- RA4M1_CLICKER
- VK_RA6M5
nrf:
- ACTINIUS_ICARUS
- ARDUINO_NANO_33_BLE_SENSE
- ARDUINO_PRIMO
- BLUEIO_TAG_EVIM
- DVK_BL652
- EVK_NINA_B1
- EVK_NINA_B3
- FEATHER52
- IBK_BLYST_NANO
- IDK_BLYST_NANO
- MICROBIT
- NRF52840_MDK_USB_DONGLE
- PARTICLE_XENON
- PCA10000
- PCA10001
- PCA10028
- PCA10031
- PCA10040
- PCA10056
- PCA10059
- PCA10090
- SEEED_XIAO_NRF52
- WT51822_S4AT
mimxrt:
- ADAFRUIT_METRO_M7
- MIMXRT1010_EVK
- MIMXRT1015_EVK
- MIMXRT1020_EVK
- MIMXRT1050_EVK
- MIMXRT1060_EVK
- MIMXRT1064_EVK
- MIMXRT1170_EVK
- OLIMEX_RT1010
- SEEED_ARCH_MIX
- TEENSY40
- TEENSY41
samd:
- ADAFRUIT_FEATHER_M0_EXPRESS
- ADAFRUIT_FEATHER_M4_EXPRESS
- ADAFRUIT_ITSYBITSY_M0_EXPRESS
- ADAFRUIT_ITSYBITSY_M4_EXPRESS
- ADAFRUIT_METRO_M4_EXPRESS
- ADAFRUIT_TRINKET_M0
- MINISAM_M4
- SAMD21_XPLAINED_PRO
- SEEED_WIO_TERMINAL
- SEEED_XIAO_SAMD21
- SPARKFUN_SAMD51_THING_PLUS
Common options that are available across all esp32 targets:
BAUD={bits per second}: How fast to flash the firmware,deploymust also be set to use thisPORT={serial port}: Port the ESP is connected to,deploymust also be set to use thisdeploy: After building flash the firmware,PORTandBAUDare optional. The speed will defaultto whatever the ESP-IDF is set to and there will be an attempt at detecting the port automatically--skip-partition-resize: If you do not want the build system to resize the application partition automatically.--partition-size={app partition size}: Manually set the application partition size. This is something you wantto do when using ota firmware updates. the size of the firmware may changeso setting the application partition to be larger than what the actual firmware
size is is something I recommend doing. Having to modify the partition sizes overthe air is not possible to do.--optimize-size: The build is set to optimize the firmware for performance. If you find that space is more of an issuethen set this to get a smaller firmware size--debug: Enables debugging output from the ESP-IDF--ccache: This will speed up the build if the application partition size gets resized. It requires theccachelibrary to be installed--flash-size={4, 8, 16, 32, 64 or 128}: Sets the flash size that you have available on your ESP32--ota: Add this flag if you wanbt to do OTA updates. This creates 2 application partitions that are the same size.--dual-core-threads: (Experimental) MicroPython is written so that the user is only able to run code on a single core of the ESP32.That is very limiting. This option allows code to run on both CPU cores. Be warned this option also disables the GILso care must be given to accessing global variables. You need to put nlocks in place to keep the memory from gettingcorrupted. You do not get to decide what core to use. That is automatically done based on the load that is on the cores.--task-stack-size={stack size in bytes}: Sets the default stack size for threadsCONFIG_*={value}: You can alter the config settings of the esp-idf by using these settings. Refer to the ESP-IDF documentationfor further information--uart-repl-bitrate={baud/bitrate}: This changes the connection speed for the serial connection when using the UART REPL.This is a nice feature to use when transferring large files to the ESP32. The highestspeed I have been able to set it to is 921600, you might be able to set it higher dependingon the UART to USB bridge IC used and the type of physical connection.--enable-uart-repl={y/n}: This allows you to turn on and off the UART based REPL. You will wany to set this of you use USB-CDC or JTAG for the REPL output
Options specific to the ESP32-S3 processors:
--octal-flash: Set this if you have octal SPI flash
Options specific to the ESP32-S2, ESP32-S3, ESP32-C3 and ESP32-C6 processors:
--enable-cdc-repl={y/n}: Enable/disable REPL output over CDC on the USB pins--enable-jtag-repl={y/n}: Enable/disable REPL output over JTAG on the USB pins--custom-board-path={path to custom board}:Custom Board--toml={path to .toml file}:TOML Example
These are options that are available across all targets, boards and board variants.The global options are broken down into 2 secions
python3 make.py {build target} {build options} {target options} {{input/output} {other}}DISPLAY={ic model or path}: Model number of the display driver that is located inapi_drivers/common_api_drivers/displayor it can be the absolute path to a custom driver you have written. This must be thepath to the folder that contains the driver files.INDEV={ic model or path}: Model number of indev driver that is located inapi_drivers/common_api_drivers/indevor it can be the absolute path to your own custom driver (with the .py extension)
The above options are able to be repeated if you want to include multiple drivers.
LV_CFLAGS="{lvgl compile options}": additional compiler flags that get passed to the LVGL build only.FROZEN_MANIFEST={path/to/manifest.py}: path to a custom frozen manifest file
Build for an ESP32-S3 processor with Octal SPIRAM and the given display and input drivers
python3 make.py esp32 BOARD=ESP32_GENERIC_S3 BOARD_VARIANT=SPIRAM_OCT DISPLAY=st7796 INDEV=gt911If you have problems on builds after the first one, you can try adding the "clean" keyword to clear out residue from previous builds.
I will provide directions on how to use the driver framework and also the drivers that are includedwith the binding in the coming weeks.
SDL fpr Unix is working properly. Make sure you review the requirements needed to compile for unix!!!The build system compiles the latest version of SDL2 so the list is pretty long for the requirements.
To build for Unix use the following build command
python3 make.py unix DISPLAY=sdl_display INDEV=sdl_pointerCouple of notes:
- DO NOT enable LV_USE_DRAW_SDL, I have not written code to allow for it's use (yet).
frommicropythonimportconst# NOQAimportlcd_bus# NOQA_WIDTH=const(480)_HEIGHT=const(320)bus=lcd_bus.SDLBus(flags=0)buf1=bus.allocate_framebuffer(_WIDTH*_HEIGHT*3,0)importlvglaslv# NOQAimportsdl_display# NOQAdisplay=sdl_display.SDLDisplay(data_bus=bus,display_width=_WIDTH,display_height=_HEIGHT,frame_buffer1=buf1,color_space=lv.COLOR_FORMAT.RGB888)display.init()importsdl_pointerimporttask_handlermouse=sdl_pointer.SDLPointer()# the duration needs to be set to 5 to have a good response from the mouse.# There is a thread that runs that facilitates double buffering.th=task_handler.TaskHandler(duration=5)scrn=lv.screen_active()scrn.set_style_bg_color(lv.color_hex(0x000000),0)slider=lv.slider(scrn)slider.set_size(300,25)slider.center()
The touch screen drivers will handle the rotation that you set to the display.There is a single caviat to this. You MUST set up and initilize the display thencreate the touch drivers and after that has been done you can set the rotation.The touch driver must exist prior to the display rotation being set.
For the ESP32 SOC's there is NVRAM that is available to store data in. Thatdata is persistant between restarts of the ESP32. This feature is pur to use tostore calibration data for the touch screen. In the exmaple below it shows howto properly create a display driver and touch driver and how to set the rotationand also the calibration storage.
importlcd_busfrommicropythonimportconst# display settings_WIDTH=const(320)_HEIGHT=const(480)_BL=const(45)_RST=const(4)_DC=const(0)_WR=const(47)_FREQ=const(20000000)_DATA0=const(9)_DATA1=const(46)_DATA2=const(3)_DATA3=const(8)_DATA4=const(18)_DATA5=const(17)_DATA6=const(16)_DATA7=const(15)_BUFFER_SIZE=const(30720)_SCL=const(5)_SDA=const(6)_TP_FREQ=const(100000)display_bus=lcd_bus.I80Bus(dc=_DC,wr=_WR,freq=_FREQ,data0=_DATA0,data1=_DATA1,data2=_DATA2,data3=_DATA3,data4=_DATA4,data5=_DATA5,data6=_DATA6,data7=_DATA7)fb1=display_bus.allocate_framebuffer(_BUFFER_SIZE,lcd_bus.MEMORY_INTERNAL|lcd_bus.MEMORY_DMA)fb2=display_bus.allocate_framebuffer(_BUFFER_SIZE,lcd_bus.MEMORY_INTERNAL|lcd_bus.MEMORY_DMA)importst7796# NOQAimportlvglaslv# NOQAlv.init()display=st7796.ST7796(data_bus=display_bus,frame_buffer1=fb1,frame_buffer2=fb2,display_width=_WIDTH,display_height=_HEIGHT,backlight_pin=_BL,# reset=_RST,# reset_state=st7796.STATE_LOW,color_space=lv.COLOR_FORMAT.RGB565,color_byte_order=st7796.BYTE_ORDER_BGR,rgb565_byte_swap=True,)importi2c# NOQAimporttask_handler# NOQAimportft6x36# NOQAdisplay.init()i2c_bus=i2c.I2C.Bus(host=0,scl=_SCL,sda=_SDA,freq=_TP_FREQ,use_locks=False)touch_dev=i2c.I2C.Device(bus=i2c_bus,dev_id=ft6x36.I2C_ADDR,reg_bits=ft6x36.BITS)indev=ft6x36.FT6x36(touch_dev)display.invert_colors()ifnotindev.is_calibrated:display.set_backlight(100)indev.calibrate()# you want to rotate the display after the calibration has been done in order# to keep the corners oriented properly.display.set_rotation(lv.DISPLAY_ROTATION._90)display.set_backlight(100)th=task_handler.TaskHandler()scrn=lv.screen_active()scrn.set_style_bg_color(lv.color_hex(0x000000),0)slider=lv.slider(scrn)slider.set_size(300,50)slider.center()label=lv.label(scrn)label.set_text('HELLO WORLD!')label.align(lv.ALIGN.CENTER,0,-50)
importlcd_busfrommicropythonimportconstimportmachine# display settings_WIDTH=const(320)_HEIGHT=const(480)_BL=const(45)_RST=const(4)_DC=const(0)_MOSI=const(11)_MISO=const(13)_SCK=const(12)_HOST=const(1)# SPI2_LCD_CS=const(10)_LCD_FREQ=const(80000000)_TOUCH_CS=const(18)_TOUCH_FREQ=const(10000000)spi_bus=machine.SPI.Bus(host=_HOST,mosi=_MOSI,miso=_MISO,sck=_SCK)display_bus=lcd_bus.SPIBus(spi_bus=spi_bus,freq=_LCD_FREQ,dc=_DC,cs=_LCD_CS,)# we are going to let the display driver sort out the best freame buffer size and where to allocate it to.# fb1 = display_bus.allocate_framebuffer(_BUFFER_SIZE, lcd_bus.MEMORY_INTERNAL | lcd_bus.MEMORY_DMA)# fb2 = display_bus.allocate_framebuffer(_BUFFER_SIZE, lcd_bus.MEMORY_INTERNAL | lcd_bus.MEMORY_DMA)importst7796# NOQAimportlvglaslv# NOQAdisplay=st7796.ST7796(data_bus=display_bus,display_width=_WIDTH,display_height=_HEIGHT,backlight_pin=_BL,color_space=lv.COLOR_FORMAT.RGB565,color_byte_order=st7796.BYTE_ORDER_RGB,rgb565_byte_swap=True,)importtask_handler# NOQAimportxpt2046# NOQAdisplay.set_power(True)display.init()display.set_backlight(100)touch_dev=machine.SPI.Device(spi_bus=spi_bus,freq=_TOUCH_FREQ,cs=_TOUCH_CS)indev=xpt2046.XPT2046(touch_dev)th=task_handler.TaskHandler()scrn=lv.screen_active()scrn.set_style_bg_color(lv.color_hex(0x000000),0)slider=lv.slider(scrn)slider.set_size(300,50)slider.center()label=lv.label(scrn)label.set_text('HELLO WORLD!')label.align(lv.ALIGN.CENTER,0,-50)
You are able to force the calibration at any time by callingindev.calibrate()regardless of whatindev.is_calibrate returns. This makes it possible to redothe calibration by either using a pin that you can check the state of or througha button in your UI that you provide to the user.
Thank again and enjoy!!
NOTE: SPI host 0 on the ESP32 is reserved for use with SPIRAM and flash.
NOT USED AT THIS TIME
Bit orders are a tuple of durations. The first 2 numbers define a bit as 0 and the second 2 define a bit as 1. Negitive numbers are the duration to hold low and positive are for how long to hold high"Res" or "Reset" is sent at the end of the data.
| Name | Bit 0 Duration 1 | Bit 0 Duration 2 | Bit 1 Duration 1 | Bit 1 Duration 2 | Res | Order |
|---|---|---|---|---|---|---|
| APA105 APA109 APA109 SK6805 SK6812 SK6818 | 300 | -900 | 600 | -600 | -800 | GRB |
| WS2813 | 300 | -300 | 750 | -300 | -300 | GRB |
| APA104 | 350 | -1360 | 1360 | -350 | -240 | RGB |
| SK6822 | 350 | -1360 | 1360 | -350 | -500 | RGB |
| WS2812 | 350 | -800 | 700 | -600 | -5000 | GRB |
| WS2818A WS2818B WS2851 WS2815B WS2815 WS2811 WS2814 | 220 | -580 | 580 | -220 | -280 | RGB |
| WS2818 | 220 | -750 | 750 | -220 | -300 | RGB |
| WS2816A WS2816B WS2816C | 200 | -800 | 520 | -480 | -280 | GRB |
| WS2812B | 400 | -850 | 800 | -450 | -5000 | GRB |
| SK6813 | 240 | -800 | 740 | -200 | -800 | GRB |
https://github.com/fabse-hack/temp_humidity_micropython_lvgl
About
LVGL module for MicroPython, customized for MicroPythonOS
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Releases
Packages0
Languages
- Python60.3%
- C39.0%
- Other0.7%