Pydisplay
Display, touch and encoder drivers for MicroPython, CircuitPython and Python
Install / Use
/learn @PyDevices/PydisplayREADME
|
|
|
|-------------------------|--------------------------------|
| @peterhinch's active.py | @russhughes's tiny_toasters.py |
About
WARNINGS: pydisplay is currently alpha quality. Every effort has been made to test on as many platforms as possible, but I need your help and feedback to get it to its inital release. A lot has changed and I am working on catching up the documentation.
pydisplay is a universal display, event and device driver framework for multiple flavors of Python, including MicroPython, CircuitPython and CPython (big Python). It may be used as-is to create graphic frontends to your apps, or may be used as a foundation with GUI libraries such as LVGL, MicroPython-touch or maybe even a GUI framework you've been thinking of developing. Its primary purpose is to provide display and touch drivers for MicroPython, but it is equally useful for developers who may never touch MicroPython.
It is important to note that pydisplay is meant to be a foundation for GUI libraries and is not itself a GUI library. It doesn't provide widgets, such as buttons, checkboxes or sliders, and it doesn't provide a timing mechanism. You will need a GUI library to provide those if necessary, although many apps won't need them. (There is a cross-platform repository multimer you can use if you want to used scheduled interrupts. It works with CPython and MicroPython, but doesn't work with CircuitPython. You can also use asyncio for timing.)
Key Features
- May be used without additional libraries to add graphics capabilities to MicroPython, CircuitPython and CPython, with a consistent API across them all.
- Enables moving from one platform to another, for example MicroPython on ESP32-S3 to CPython on Windows without changing your code. Do your graphics development on your desktop, laptop or ChromeBook and then move to a microcontroller when you are ready to interface with your sensors and devices. CPython has much better error messages than MicroPython making it easier to troubleshoot when things go wrong!
- Built around devices available on microcontrollers but not necessarily available on desktop operating systems. For instance, rotary encoders and mouse scroll wheels show up as the same device type and yield the same events. Touchscreens on microcontrollers yield the same events as mice on desktops. Likewise with keypads / keyboards.
- Easily extensible. Use the primitives provided by pydisplay and add your own libraries, classes and functions to have even greater functionality.
- Provides several built-in color palettes and a mechanism to generate your own palettes.
- Lots of examples included, whether developed specifically for pydisplay or ported from Russ Hughes's st7789py_mpy. Also works with all of the examples from Peter Hinch's MicroPython GUI libraries MicroPython-Touch and Nano-GUI on MicroPython.
- Support MicroPython on microcontrollers and on Unix(-like) operating systems.
- On MicroPython, can be configured to work with kdschlosser's lvgl_micropython bus drivers, which are very fast bus drivers written in C.
- Works with CircuitPython's FourWire and ParallelBus bus drivers, as well as FrameBufferDisplay based interfaces such as dotclockframebuffer, usb_video and rgbmatrix
Getting Started
This section is under construction. For now, see [Getting Started]docs/getting_started.md) for more information.
Running your first app
You will need to import the path.py file before running any of the examples.
On desktop operating systems, cd into the mp directory (or wherever you have the files staged) and type:
python3 -i path.py
or
micropython -i path.py
On microcontrollers, either add the following to your boot.py (MicroPython) or code.py (CircuitPython), or simply import it at the REPL before importing your desired app:
import lib.path
The examples directory will be on the system path, so to run an app from it, you just need to type:
import calculator # substitute `calculator` with the file OR directory you want to run, omitting the .py extension
To run any of the examples from MicroPython-Touch (remember, its for MicroPython only) type:
import gui.demos.various # substitute `various` with the file you want to run, omitting the .py extension
API
Where possible, existing, proven APIs were used.
- There are currently 5 display classes, and hopefully another
EPaperDisplaydisplay class will be added soon, although I will need help from the community for this.- BusDisplay is for microcontrollers, both on MicroPython and CircuitPython. CircuitPython provides the required bus drivers, as mentioned elsewhere in this README, but MicroPython doesn't have display bus drivers. The buses packages are included with the installer. It is my hope that community members will create other C bus drivers similar to @kdschlosser's bus drivers in lvgl_micropython.
- SDL2Display - the preferred class for desktop operating systems as it is faster than PGDisplay. It uses an SDL
texturein place of an LCD's Graphics RAM (GRAM). - PGDisplay - an optional class for desktop operating systems. It uses a pygame
surfacein place of an LCD's GRAM. It can be benificial in a couple of instances:- SDL2Display "glitches" on my ChromeBook, but PGDisplay doesn't
- On Windows, it is easier to install PyGame than SDL2
- SDL2Display - the preferred class for desktop operating systems as it is faster than PGDisplay. It uses an SDL
- FBDisplay works with CircuitPython framebufferio.FramebufferDisplay objects, such as dotclockframebuffer (RGB displays), usb_video and rgbmatrix. (usb_video may be the coolest thing you can do with displaysys, although I'm not sure how practical or useful it is. It allows your board to function as a webcam, even without a camera, and to render the display through USB to any application on your host PC that can open a webcam! My Windows machine sees it as an unsupported device, so it will not work, but it does work on my ChromeBook. Currently it is limited to RP2040 only and is hardcoded to a 128 x 96 resolution, but that likely will change. See the screen capture and the board_config.py for more details.)
- JNDisplay for Jupyter Notebooks. No input devices are currently supported.
- PSDisplay for PyScript. Only touchscreens are currently supported.
- BusDisplay is for microcontrollers, both on MicroPython and CircuitPython. CircuitPython provides the required bus drivers, as mentioned elsewhere in this README, but MicroPython doesn't have display bus drivers. The buses packages are included with the installer. It is my hope that community members will create other C bus drivers similar to @kdschlosser's bus drivers in lvgl_micropython.
- Names of events and Devices in eventsys are taken from PyGame and/or SDL2 to keep the API consistent.
- All drawing targets, sometimes referred to as
canvasin the code, may be written to using the API from MicroPython's framebuf.FrameBuffer API- CPython and CircuitPython don't have a
framebufmodule that is API compliant with MicroPython'sframebuf, so framebuf.py is provided for those platforms. It is not used in MicroPython unless framebuf wasn't compiled in. - A
graphicsmodule is provided that subclassesFrameBuffer(either built-in or from framebuf.py) and provides additional drawing tools, such asround_rect. All methods in graphics return an Area object with x, y, w and h attributes describing a bounding box of what was changed. This can be used by applications to only update the part of the display that needs it. That functionality is implemented in DisplayBuffer and will likely be required by EPaperDisplay when it is implemented. - Canvases include, but are not limited to, the display itself, framebuf bytearrays, bmp565 (16-bit Windows Bitmap files) and displaybuf.DisplayBuffer objects.
- displaybuf.DisplayBuffer implements @peterhinch's API that represents the full display as a framebuffer and allows for 4-, 8- and 16-bit bytearrays while still drawing to the screen as 16-bit. It is required for
MicroPython-Touchand is very useful outside of that library as well, especially when memory is constrained.
- CPython and CircuitPython don't have a
- Display drivers for MicroPython BusDisplay use the constructor API of CircuitPython's DisplayIO drivers. This includes rotation = 0, 90, 180, 270 instead of 0, 1, 2, 3.
- BusDisplay can communicate with the underlying bus driver using either CircuitPython's DisplayIO method calls or @kdschlosser's [lvgl_micropython] method calls.
- There are 3 primary mechanism's for fonts: the graphics.Font class, tft_text.text() and tft_write.write() methods. All 3 of these return an Area object as mentioned earlier. A fourth font mechanism called EZFont is included in the utils folder, but it doesn't return an Area object, which is why it isn't in the lib folder.
- Font is derived from Tony DiCola's 5x7 font class and reads 8x8, 8x14 and 8x16 .bin files from @spaceraces romfont repo
- .text() is written by @russhughes and uses fonts generated by his [text_font_converter](https://github.com/russhughes/
