|
| 1 | +# Micropython + lvgl |
| 2 | + |
| 3 | +**Micropython bindings to LVGL for Embedded devices, Unix and JavaScript** |
| 4 | + |
| 5 | +[](https://github.com/lvgl/lv_micropython/actions/workflows/unix_port.yml) |
| 6 | +[](https://github.com/lvgl/lv_micropython/actions/workflows/stm32_port.yml) |
| 7 | +[](https://github.com/lvgl/lv_micropython/actions/workflows/ports_esp32.yml) [](https://github.com/lvgl/lv_micropython/actions/workflows/rp2_port.yml) |
| 8 | +[](https://gitpod.io/#https://github.com/lvgl/lv_micropython) |
| 9 | + |
| 10 | +To quickly run Micropython + LVGL from your web browser you can also use the [Online Simulator](https://sim.lvgl.io/). |
| 11 | + |
| 12 | +**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)** |
| 13 | + |
| 14 | +See also [Micropython + LittlevGL](https://blog.lvgl.io/2019-02-20/micropython-bindings) blog post. (LittlevGL is LVGL's previous name.) |
| 15 | +For questions and discussions - please use the forum: https://forum.lvgl.io/c/micropython |
| 16 | + |
| 17 | +Original micropython README: https://github.com/micropython/micropython/blob/master/README.md |
| 18 | + |
| 19 | +## Relationship between `lv_micropython` and `lv_binding_micropython` |
| 20 | + |
| 21 | +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. |
| 22 | +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.) |
| 23 | + |
| 24 | +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. |
| 25 | +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. |
| 26 | + |
| 27 | +## Build Instructions |
| 28 | + |
| 29 | +First step is always to clone lv_micropython and update its submodules recursively: |
| 30 | + |
| 31 | +``` |
| 32 | +git clone https://github.com/lvgl/lv_micropython.git |
| 33 | +cd lv_micropython |
| 34 | +git submodule update --init --recursive lib/lv_bindings |
| 35 | +``` |
| 36 | + |
| 37 | +Next you should build mpy-cross |
| 38 | + |
| 39 | +``` |
| 40 | +make -C mpy-cross |
| 41 | +``` |
| 42 | + |
| 43 | +Port specific steps usually include updating the port's submodules with `make submodules` and running make for the port itself. |
| 44 | + |
| 45 | +### Unix (Linux) port |
| 46 | + |
| 47 | +1. `sudo apt-get install build-essential libreadline-dev libffi-dev git pkg-config libsdl2-2.0-0 libsdl2-dev python3.8 parallel` |
| 48 | +Python 3 is required, but you can install some other version of python3 instead of 3.8, if needed. |
| 49 | +2. `git clone https://github.com/lvgl/lv_micropython.git` |
| 50 | +3. `cd lv_micropython` |
| 51 | +4. `git submodule update --init --recursive lib/lv_bindings` |
| 52 | +5. `make -C mpy-cross` |
| 53 | +6. `make -C ports/unix submodules` |
| 54 | +7. `make -C ports/unix` |
| 55 | +8. `./ports/unix/micropython` |
| 56 | + |
| 57 | +## Unix (MAC OS) port |
| 58 | + |
| 59 | +1. `brew install sdl2 pkg-config` |
| 60 | +2. `git clone https://github.com/lvgl/lv_micropython.git` |
| 61 | +3. `cd lv_micropython` |
| 62 | +4. `git submodule update --init --recursive lib/lv_bindings` |
| 63 | +5. `sudo mkdir -p /usr/local/lib/` |
| 64 | +6. `sudo cp /opt/homebrew/Cellar/sdl2/2.24.0/lib/libSDL2.dylib /usr/local/lib/` |
| 65 | +7. `sudo cp -r /opt/homebrew/Cellar/sdl2/2.24.0/include /usr/local/` |
| 66 | +8. `sed -i '' 's/ -Werror//' ports/unix/Makefile mpy-cross/Makefile` Remove -Werror from compiler parameters as Mac fails compilation otherwise |
| 67 | +9. `make -C mpy-cross` |
| 68 | +10. `make -C ports/unix submodules` |
| 69 | +11. `make -C ports/unix` |
| 70 | +12. `./ports/unix/build-standard/micropython` |
| 71 | + |
| 72 | +### ESP32 port |
| 73 | + |
| 74 | +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) |
| 75 | +ESP-IDF version needs to match Micropython expected esp-idf, otherwise a warning will be displayed (and build will probably fail) |
| 76 | +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) |
| 77 | + |
| 78 | +When using IL9341 driver, the color depth need to be set to match ILI9341. This can be done from the command line. |
| 79 | +Here is the command to build ESP32 + LVGL which is compatible with ILI9341 driver: |
| 80 | + |
| 81 | +``` |
| 82 | +make -C mpy-cross |
| 83 | +make -C ports/esp32 LV_CFLAGS="-DLV_COLOR_DEPTH=16" BOARD=GENERIC_SPIRAM deploy |
| 84 | +``` |
| 85 | + |
| 86 | +Explanation about the paramters: |
| 87 | +- `LV_CFLAGS` are used to override color depth, for ILI9341 compatibility. |
| 88 | + - `LV_COLOR_DEPTH=16` is needed if you plan to use the ILI9341 driver. |
| 89 | +- `BOARD` - I use WROVER board with SPIRAM. You can choose other boards from `ports/esp32/boards/` directory. |
| 90 | +- `deploy` - make command will create ESP32 port of Micropython, and will try to deploy it through USB-UART bridge. |
| 91 | + |
| 92 | +For more details please refer to [Micropython ESP32 README](https://github.com/micropython/micropython/blob/master/ports/esp32/README.md). |
| 93 | + |
| 94 | +### JavaScript port |
| 95 | + |
| 96 | +Refer to the README of the `lvgl_javascript` branch: https://github.com/lvgl/lv_micropython/tree/lvgl_javascript_v8#javascript-port |
| 97 | + |
| 98 | +### Raspberry Pi Pico port |
| 99 | + |
| 100 | +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: |
| 101 | + |
| 102 | +1. `git clone https://github.com/lvgl/lv_micropython.git` |
| 103 | +2. `cd lv_micropython` |
| 104 | +3. `git submodule update --init --recursive lib/lv_bindings` |
| 105 | +4. `make -C ports/rp2 BOARD=PICO submodules` |
| 106 | +5. `make -j -C mpy-cross` |
| 107 | +6. `make -j -C ports/rp2 BOARD=PICO USER_C_MODULES=../../lib/lv_bindings/bindings.cmake` |
| 108 | + |
| 109 | +#### Troubleshooting |
| 110 | + |
| 111 | +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. |
| 112 | +If the storage base is lower than the binary end, parts of the firmware will be overwritten when the micropython filesystem is initialised. |
| 113 | + |
| 114 | +## Super Simple Example |
| 115 | + |
| 116 | +First, LVGL needs to be imported and initialized |
| 117 | + |
| 118 | +```python |
| 119 | +import lvgl as lv |
| 120 | +lv.init() |
| 121 | +``` |
| 122 | + |
| 123 | +Then event loop, display driver and input driver needs to be registered. |
| 124 | +Refer to [Porting the library](https://docs.lvgl.io/8.0/porting/index.html) for more information. |
| 125 | +Here is an example of registering SDL drivers on Micropython unix port: |
| 126 | + |
| 127 | +```python |
| 128 | +# Create an event loop and Register SDL display/mouse/keyboard drivers. |
| 129 | +from lv_utils import event_loop |
| 130 | + |
| 131 | +WIDTH = 480 |
| 132 | +HEIGHT = 320 |
| 133 | + |
| 134 | +event_loop = event_loop() |
| 135 | +disp_drv = lv.sdl_window_create(WIDTH, HEIGHT) |
| 136 | +mouse = lv.sdl_mouse_create() |
| 137 | +keyboard = lv.sdl_keyboard_create() |
| 138 | +keyboard.set_group(self.group) |
| 139 | +``` |
| 140 | + |
| 141 | +Here is an alternative example, for registering ILI9341 drivers on Micropython ESP32 port: |
| 142 | + |
| 143 | +```python |
| 144 | +import lvgl as lv |
| 145 | + |
| 146 | +# Import ILI9341 driver and initialized it |
| 147 | + |
| 148 | +from ili9341 import ili9341 |
| 149 | +disp = ili9341() |
| 150 | + |
| 151 | +# Import XPT2046 driver and initalize it |
| 152 | + |
| 153 | +from xpt2046 import xpt2046 |
| 154 | +touch = xpt2046() |
| 155 | +``` |
| 156 | + |
| 157 | +By default, both ILI9341 and XPT2046 are initialized on the same SPI bus with the following parameters: |
| 158 | + |
| 159 | +- 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` |
| 160 | +- 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` |
| 161 | + |
| 162 | +You can change any of these parameters on ili9341/xpt2046 constructor. |
| 163 | +You can also initalize them on different SPI buses if you want, by providing miso/mosi/clk parameters. Set them to -1 to use existing (initialized) spihost bus. |
| 164 | + |
| 165 | +Now you can create the GUI itself: |
| 166 | + |
| 167 | +```python |
| 168 | + |
| 169 | +# Create a screen with a button and a label |
| 170 | + |
| 171 | +scr = lv.obj() |
| 172 | +btn = lv.btn(scr) |
| 173 | +btn.align_to(lv.scr_act(), lv.ALIGN.CENTER, 0, 0) |
| 174 | +label = lv.label(btn) |
| 175 | +label.set_text("Hello World!") |
| 176 | + |
| 177 | +# Load the screen |
| 178 | + |
| 179 | +lv.scr_load(scr) |
| 180 | + |
| 181 | +``` |
| 182 | + |
| 183 | +## More information |
| 184 | + |
| 185 | +More info about LVGL: |
| 186 | +- Website https://lvgl.io |
| 187 | +- GitHub: https://github.com/lvgl/lvgl |
| 188 | +- Documentation: https://docs.lvgl.io/master/get-started/bindings/micropython.html |
| 189 | +- Examples: https://docs.lvgl.io/master/examples.html |
| 190 | +- More examples: https://github.com/lvgl/lv_binding_micropython/tree/master/examples |
| 191 | + |
| 192 | +More info about lvgl Micropython bindings: |
| 193 | +- https://github.com/lvgl/lv_binding_micropython/blob/master/README.md |
| 194 | + |
| 195 | +Discussions about the Micropython binding: https://github.com/lvgl/lvgl/issues/557 |
| 196 | + |
| 197 | +More info about the unix port: https://github.com/micropython/micropython/wiki/Getting-Started#debian-ubuntu-mint-and-variants |
0 commit comments