Skip to main content

slm-dmd-linux

Spatial light modulators and DMDs that connect over HDMI or DisplayPort, driven from Python on Linux. Finds the device by the name in its EDID, opens a fullscreen window on that output with no scaling, and tells you the vertical sync each pattern went up on. X11 and Wayland.

Creator

Warwick Brown
School of Electrical and Information Engineering, University of the Witwatersrand, Johannesburg, South Africa
Email: warwickb10@gmail.com
Homepage: https://www.wits.ac.za/oclab

If you use this in published work, please cite the repository (see CITATION.cff) or acknowledge the Wits OC Lab. Pull requests are welcome.

Why not "the second monitor"

An SLM on HDMI is a monitor to the operating system. The usual approach, slmPy and others, opens a fullscreen window on screen 2. That stops working when a cable moves, a driver renumbers outputs, or the desktop is Wayland, where a program cannot pick the screen its window goes to and the compositor may scale it. It also never tells you when the pattern was actually on the panel, which is what a camera exposure has to be timed from. This package identifies the panel by its EDID, so the same config works after any replugging, and show() returns after the buffer swap with a timestamp.

Verified with a HOLOEYE PLUTO-2.1 (phase SLM) and a Texas Instruments DLP4710 EVM (binary DMD; see the lab's DLP4710-SLM for the mount) on the NVIDIA driver, under GNOME on Xorg and under COSMIC on Wayland.

Install

pip install slm-dmd-linux                # or, before the PyPI release: pip install git+https://github.com/WitsOCLab/slm-dmd-linux
slmscreen list                          # the connected outputs and their EDID names
slmscreen show "HE PLUTO-2.1" blazed period_px=16 angle_deg=45

Needs GLFW 3.4 or newer (sudo apt install libglfw3) and a GPU driver in KMS mode; on NVIDIA that is nvidia-drm.modeset=1 on the kernel command line. Turn off screen locking, idle blanking and night light for the session that drives the panel; slmscreen list warns if an output is scaled.

From Python

from slmscreen import Display, find_output, patterns

output = find_output(edid_name="HE PLUTO-2.1")
with Display("slm", output) as slm:
    frame = patterns.render("blazed", output.width, output.height, period_px=16, angle_deg=45)
    info = slm.show(frame)               # returns after the vsync it went up on: info["t_flip"]
    # settle, then trigger the camera

frame is any uint8 array of the panel's size: your own hologram, or one of the generators in slmscreen.patterns (blazed and binary gratings, Laguerre-Gauss and Lee holograms, crosshair, disc, checkerboard). For a DMD, patterns.bayer() gives an ordered-dither matrix to binarise a grey image. SimDisplay has the same interface and no window, for tests.

From MATLAB

pyenv(Version="/usr/bin/python3");
out = py.slmscreen.find_output(pyargs('edid_name', 'HE PLUTO-2.1'));
slm = py.slmscreen.Display('slm', out);
holo = uint8(mod((1:1920) * 16, 256)) .* ones(1080, 1, 'uint8');   % your hologram, 1080x1920 uint8
info = slm.show(py.numpy.array(holo));                               % MATLAB matrix to the panel
pause(0.05);                                                         % settle, then grab
slm.close();

matlab/show_hologram.m is a working script. Tested with R2026a.

Command line

Command Does
slmscreen list outputs, EDID names, geometry, scale
slmscreen show <output> <pattern> k=v ... hold a pattern until Ctrl-C
slmscreen show DP-6 hologram.npy --seconds 5 your own array from a file

Troubleshooting

  • no connected output matches: run slmscreen list; the EDID name is exactly what it prints. Two identical panels: add edid_serial.
  • Output listed with scale 1.5x: set that display to 100 % in the desktop's display settings, or every pattern is resampled.
  • Under X11 the pattern looks wrong in intensity: xrandr --output DP-6 --gamma 1:1:1 --brightness 1, and turn off night light.
  • NVIDIA, after a driver update: reboot before the window can be created.

Disclaimer

Not affiliated with or endorsed by HOLOEYE Photonics or Texas Instruments. "HOLOEYE", "PLUTO" and "DLP" are trademarks of their owners, used here only to say which devices this was tested with. The devices are driven as ordinary displays; no vendor software is used or included.

License

MIT. Copyright (c) 2026 Wits OC Lab. See LICENSE.

Acknowledgements

Written for the OC Lab optical computing rig. The DMD mount is Mitchell Cox's DLP4710-SLM.

Release files for slm-dmd-linux 0.1.0

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

Source distribution (sdist)

Source distribution for slm-dmd-linux 0.1.0
File Size Uploaded
slm_dmd_linux-0.1.0.tar.gz 19.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for slm-dmd-linux 0.1.0
File Interpreter ABI Platform
slm_dmd_linux-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 38.4 kB

Release files / slm_dmd_linux-0.1.0.tar.gz

Download URL slm_dmd_linux-0.1.0.tar.gz
Size 19.8 kB
Tags Source
SHA-256 checksum
How to use checksums
2f2566605722c509268fbdc6d41abd9a580f4079f15bce7789997861ddfe9246
BLAKE2b-256 checksum
How to use checksums
94837ecbbd1774bf2b208930e7ba6df6e3f8a852ba5aa8ff381680f22bfc0aa0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Sep 17, 2026.

Transparency log

Release files / slm_dmd_linux-0.1.0-py3-none-any.whl

Download URL slm_dmd_linux-0.1.0-py3-none-any.whl
Size 18.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2d7dba783b01046024d4ce5a5f8eb27c7f49269b3b754c3c2deebdc7d2437d0e
BLAKE2b-256 checksum
How to use checksums
78d9437ca09cc8542bf1dc689d8ee5216f9688c7e28ffe9ad1fde346d0d47d6b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Sep 17, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

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