Is it possible to use ttymidi for an USB serial port? --- Resolved ---

EDIT: I changed the title replacing “preempt” by "“use” as a solution allows to use ttymidi in several instances to translate serial data stream into MIDI data stream

Hello,

I try to connect the very compact Open Theremin V4 to the Zynthian V2.

Open Theremin V4 is an Atmega (Arduino-like) based project but is not possible to re-programm the USB serial interface into a genuine MIDI interface.

Hence I tried to involve ttymidi but it is already used by the DIN MIDI interface and it doesn’t seem to be multi instance.

The following command seems to work
systemctl stop mod-ttymidi
ttymidi -b 115200 -s /dev/ttyUSB0

But it would be nice if it was done automatically at ttyUSB* connection.
I went through some rules and systemd service research but ended with no elegant solution…

Any Idea ?

IIRC, the Pi4 and above have four serial ports so you may have better luck with one of the other ones.

Hi Kirtai,

It is not that much about having enough serial ports. It is more about the program named “ttymidi” which changes the Serial data stream into a MIDI data stream. This program can only be used once at a time and is already taken by the DIN MIDI interface. You see…

Odd, there’s really no way to run one instance per serial port?

Still searching but currently “ttymidi -b 115200 -s /dev/ttyUSB0” without stoping existing service using ttymidi will end with an errror message.

In my use case, I am not using MIDI DIN and USB MIDI through Serial at the same time. Then a preemption could be enough: taking ttymidi from MIDI DIN at USB connection and give it back to MIDI DIN at USB disconnection.

Are you using the right /dev/ttyUSB* device?

Yes, I used “ls /dev/tty*” before to get list of serial ports.
The message I get with “ttymidi -b 115200 -s /dev/ttyUSB0” is clearly saying that ttymidi is already used.

My error, I should have used -n option to create another entry point for jack.

Effectively “ttymidi -s /dev/ttyUSB0 -b 115200 -n Open-ther-midi” doesn’t seem to generate any conflict. A new MIDI_in/out is created :

image

And MIDI stream arrives properly in the Zynthian.

Remains for me to find the right tweak for auto-start at usb connection…

1 Like

Solution:

Add 2 new rules in “/etc/udev/rules.d/99-serial-usb.rules” (create this file if it doesn’t exist)

#ttymidi at USB serial port connection
#connect
ACTION==“add”, SUBSYSTEM==“tty”, ENV{DEVNAME}==“/dev/ttyUSB[0-9]”, TAG+=“systemd”, ENV{SYSTEMD_WANTS}+=“hairlessUSBttymidi@$env{DEVNAME}.service”

#disconnect
ACTION==“unbind”, SUBSYSTEM==“usb-serial”, RUN+=“/bin/systemctl --no-block stop hairlessUSBttymidi@*.service”

***************

Create the service “/etc/systemd/system/hairlessUSBttymidi@.service”

[Unit]
Description=TTYmidi to convert USB Serial to MIDI
After=mod-ttymidi
Requires=mod-ttymidi

[Service]
Environment=HOME=/root
WorkingDirectory=/root
ExecStart=/usr/local/bin/ttymidi -b 115200 -n hairless-midi -s %I

***************

This will create a new MIDI connection each time you connect an USB serial port, very useful for Arduino experimental MIDI devices projects.