Skip to main content

pimoroni-emu logo

pimoroni-emu

CI PyPI License Python

Desktop emulator for Pimoroni devices. Run MicroPython and Raspberry Pi apps on your desktop with simulated displays, buttons, and touch input.

Note: This is an unofficial community project and is not affiliated with or endorsed by Pimoroni.

Screenshots

Badges & displays

Tufty 2350 Badger 2350
Tufty 2350 Badger 2350

Badgeware (LED matrix)

Blinky 2350
Blinky 2350

Inky

Inky Frame 7.3" Inky Impression 5.7"
Inky Frame Inky Impression

Presto

Presto
Presto

Install

pip install pimoroni-emulator

Or from source:

git clone --recurse-submodules https://github.com/iksaif/pimoroni-emu
cd pimoroni-emulator
pip install -e ".[dev]"

Usage

# Run an app on a specific device
pimoroni-emulator --device tufty apps/tufty/hello_badge.py
pimoroni-emulator --device presto apps/presto/touch_demo.py
pimoroni-emulator --device badger apps/badger/hello_badge.py
pimoroni-emulator --device inky_frame apps/inky_frame/hello_inky.py
pimoroni-emulator --device inky_impression apps/inky_impression/hello_impression.py

# Run Blinky apps (auto-detected from path)
pimoroni-emulator apps/blinky/snake.py

# Device is auto-detected from app path
pimoroni-emulator apps/tufty/hello_badge.py

# List all supported devices
pimoroni-emulator --list-devices

# Headless mode (for CI/testing)
pimoroni-emulator --device tufty --headless --max-frames 5 app.py

# Save frames to disk
pimoroni-emulator --device presto --autosave frames/ app.py

# Enable API call tracing
pimoroni-emulator --device tufty --trace app.py

# Scale display window
pimoroni-emulator --device tufty --scale 3 app.py

Keyboard controls

  • Q / Escape - Quit
  • A, S, D, F, G - Buttons A-E (device-dependent)
  • Up / Down - UP/DOWN buttons (Tufty, Badger)
  • Mouse click - Touch input (Presto)

QwSTPad gamepad (Presto, Blinky)

When an app creates a QwSTPad instance, a clickable gamepad widget appears below the display:

  • Arrow keys - D-pad (U/D/L/R)
  • Z / X / C / V - Face buttons (A/B/X/Y)
  • = / - - Plus/Minus buttons

Running on a real Raspberry Pi with --hardware

For Inky HATs on a real Raspberry Pi, --hardware routes the emulator's framebuffer to the physical panel via the upstream inky library:

pip install 'pimoroni-emulator[hardware]'
pimoroni-emulator --device inky_impression_73 --hardware --headless main.py

--headless is recommended (and auto-enabled when no display server is available); add --trace to see every call to the real HAT (entry, args, return value, elapsed time).

Bookworm: the SPI overlay

On Raspberry Pi OS Bookworm, the default device tree reserves the SPI0 CE0/CE1 GPIOs as hardware chip-selects. On 7.3" Impression HATs that GPIO is also the BUSY pin inky.show() polls — so show() blocks forever (or returns silently with no flicker) until you free the pins.

Add dtoverlay=spi0-0cs to /boot/firmware/config.txt and reboot:

sudo cp /boot/firmware/config.txt /boot/firmware/config.txt.bak
echo "dtoverlay=spi0-0cs" | sudo tee -a /boot/firmware/config.txt
sudo reboot

Symptom if missing: with --trace, you'll see [Hardware] -> show() followed by no <- show line for minutes. The wiring on our side is fine — userspace just can't read BUSY.

Compatibility matrix

Devices

Family Device Display Resolution Library Status
Tufty Tufty 2350 TFT IPS 320x240 PicoGraphics Working
Blinky Blinky 2350 LED matrix 39x26 Badgeware Working
Presto Presto TFT IPS touch 480x480 PicoGraphics Working
Badger Badger 2350 E-ink mono 296x128 PicoGraphics Working
Inky Frame 7.3" E-ink 6-color 800x480 PicoGraphics Working
5.8" E-ink 7-color 600x448 PicoGraphics Working
4.0" E-ink 7-color 640x400 PicoGraphics Working
Inky Impression 7.3" E-ink 6-color 800x480 inky (RPi) Working
5.7" E-ink 7-color 600x448 inky (RPi) Working
4.0" E-ink 7-color 640x400 inky (RPi) Working
13.3" E-ink 6-color 1200x1600 inky (RPi) Working

Mock modules

Module Coverage Notes
picographics Good Drawing primitives, text, fonts, framebuffer
pimoroni Good Button class, RGBLED
machine Partial Pin, PWM, I2C, SPI stubs
presto Good Presto class, touch
badger2040 Good Badger2040 class
badgeware Partial Drawing API for Blinky
inky Good Inky, InkyImpression, auto-detect
inky_frame Good InkyFrame class
network / socket Good WiFi connect, sockets pass through to host
jpegdec / pngdec Good Decode via Pillow, render to framebuffer
picovector Good Vectors, polygons, .af fonts, SVG loading
qwstpad Good Gamepad input via keyboard/mouse, LED indicators
Sensors Stubs BME280, LTR559, LSM6DS3

Not yet working

Hard

  • Memory constraints - Basic heap tracking exists (--memory-tracking) via tracemalloc with CPython-to-MicroPython scaling, but it's approximate. True byte-accurate simulation would need a custom allocator.
  • I2C/SPI peripherals - Stubs return zeros. Full simulation would require modeling each breakout board's register map.

Testing

pytest tests/ -v

The test harness supports headless execution, screenshot capture, button simulation, and touch input:

from emulator.testing import DeviceTest

class TestMyApp(DeviceTest):
    device = "tufty"
    app = "apps/tufty/hello_badge.py"

    def test_display(self):
        self.run_frames(5)
        self.screenshot("output.png")

    def test_button(self):
        self.click_button("A")
        self.run_frames(3)

Architecture

emulator/
  __main__.py          # CLI entry point
  main.py              # App runner, event loop
  devices/             # Device configs (resolution, buttons, features)
  display/             # Renderers (TFT, LED matrix, e-ink)
  hardware/            # Input simulation (buttons, touch, sensors)
  mocks/               # MicroPython module replacements (~38 modules)
  testing/             # Test harness and screenshot comparison
vendor/                # Upstream submodules (read-only reference)
apps/                  # Demo applications

The emulator injects mock modules into sys.modules before running your app. Three mock profiles exist:

  • PicoGraphics - For Tufty, Presto, Badger, Inky Frame
  • Badgeware - For Blinky 2350
  • inky - For Inky Impression (Raspberry Pi)

License

MIT. See LICENSE.

Vendor submodules under vendor/ are all MIT-licensed (Pimoroni Ltd).

Metadata

Release files for pimoroni-emulator 0.5.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pimoroni-emulator 0.5.1
File Size Uploaded
pimoroni_emulator-0.5.1.tar.gz 119.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pimoroni-emulator 0.5.1
File Interpreter ABI Platform
pimoroni_emulator-0.5.1-py3-none-any.whl Python 3 none any Details

Total release size: 279.0 kB

Release files / pimoroni_emulator-0.5.1.tar.gz

Download URL pimoroni_emulator-0.5.1.tar.gz
Size 119.6 kB
Tags Source
SHA-256 checksum
How to use checksums
49e3aadabd6ec14e60549aae126bb80899478ce4f267bb03c4d7c3590f86bc69
BLAKE2b-256 checksum
How to use checksums
4b484087debaedb7f3128d1def2c12825c9ee1916a6a0d591b32ca0f5bcf2d8b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 15, 2026.

Transparency log

Release files / pimoroni_emulator-0.5.1-py3-none-any.whl

Download URL pimoroni_emulator-0.5.1-py3-none-any.whl
Size 159.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8655697010423f7aff0e725915009505788108c5ed64fb64bad6ff0f4eb0f799
BLAKE2b-256 checksum
How to use checksums
1a4c95c92fdfddcbf6dd9b7b108cebdb1fd632c24bce5ac3b8461df0d9df5901
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 15, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.5.1 This release

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page