A lightweight, NumPy-free Python driver for the Pimoroni Display HAT Mini — works out-of-the-box on Raspberry Pi Zero 2 W and other resource-constrained devices.
The official displayhatmini-python library depends on NumPy, which:
- Has no prebuilt wheels for Python 3.13 on ARM
- Falls back to source compilation that takes hours on Pi Zero
- Often fails entirely due to memory constraints
This library provides a drop-in replacement using luma.lcd — a mature, lightweight display driver that works cleanly without NumPy.
- ST7789 display (320×240) via
luma.lcd - RGB LED control with PWM brightness
- Backlight control (on/off or PWM dimming)
- Four buttons with callback support
- API-compatible with the original
displayhatminilibrary - Python 3.9+ including 3.13
| Function | GPIO (BCM) |
|---|---|
| SPI MOSI | 10 |
| SPI SCLK | 11 |
| SPI CE1 (CS) | 7 |
| DC | 9 |
| Backlight | 13 |
| LED Red | 17 |
| LED Green | 27 |
| LED Blue | 22 |
| Button A | 5 |
| Button B | 6 |
| Button X | 16 |
| Button Y | 24 |
Please check official Pimoroni Display HAT Mini pinout for more information.
Enable SPI on your Raspberry Pi:
sudo raspi-config nonint do_spi 0Or add to /boot/firmware/config.txt:
dtparam=spi=onFor smooth, flicker-free backlight dimming, enable kernel PWM by adding this line to /boot/firmware/config.txt:
dtoverlay=pwm-2chan,pin2=13,func2=4Then reboot. The library will automatically use kernel PWM when available, falling back to software PWM otherwise.
Hardware fix for completely flicker-free operation: Add a 0.1µF ceramic capacitor between GPIO 13 and GND. This eliminates all brightness spikes and dips, especially noticeable at mid-range brightness levels.
sudo apt update
sudo apt install -y \
python3-pil \
python3-spidev \
python3-rpi.gpio \
fonts-dejavu-core \
libfreetype6 \
libjpeg62-turbo \
zlib1gImportant: Install fonts and freetype before creating your virtual environment, otherwise TrueType fonts won't work in Pillow.
pip install displayhatmini-liteOr for development:
git clone https://github.com/FireHawken/pimoroni-display-hat-mini-examples.git
cd pimoroni-display-hat-mini-examples
pip install -e .GPIO access requires system packages. Create your venv with:
python3 -m venv --system-site-packages .venv
source .venv/bin/activatefrom displayhatmini_lite import DisplayHATMini
from PIL import Image, ImageDraw, ImageFont
# Create display instance
display = DisplayHATMini()
# Turn on backlight
display.set_backlight(1.0)
# Set RGB LED to purple
display.set_led(1.0, 0.0, 1.0)
# Draw something
image = Image.new("RGB", (320, 240), "black")
draw = ImageDraw.Draw(image)
draw.text((10, 100), "Hello World!", fill="white")
# Send to display
display.display(image)
# Button handling
def button_callback(pin):
if not display.read_button(pin): # Button released
return
if pin == DisplayHATMini.BUTTON_A:
print("Button A pressed!")
display.on_button_pressed(button_callback)# Buttons
DisplayHATMini.BUTTON_A # GPIO 5
DisplayHATMini.BUTTON_B # GPIO 6
DisplayHATMini.BUTTON_X # GPIO 16
DisplayHATMini.BUTTON_Y # GPIO 24
# Display dimensions
DisplayHATMini.WIDTH # 320
DisplayHATMini.HEIGHT # 240| Method | Description |
|---|---|
__init__(backlight_pwm=False, spi_speed_hz=None) |
Initialize display. Set backlight_pwm=True for dimmable backlight. Default SPI speed is 80 MHz. |
set_led(r, g, b) |
Set RGB LED color (0.0–1.0 per channel) |
set_backlight(value) |
Set backlight brightness (0.0–1.0) |
display(image) |
Send PIL Image to the display |
on_button_pressed(callback) |
Register button event callback |
read_button(pin) |
Read button state (True = pressed) |
using_hardware_pwm |
Property: True if using kernel PWM for backlight |
See the examples/ directory:
hello.py— Basic display and LED testpong.py— Classic Pong game using the buttonsbacklight_pwm.py— Backlight dimming demo
When backlight_pwm=True, the library uses a 2 kHz PWM signal for smooth dimming:
- Kernel PWM (preferred): Uses
/sys/class/pwminterface — rock-solid timing, no CPU jitter - Software PWM (fallback): Uses
RPi.GPIO.PWM— may have occasional brightness fluctuations
The library automatically detects and uses kernel PWM when the overlay is enabled.
Why 2 kHz? Higher frequencies (5–10 kHz) cause the backlight to appear black at low brightness levels (below 20%). At 2 kHz, all brightness levels work correctly from 0% to 100%.
The display runs at 80 MHz SPI by default, achieving ~17 FPS for full-screen updates. If you experience display artifacts, try lowering the speed:
display = DisplayHATMini(spi_speed_hz=52_000_000) # 52 MHzReplace:
from displayhatmini import DisplayHATMiniWith:
from displayhatmini_lite import DisplayHATMiniThe main API difference: this library doesn't use a numpy buffer. Instead, pass a PIL Image directly to display().
MIT License — see LICENSE for details.