Display Backends

PyHMI uses a pluggable backend architecture. The same UI description (PyHML) runs across all platforms. The backend determines how pixels reach the display and how input is captured.

Framebuffer

Direct Linux framebuffer access via mmap. Zero-copy pixel rendering to /dev/fb0.

SPI / LCD

CircuitPython displayio protocol for SPI LCD displays on microcontrollers.

SDL2 Emulation

Cross-platform SDL2 window for design and testing on macOS, Linux, and Windows.

Framebuffer Backend

The framebuffer backend renders directly to the Linux framebuffer device. No X11, Wayland, or graphical desktop environment is required.

Setup

from pyhmi import Application

app = Application(
    backend="fb",
    device="/dev/fb0",
    color_format="rgb565",  # or "rgb888", "grayscale"
)
app.load_scene("main.pyhml")
app.run()

Configuration

Parameter Description Default
device Framebuffer device path /dev/fb0
color_format Pixel color format Auto-detected
resolution Override display resolution Auto-detected
double_buffer Enable double buffering true

Requirements

Performance

Target: 30 FPS on Raspberry Pi 3. Double buffering reduces tearing. Partial updates supported for efficiency.

SPI / LCD Backend

The SPI backend renders to LCD displays connected via SPI bus. Designed for CircuitPython 9+ on microcontrollers.

Supported Displays

Controller Common Sizes Resolution
ST7735 0.96", 1.8" 80x160, 128x160
ST7789 1.3", 1.54", 2.0" 240x240, 240x320
ILI9341 2.2", 2.4", 2.8" 320x240, 320x480
HX8357 3.2", 3.5" 320x480, 480x320

Setup

import displayio
import board
from pyhmi import Application

displayio.release_displays()
display = displayio.Display(
    board.SCK, board.MOSI,
    data_command=board.D9,
    reset=board.D10,
)

app = Application(
    backend="spi",
    display=display,
    color_format="rgb565",
)
app.load_scene("main.pyhml")
app.run()

Requirements

Performance

Target: 15 FPS on Raspberry Pi Pico W with 240x240 display. Partial updates reduce SPI bandwidth. Use rgb565 for best performance.

SDL2 Emulation Backend

The SDL2 backend renders to a window using the SDL2 library. This is the primary development and testing backend, running on macOS, Linux, and Windows.

Setup

from pyhmi import Application

app = Application(
    backend="sdl2",
    width=320,
    height=240,
    title="PyHMI Demo",
    scale=2,  # Window scale factor
)
app.load_scene("main.pyhml")
app.run()

Configuration

Parameter Description Default
width Virtual display width 320
height Virtual display height 240
title Window title "PyHMI"
scale Window scale factor 1
fullscreen Start in fullscreen false
fps_limit Frame rate limit 60

Installation

# Install with SDL2 backend
pip install pyhmi[sdl2]

# Or install SDL2 system library first:
# macOS:  brew install sdl2
# Linux:  sudo apt install libsdl2-2.0-0
# Windows: included in wheel

Input

The SDL2 backend captures keyboard and mouse input natively. Touch input is simulated via mouse events. Use scale to enlarge the window for comfortable interaction.

Performance

Target: 60 FPS on desktop. The SDL2 backend is the fastest backend, suitable for performance testing and animation verification.

Input Backends

Input handling is also pluggable. Each display backend pairs with an appropriate input backend:

evdev

Linux input devices: touchscreen, keyboard, mouse. Paired with framebuffer backend.

tinyusb

USB HID keyboard/mouse on CircuitPython. Paired with SPI LCD backend.

SDL2 Input

Keyboard and mouse via SDL2. Paired with SDL2 emulation backend.

Backend Selection Guide

Scenario Recommended Backend
Design and prototyping SDL2 Emulation
Desktop Linux HMI Framebuffer
Raspberry Pi (headless) Framebuffer
Raspberry Pi Pico + SPI LCD SPI / LCD
Testing on macOS / Windows SDL2 Emulation
Industrial HMI (Linux) Framebuffer