A big screen for a Digitakt, Digitone or Model:Cycles / Model:Samples: an Android phone or tablet on a USB cable shows the device's own 128 x 64 screen, as large as the phone allows.
It needs no firmware mod. The Elektron OSes answer a screenshot request over USB MIDI (part of the SysEx RPC that Transfer uses), and the page asks for one 10 times a second (5 to 30 to choose from). It is one static web page, using Web MIDI.
Not made by or affiliated with Elektron.
Open it: https://irpina.github.io/digiscreen/ (or https://irpina.github.io/digiscreen/?demo for a pretend device).
- Power the device from its own supply.
- Plug it into the phone with a USB-C OTG cable or adapter.
- Close Transfer, Overbridge or any other app that holds its MIDI port.
- Open https://irpina.github.io/digiscreen/ in Chrome, tap Connect, and allow MIDI devices.
If the phone does not list the device, check the device's USB setting in its SETTINGS menu: it has to offer class-compliant USB MIDI.
Tap the screen to show or hide the bar. Full screen also turns the phone to landscape, and the page keeps the phone awake while it shows the screen. Add to Home screen installs it as an app that also works offline.
Web MIDI needs Chrome (Android or desktop) or Edge. iPhone and iPad browsers have none. The page must be served over HTTPS (or from localhost).
| device | OS | emulator | a unit |
|---|---|---|---|
| Digitakt mk1 | 1.53 | answers | answers (our Python host tool) |
| Digitakt mk1 | 1.54 | the OS lists the request | |
| Digitone mk1 | 1.43, 1.44 | answers | |
| Model:Cycles | 1.13 | answers | |
| Model:Samples | 1.13 | answers |
All five use the same request and the same answer. NOTES.md has the addresses in each OS and how they were checked.
The device answers from its MIDI task, which waits for the UI task to copy the screen. While it waits, incoming MIDI waits too (it is queued, not lost): about 12 ms per request in the emulator. So the page asks no more often than it has to. It asks at the chosen rate while the screen changes, and 4 times a second once it has stood still for two seconds. If the device follows MIDI clock or plays from a MIDI controller, keep the rate low and listen for timing changes.
If the page keeps showing a blank screen while the device's own screen is not blank, restart the device. The code allows for a rare case where every later screenshot comes back blank. It has not been seen; the page warns if it happens.
Only three read-only requests: Ping (0x01), SoftwareVersion (0x02) and
Screenshot (0x04). rpc.js refuses to build any other command, and the tests
check that it refuses the ones that write.
The framing (both ways) is F0 00 20 3C 10 00 <pack7(msg)> F7, where msg is
a u16 seq, a u16 ref (the request's seq in a response), a u8 cmd (| 0x80 in a
response) and a big-endian payload. A screenshot answer is a u8 format, a u16
width, a u16 height, a u32 length and the bitmap: each column is height/8
bytes, the bottom band first, bit k being row k of its band.
python -m http.server 8790 --directory .Then open http://localhost:8790/?demo for the built-in demo device (a
Model:Cycles main screen whose pan and level move), or without ?demo to
connect to a real one.
node --test test/*.test.mjsThe tests check the 7-bit codec, every request against the Python host tool
byte for byte, that write commands cannot be built, the decoder against the
Ping answers and screenshots captured from the emulators (test/vectors/),
and that an answer arriving in pieces is put back together.
GPL-2.0-or-later.