Using the SLIM MIDI interface with a Raspberry PI 3 or 4

This article will show you how to properly configure the SLIM MIDI interface for your Raspberry PI3 or PI4. It is preferable that you already have a good experience with Raspberry and the Linux command line. 

Configure the SLIM MIDI interface on your Raspberry PI 3/4

The instructions below were tested with Raspberry Pi OS / Debian versions 10 and 11. If you find problems please comment below!

One important step in MIDI configuration on a Raspberry is to set the transmission speed of the serial port. MIDI connections are relatively slow compared to other digital communication protocols, such as USB or Ethernet. MIDI data is transmitted at a rate of 31.25 kilobits per second (kbps), which is equivalent to 3125 bytes per second. This speed is sufficient for transmitting the control signals and performance data typically used in music production, such as note on/off messages, pitch bend, and modulation, but it may not be sufficient for transmitting large amounts of audio or other data. 

First, you will have to make sure that no other software and the Linux console will interfere with our MIDI interface, since it uses the 2nd serial port (on a PI 3 or 4). This also applies to any Raspberry MIDI interface that use the native hat serial port, such as the Zynaptik Zynthian ones.

This can be done by using raspi-config:

  • Start raspi-config:
    sudo raspi-config.
  • Select option 3 - Interface Options.
  • Select option P6 - Serial Port.
  • At the prompt Would you like a login shell to be accessible over serial? answer 'No'
  • At the prompt Would you like the serial port hardware to be enabled? answer 'Yes'
  • Exit raspi-config

Now we have to you should have access to the MIDI port with the /dev/serial0 device, but there is still one problem: MIDI uses a baud-rate of 31250 and, some programs can only communicate with a baud-rate of 38400, which is a 'Unix standard'.

So to enable a hack that will allow a 31250 baud communication to occur when 38400 bauds is selected, we have to modify /boot/config.txt.

  • Type: sudo nano /boot/config.txt
  • Search for the line
    enable_uart=1
  • Below, add
    dtoverlay=miniuart-bt
    dtoverlay=midi-uart0
  • Type Ctrl-X and save

Reboot the Raspberry Pi for changes to take effect, and now you'll be ready to continue the configuration. Note that with this configuration onboard Bluetooth won't work anymore. 

 

Basic MIDI OUT connectivity check

To check that everything is ok, you can run this Python 3 test script:

#!/usr/bin/env python3

import serial
import time

ser = serial.Serial('/dev/serial0', baudrate=38400)
channel = 0 # this represents channel 1
note = 60 # C4
velocity = 85
note_off = 8
note_on = 9

while True:
  msg_note_on  = bytearray([(note_on << 4) | channel, note, velocity])
  msg_note_off = bytearray([(note_off << 4) | channel, note, velocity])
  print(str(hex(msg_note_on[0]))+' '+str(msg_note_on[1])+' '+str(msg_note_on[2]))
  ser.write(msg_note_on)
  time.sleep(0.5)
  ser.write(msg_note_off)
  time.sleep(0.5)

This script will play a C4 note one time per second, on the 1st MIDI channel.

If it does not work, it means:

  1. You did not follow the raspi-config procedure above
  2. Or did not add the dtoverlay line above
  3. Or you did not plug the right TRS-DIN Midi cable. Remember that it should be of Type A.

Note: if you replace 38400 with 31250 in the code above and it works, then you had a problem with the 'ddtoverlay' step.

Now if you want to do more than custom Python MIDI scripts and use many other Linux MIDI tools, you'll have to continue with the next step.

Configure the Slim MIDI port for standard linux tools

Using the 'ttymidi' program will connect this MIDI serial port with the Alsa abstraction layer. Install this version of ttymidi, since it's the only one that supports all MIDI messages like Sysex, Timings etc.

A package for the Raspberry PI OS version 11 can be downloaded here: ttymidi-rpi_0.20230220_armhf.deb

Install the package with 'sudo dpkg -i ttymidi-rpi_0.20230220_armhf.deb' and it should setup the background service, the boot files, etc. After this reboot your Raspberry.

If you prefer not to use the prebuild package, you will have to:

  • setup the boot files as show above
  • download the tool and compile it following the instruction on Github.
  • Manually run ttymidi:
    ttymidi -s /dev/serial0 -b 38400 -v

Now you can check the list of MIDI inputs and outputs of Alsa:

pi@raspberrypi:~ $ aconnect -l
client 0: 'System' [type=kernel]
    0 'Timer '
    1 'Announce '
client 14: 'Midi Through' [type=kernel]
    0 'Midi Through Port-0'
client 128: 'ttymidi' [type=user,pid=985]
    0 'MIDI out '
    1 'MIDI in '

Now you know that MIDI Out has a port number '128:0' and MIDI In '128:1'.

And you can try to play a midi file: playmidi -p 128:1 mario64.mid

 

Basic Python MIDO example

Once you have 'ttymidi' set-up, you can try to program your own MIDI controller using the best Midi library for Python: MIDO. To install Mido, type:

$ sudo pip3 install mido python-rtmidi

Then a basic program that will print incoming MIDI and pass the messages to the out port will look like:

#!/usr/bin/env python3
import mido

# yes in and out are reversed with ttymidi!
inport = mido.open_input('MIDI out')
outport = mido.open_output('MIDI in')
for msg in inport:
  print(msg)
  outport.send(msg)

Basic Python PY-MIDI example

This other example uses the py-midi library, which does not need a working 'ttymidi' program. You may need to install it with 'pip3 install py-midi'. This code prints what is received on MIDI IN, and if nothing is received during 1 second, it will output a Midi note on channel 1. 

 

#!/usr/bin/env python3
import midi
import os

conn = midi.MidiConnector('/dev/serial0', baudrate=38400, timeout=1)

note = 70
channel = 0

while True:
  msg = None
  try:
    msg = conn.read()
  except TypeError:
    print("MIDI read error")

  if msg != None:
    print(msg)
  else:
    print("Sending note")
    n = midi.NoteOn(note, 100)
    conn.write(midi.Message(n, channel = channel))
    os.system('sleep 1')
    n = midi.NoteOff(note, 100)
    conn.write(midi.Message(n, channel = channel))
    note += 1
    if note > 90:
      note = 70

Here is an example of what you should see by running this script:

Message(NoteOn(57, 40), channel=3)
Message(NoteOff(57, 0), channel=3)
Message(NoteOn(65, 35), channel=3)
Message(NoteOff(65, 0), channel=3)
Message(NoteOn(67, 43), channel=3)
Message(NoteOff(67, 0), channel=3)
Message(NoteOn(69, 98), channel=3)
Message(NoteOff(69, 0), channel=3)
Sending note
Message(ControlChange(80, 7), channel=4)
Message(ControlChange(80, 14), channel=4)
Message(ControlChange(80, 17), channel=4)
Message(ControlChange(80, 18), channel=4)
Message(ControlChange(80, 19), channel=4)
Message(ControlChange(80, 20), channel=4)
Message(ControlChange(80, 21), channel=4)
Message(ControlChange(80, 25), channel=4)
Message(ControlChange(80, 30), channel=4)
Message(ControlChange(80, 34), channel=4)
Sending note
Sending note
Sending note

Slim MIDI plus onboard Bluetooth Configuration

  • In /boot/config.txt, remove:
dtoverlay=miniuart-bt
  • And make sure you have
dtoverlay=midi-uart1
core_freq=250
core_freq_min=250
<

Best Sellers

  • Slim MIDI hat for Raspberry PI 3/4
    Regular price
    19,70€ - 28,70€
    Sale price
    19,70€ - 28,70€
  • Slim MIDI hat for Raspberry PI Zero
    Regular price
    19,70€ - 28,70€
    Sale price
    19,70€ - 28,70€
  • Bluetooth Wireless 5-pin DIN MIDI and USB adapter / MVAVE MS1
    Regular price
    24,90€
    Sale price
    24,90€
  • M-Vave Wireless Midi Controller with 4 foot switches
    Regular price
    57,90€
    Sale price
    49,90€

Leave a comment

Name .
.
Message .

Please note, comments must be approved before they are published