Skip to main content

Desktop emulator for Pimoroni devices (Tufty, Presto, Badger, Blinky, Inky)

Project description

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).

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pimoroni_emulator-0.5.1.tar.gz (119.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pimoroni_emulator-0.5.1-py3-none-any.whl (159.4 kB view details)

Uploaded Python 3

File details

Details for the file pimoroni_emulator-0.5.1.tar.gz.

File metadata

  • Download URL: pimoroni_emulator-0.5.1.tar.gz
  • Upload date:
  • Size: 119.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pimoroni_emulator-0.5.1.tar.gz
Algorithm Hash digest
SHA256 49e3aadabd6ec14e60549aae126bb80899478ce4f267bb03c4d7c3590f86bc69
MD5 f2dc36a5d57040aaabf18d182c6b6f03
BLAKE2b-256 4b484087debaedb7f3128d1def2c12825c9ee1916a6a0d591b32ca0f5bcf2d8b

See more details on using hashes here.

Provenance

The following attestation bundles were made for pimoroni_emulator-0.5.1.tar.gz:

Publisher: release.yml on iksaif/pimoroni-emu

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pimoroni_emulator-0.5.1-py3-none-any.whl.

File metadata

File hashes

Hashes for pimoroni_emulator-0.5.1-py3-none-any.whl
Algorithm Hash digest
SHA256 8655697010423f7aff0e725915009505788108c5ed64fb64bad6ff0f4eb0f799
MD5 5404418362a380262c6270ea087803be
BLAKE2b-256 1a4c95c92fdfddcbf6dd9b7b108cebdb1fd632c24bce5ac3b8461df0d9df5901

See more details on using hashes here.

Provenance

The following attestation bundles were made for pimoroni_emulator-0.5.1-py3-none-any.whl:

Publisher: release.yml on iksaif/pimoroni-emu

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page