197 lines
8.8 KiB
Markdown
197 lines
8.8 KiB
Markdown
# Micropython + lvgl
|
|
|
|
**Micropython bindings to LVGL for Embedded devices, Unix and JavaScript**
|
|
|
|
[](https://github.com/lvgl/lv_micropython/actions/workflows/unix_port.yml)
|
|
[](https://github.com/lvgl/lv_micropython/actions/workflows/stm32_port.yml)
|
|
[](https://github.com/lvgl/lv_micropython/actions/workflows/ports_esp32.yml) [](https://github.com/lvgl/lv_micropython/actions/workflows/rp2_port.yml)
|
|
[](https://gitpod.io/#https://github.com/lvgl/lv_micropython)
|
|
|
|
To quickly run Micropython + LVGL from your web browser you can also use the [Online Simulator](https://sim.lvgl.io/).
|
|
|
|
**For information about Micropython lvgl bindings please refer to [lv_binding_micropython/README.md](https://github.com/lvgl/lv_binding_micropython/blob/master/README.md)**
|
|
|
|
See also [Micropython + LittlevGL](https://blog.lvgl.io/2019-02-20/micropython-bindings) blog post. (LittlevGL is LVGL's previous name.)
|
|
For questions and discussions - please use the forum: https://forum.lvgl.io/c/micropython
|
|
|
|
Original micropython README: https://github.com/micropython/micropython/blob/master/README.md
|
|
|
|
## Relationship between `lv_micropython` and `lv_binding_micropython`
|
|
|
|
Originally, `lv_micropython` was created as an example of how to use [lv_binding_micropython](https://github.com/lvgl/lv_binding_micropython) on a Micropython fork.
|
|
As such, we try to keep changes here as minimal as possible and we try to keep it in sync with Micropython upstream releases. We also try to add changes to `lv_binding_micropython` instead of to `lv_micropython`, when possible. (for example we keep all drivers in `lv_binding_micropython`, the ESP32 CMake functionality etc.)
|
|
|
|
Eventually it turned out that many people prefer using `lv_micropython` directly and only a few use it as a reference to support LVGL on their own Micropython fork.
|
|
If you are only starting with Micropython+LVGL, it's recommended that you use `lv_micropython`, while porting a Micropython fork to LVGL is for advanced users.
|
|
|
|
## Build Instructions
|
|
|
|
First step is always to clone lv_micropython and update its submodules recursively:
|
|
|
|
```
|
|
git clone https://github.com/lvgl/lv_micropython.git
|
|
cd lv_micropython
|
|
git submodule update --init --recursive lib/lv_bindings
|
|
```
|
|
|
|
Next you should build mpy-cross
|
|
|
|
```
|
|
make -C mpy-cross
|
|
```
|
|
|
|
Port specific steps usually include updating the port's submodules with `make submodules` and running make for the port itself.
|
|
|
|
### Unix (Linux) port
|
|
|
|
1. `sudo apt-get install build-essential libreadline-dev libffi-dev git pkg-config libsdl2-2.0-0 libsdl2-dev python3.8 parallel`
|
|
Python 3 is required, but you can install some other version of python3 instead of 3.8, if needed.
|
|
2. `git clone https://github.com/lvgl/lv_micropython.git`
|
|
3. `cd lv_micropython`
|
|
4. `git submodule update --init --recursive lib/lv_bindings`
|
|
5. `make -C mpy-cross`
|
|
6. `make -C ports/unix submodules`
|
|
7. `make -C ports/unix`
|
|
8. `./ports/unix/micropython`
|
|
|
|
## Unix (MAC OS) port
|
|
|
|
1. `brew install sdl2 pkg-config`
|
|
2. `git clone https://github.com/lvgl/lv_micropython.git`
|
|
3. `cd lv_micropython`
|
|
4. `git submodule update --init --recursive lib/lv_bindings`
|
|
5. `sudo mkdir -p /usr/local/lib/`
|
|
6. `sudo cp /opt/homebrew/Cellar/sdl2/2.24.0/lib/libSDL2.dylib /usr/local/lib/`
|
|
7. `sudo cp -r /opt/homebrew/Cellar/sdl2/2.24.0/include /usr/local/`
|
|
8. `sed -i '' 's/ -Werror//' ports/unix/Makefile mpy-cross/Makefile` Remove -Werror from compiler parameters as Mac fails compilation otherwise
|
|
9. `make -C mpy-cross`
|
|
10. `make -C ports/unix submodules`
|
|
11. `make -C ports/unix`
|
|
12. `./ports/unix/build-standard/micropython`
|
|
|
|
### ESP32 port
|
|
|
|
Please run `esp-idf/export.sh` from your ESP-IDF installation directory as explained in the [Micropython ESP32 Getting Started documentation](https://docs.espressif.com/projects/esp-idf/en/stable/esp32/get-started/#get-started-export)
|
|
ESP-IDF version needs to match Micropython expected esp-idf, otherwise a warning will be displayed (and build will probably fail)
|
|
For more details refer to [Setting up the toolchain and ESP-IDF](https://github.com/lvgl/lv_micropython/blob/master/ports/esp32/README.md#setting-up-the-toolchain-and-esp-idf)
|
|
|
|
When using IL9341 driver, the color depth need to be set to match ILI9341. This can be done from the command line.
|
|
Here is the command to build ESP32 + LVGL which is compatible with ILI9341 driver:
|
|
|
|
```
|
|
make -C mpy-cross
|
|
make -C ports/esp32 LV_CFLAGS="-DLV_COLOR_DEPTH=16" BOARD=GENERIC_SPIRAM deploy
|
|
```
|
|
|
|
Explanation about the parameters:
|
|
- `LV_CFLAGS` are used to override color depth, for ILI9341 compatibility.
|
|
- `LV_COLOR_DEPTH=16` is needed if you plan to use the ILI9341 driver.
|
|
- `BOARD` - I use WROVER board with SPIRAM. You can choose other boards from `ports/esp32/boards/` directory.
|
|
- `deploy` - make command will create ESP32 port of Micropython, and will try to deploy it through USB-UART bridge.
|
|
|
|
For more details please refer to [Micropython ESP32 README](https://github.com/micropython/micropython/blob/master/ports/esp32/README.md).
|
|
|
|
### JavaScript port
|
|
|
|
Refer to the README of the `lvgl_javascript` branch: https://github.com/lvgl/lv_micropython/tree/lvgl_javascript_v8#javascript-port
|
|
|
|
### Raspberry Pi Pico port
|
|
|
|
This port uses [Micropython infrastructure for C modules](https://docs.micropython.org/en/latest/develop/cmodules.html#compiling-the-cmodule-into-micropython) and `USER_C_MODULES` must be given:
|
|
|
|
1. `git clone https://github.com/lvgl/lv_micropython.git`
|
|
2. `cd lv_micropython`
|
|
3. `git submodule update --init --recursive lib/lv_bindings`
|
|
4. `make -C ports/rp2 BOARD=PICO submodules`
|
|
5. `make -j -C mpy-cross`
|
|
6. `make -j -C ports/rp2 BOARD=PICO USER_C_MODULES=../../lib/lv_bindings/bindings.cmake`
|
|
|
|
#### Troubleshooting
|
|
|
|
If you experience unstable behaviour, it is worth checking the value of *MICROPY_HW_FLASH_STORAGE_BASE* against the value of *__flash_binary_end* from the firmware.elf.map file.
|
|
If the storage base is lower than the binary end, parts of the firmware will be overwritten when the micropython filesystem is initialised.
|
|
|
|
## Super Simple Example
|
|
|
|
First, LVGL needs to be imported and initialized
|
|
|
|
```python
|
|
import lvgl as lv
|
|
lv.init()
|
|
```
|
|
|
|
Then event loop, display driver and input driver needs to be registered.
|
|
Refer to [Porting the library](https://docs.lvgl.io/8.0/porting/index.html) for more information.
|
|
Here is an example of registering SDL drivers on Micropython unix port:
|
|
|
|
```python
|
|
# Create an event loop and Register SDL display/mouse/keyboard drivers.
|
|
from lv_utils import event_loop
|
|
|
|
WIDTH = 480
|
|
HEIGHT = 320
|
|
|
|
event_loop = event_loop()
|
|
disp_drv = lv.sdl_window_create(WIDTH, HEIGHT)
|
|
mouse = lv.sdl_mouse_create()
|
|
keyboard = lv.sdl_keyboard_create()
|
|
keyboard.set_group(self.group)
|
|
```
|
|
|
|
Here is an alternative example, for registering ILI9341 drivers on Micropython ESP32 port:
|
|
|
|
```python
|
|
import lvgl as lv
|
|
|
|
# Import ILI9341 driver and initialized it
|
|
|
|
from ili9341 import ili9341
|
|
disp = ili9341()
|
|
|
|
# Import XPT2046 driver and initialize it
|
|
|
|
from xpt2046 import xpt2046
|
|
touch = xpt2046()
|
|
```
|
|
|
|
By default, both ILI9341 and XPT2046 are initialized on the same SPI bus with the following parameters:
|
|
|
|
- ILI9341: `miso=5, mosi=18, clk=19, cs=13, dc=12, rst=4, power=14, backlight=15, spihost=esp.HSPI_HOST, mhz=40, factor=4, hybrid=True`
|
|
- XPT2046: `cs=25, spihost=esp.HSPI_HOST, mhz=5, max_cmds=16, cal_x0 = 3783, cal_y0 = 3948, cal_x1 = 242, cal_y1 = 423, transpose = True, samples = 3`
|
|
|
|
You can change any of these parameters on ili9341/xpt2046 constructor.
|
|
You can also initialize them on different SPI buses if you want, by providing miso/mosi/clk parameters. Set them to -1 to use existing (initialized) spihost bus.
|
|
|
|
Now you can create the GUI itself:
|
|
|
|
```python
|
|
|
|
# Create a screen with a button and a label
|
|
|
|
scr = lv.obj()
|
|
btn = lv.btn(scr)
|
|
btn.align_to(lv.scr_act(), lv.ALIGN.CENTER, 0, 0)
|
|
label = lv.label(btn)
|
|
label.set_text("Hello World!")
|
|
|
|
# Load the screen
|
|
|
|
lv.scr_load(scr)
|
|
|
|
```
|
|
|
|
## More information
|
|
|
|
More info about LVGL:
|
|
- Website https://lvgl.io
|
|
- GitHub: https://github.com/lvgl/lvgl
|
|
- Documentation: https://docs.lvgl.io/master/get-started/bindings/micropython.html
|
|
- Examples: https://docs.lvgl.io/master/examples.html
|
|
- More examples: https://github.com/lvgl/lv_binding_micropython/tree/master/examples
|
|
|
|
More info about lvgl Micropython bindings:
|
|
- https://github.com/lvgl/lv_binding_micropython/blob/master/README.md
|
|
|
|
Discussions about the Micropython binding: https://github.com/lvgl/lvgl/issues/557
|
|
|
|
More info about the unix port: https://github.com/micropython/micropython/wiki/Getting-Started#debian-ubuntu-mint-and-variants |