MT32 Clumsy MIDI Program Changer and Filter

Having used my MT32-Pi (in fluidsynth mode) with an updated Arduino MIDI Filter in the Lo-Fi Orchestra – Jupiter from The Planets I decided to combine them with my Arduino MT-32 Program Changer try to create an add-on board for my Clumsy MIDI interface to allow a self-contained unit that:

  • Can set the patch number (voice) for the MT-32 in either MT-32 or GM Synth mode.
  • Can act as a MIDI filter on the MIDI in.
  • Will allow the MIDI channel for the filter to be set.

Now this is likely to be a bit niche, and the MT-32 project has a continually evolving “control surface” that is adding additional buttons and knobs to control the synth, but I thought I’d give it a go anyway.

TL;DR: It kind or works, but there are some significant limitations at present:

  • The MT-32 only receives on 8 MIDI channels anyway (2-9 by default, but I run mine in 1-8 mode).
  • The 8MHz/3.3V Arduino Pro Mini I chose to use isn’t currently keeping up with the MIDI load from my Lo-Fi Orchestra!
  • It is 5-pin MIDI only. It won’t work alongside a USB MIDI device plugged into the MT32-Pi.

So this project documents the current hardware prototype build, but if this is to become useful, it will need some revisions!

Warning! I strongly recommend using old or second hand equipment for your experiments.  I am not responsible for any damage to expensive instruments!

If you are new to MIDI and microcontrollers, see the Getting Started pages.

Parts list

  • Raspberry Pi v3 or v4
  • Clumsy MIDI interface (will need some modifications – see below)
  • 3.3V/8MHz Arduino Pro Mini (note the limitations – this might not be fast enough!)
  • Additional 0.91″ 128×32 SSD1306 I2C display (optional)
  • 1x 4-way DIP switch
  • 2x 10kΩ “thumb adjust” potentiometers
  • Protoboard, headers, and jumper wires

The Circuit

MT32-Pi Contol_bb

Core ideas for the circuit:

  • Two potentiometers to select the Group and Sound as per the Arduino MT-32 Program Changer.
  • 4 DIP switches to choose the MIDI channel for the Arduino MIDI Filter.
  • An optional second screen for the program changer display to show the voice details.
  • Passes through the original Clumsy MIDI display.
  • Intercept the MIDI in signal from the Clumsy MIDI and passes it through the Arduino before sending it to the Raspberry Pi.
  • Include the option to disable to Arduino to Raspberry Pi serial (MIDI) link to enable the Arduino to be re-programmed.
  • Build the Clumsy in “MIDI Thru” mode so the OUT becomes a THRU socket.
  • Use a 3.3V Arduino so that the TX output is compatible with the Raspberry Pi’s 3.3V RX input.

I decided to achieve all this on an add-on board as shown above.  This will plug into the extended GPIO connector of the Clumsy MIDI with an additional connector to extend to the Clumsy MIDI’s display header.

To intercept the MIDI In signal, I noticed from the schematic and PCB that the output of the opto-isolator is pretty close to the header I’m going to add for the display extension, so I’ve opted to add in a 5-way header but link the 5th pin to the optoisolator’s output instead.

The add-on board will include an Arduino Pro Mini, which will be mounted upside down on the underside of the board in the gap left between the boards from having moved the display.

The add-on board will be shaped to go around the MIDI sockets but still connect to the full GPIO connector and the four mounting holes.

The I2C interface for the additional screen will have to link to the Arduino’s A4 and A5, which on a Pro Mini means the extra two header holes just inside the main headers (that don’t align with the rest of the holes).

In short, this is what I’m aiming for.

IMG_5016

Add-on PCB

First of all the protoboard needs to be shaped as shown below.  The resulting shape is 21×25 holes with a 9×17 hole piece removed from one side.  For me, this allowed it to clear the MIDI ports but just sit nicely on top of the capacitors.  If you end up with bigger capacitors than I used, you might need to be a bit more creative with the shape or use longer stand-offs.

One thing to watch out for (and I struggled with a little) is the alignment of the top the of PCB with the GPIO connector.  Using the Clumsy MIDI as a template might help get the holes aligned.

IMG_4978

One additional thing to do now, which I didn’t think about until much later, is creating the mounting holes.  This should be relatively easy to do by overlaying the Clumsy MIDI PCB.  The Raspberry Pi uses 2.5mm standoffs, so I’m assuming a 2.5mm drill is required for the mounting holes, but just copy the Clumsy MIDI PCB.

Another thing, again that didn’t occur to me until later on, is that I need an additional hole for A4 and A5 on the Pro Mini.  These are not aligned with the main headers so won’t align with existing holes on the board.  In the end I just cut out a larger hole to accommodate them as shown below (shown from the underside).

IMG_4983

Another “with hindsight” observation – on my final build, the bottom right mounting hole ended up underneath the additional display.  That didn’t turn out to be an issue for me, but it might be worth some test lining up to see if it works for you.

Clumsy MIDI Build

IMG_4978 - Copy

Before constructing the Clumsy MIDI interface there are several “mods” to be performed or thought about:

  • The link from the MIDI in to the Raspberry Pi GPIO 15 must be broken.  The easiest way to do this is to cut the track on the rear of the PCB that passes close to the GPIO edge of the board as shown below.

IMG_5003

  • Whilst on the topic of GPIO, we’ll be using “extended” or “stacking” headers to allow the GPIO to pass upwards to the add-on board.  You might need to do some experimenting with spacers and stand-offs to get the height just right.
  • The 0.91″ display will be replaced with a set of female headers into which a “passed through” display on the add-on board will be plugged.
  • An additional header pin will be added to also pass “up” the MIDI in signal from the optoisolator to the add-on board.  I used some of those left-over pins from cutting up female headers that I’ve used before, as shown in the photos below.  This enabled me to make a link above the PCB without needing extra holes by inserting the bent pin into the hole used by the 6-way DIP socket before soldering it down, and by bending out a pin from the 5-way female header I’m about to add, then soldering them together.
  • Build the board for “MIDI Thru” mode. This is described in the build instructions, but essentially means leaving out R1 and R5 and adding a connecting wire between the circled pads on the PCB on R1 and J4.  You can see I routed a blue wire over the top of the board as shown below.

IMG_5008

The rest of the build is pretty much as you’d expect for a normal Clumsy MIDI board.

MT32-Program Changer/Filter Add-on

Before soldering anything it is worth doing some manual placing of the components to get an idea for where everything is going.  In particular, note the orientation of the Pro Mini – i.e. programming headers on the outside.

I started by soldering the pots and switches and then linked their grounds and the ground connection of the additional display header.

NOTE: The top legs of the switches should not be soldered into holes, but bent out to remain on the top of the PCB.  I decided this after I’d started mounting it, but you’ll see in a moment why this is a useful thing to do!

Now add the pin-headers for the Pro Mini.  Don’t do what I did and forget to inset them by one hole…

Then the bent pins from the switches can be soldered onto the pin headers and the GND link from the switches soldered “through” the board to the GND link on the Pro Mini.

Then it is a case of starting to wire up some of the other links:

  • The pot links to A0 and A1 (pink).
  • The 3.3V “VCC” connection to the pots (orange).

Note both of these continue on the underside of the board (uninsulated in my case) as shown below.

At this point there isn’t much more that can be done until the other headers are added, so next I did some manual aligning and experimenting with standoffs and spacers to see how the add-on board would fit on the Clumsy MIDI.  Once it all looked ok, I soldered on the GPIO header.

NOTE: I only soldered a couple of the pins, so that I had the option of adjusting it later.  I ended up with just five pins soldered – the outer four and RX (GPIO15) – enough for some stability and to allow the only three connections I actually electrically need – 5V, GND and RX.

IMG_4992

Next it is time to consider the Clumsy MIDI’s display pass-through link.  This is not electrically connected to the add-on board at all, although if you recall I’ve added a 5th header pin for the MIDI In connection that will be.  I used some bent, longer male header pins to make this link.  These holes won’t line up with the add-on board if you want your GPIO to align!  So the simplest is just to bend some pins appropriately.  I’m using a spare Clumsy MIDI PCB in the photos below to show the general idea.

At this point some more connecting wires can be added, in this suggested order:

  • Raspberry Pi GPIO GND to the Pro Mini GND (solder link – top right corner of the board).
  • 5V  from the Raspberry Pi GPIO 5V to the Pro Mini “Raw” input and the additional display’s 5V pin (red).
  • MIDI In (from the header we’ve just added – the pin can be trimmed off once soldered) to Pro Mini RX (yellow).
  • Pro Mini TX to the Raspberry Pi RX GPIO 15 (yellow).

NOTE: Once I got to the point of programing the Pro Mini a few times, I decided it would be really useful to have a “disable” switch on the Pro Mini TX-GPIO link.  My initial plan was to remove the add-on board for programming, but once it is screwed together that is actually a bit of a pain, so a switch is much more useful.

If that is something you want to do, now is a good time to do it (I ended up trying to add it after having added the display – as you can see in the photo – and that wasn’t easy).

At this point we can go no further until the Pro Mini is in place, so we need to solder on the header pins for A4 and A5 and then poke them through the hole we made in the add-on board.  Then they can be bent over and soldered across to SCL/SDA on the display header, as shown with the brown wires below.

At this point I haven’t actually soldered on the Pro Mini itself.

This is probably a good time to get your multimeter out and check your connections (if you haven’t already).  Specifically check for shorts between 5V and GND and 3.3V and GND and 3.3V and 5V; and then make sure the yellow links are sound and unconnected to anything else.

I was in two minds about adding on some programming headers.  In the end I opted not to, and just rely on “holding headers in the holes by hand” to make a good enough connection to programme the board.  But that was when I had nothing poking out the side of the add-on board, and I wanted a neat edge.  As I ended up adding a switch anyway, there isn’t really anything to lose from adding programming headers too… so it’s up to you.  When I next take mine apart, I might just add some headers on anyway.

With everything ok up to this point you can solder the Pro Mini in place.  I didn’t solder every pin, just the ones needed to make connections to the add-on board – A0, A1, D3-6, RX, TX, Raw, 3.3V, two GNDs.  Recall A4 and A5 are already linked up via the brown wires at this point.

Assuming everything has gone ok so far, the only thing left to do is to add the two displays.  Note that the top display really needs a bit of insulating tape over the exposed A4/A5 links to the Pro Mini.

Putting it all together

Now, depending on how confident you’re feeling at this point, I’d recommend testing everything independently:

  1. Test the Clumsy MIDI on its own. If you have a spare display, you can plug it in, but otherwise run it without a display.  Note that you can use a jumper wire to go from the “MIDI In” header socket to the RPi GPIO RX pin to check MIDI works.  Check the following:
    1. MIDI In works.
    2. Audio output works.
    3. MIDI Thru works.
  2. Test the add-on board on its own.  Power it from the RPi GPIO connector’s 5V and GND (but don’t plug it into a Pi or the Clumsy MIDI) and load up a sketch to check the following:
    1. The pots give a good full range reading on A0 and A1.
    2. The switches are read accurately on D3 to D6.
    3. The lower display is found and works (you can try the Adafruit demo applications).
    4. Hook up the RX/TX pins via the underside header connection and the RPi GPIO connection to a MIDI module and test receiving and sending MIDI.

Only if all that works ok, then would I suggest actually plugging it all in together with the “real” code and see how it works.

Programming the Pro Mini

Before I get onto the main code, just a quick note about programming the Pro Mini.  Assuming everything goes fine with the testing, then you should be able to actually programme the Pro Mini whilst connected to the Clumsy MIDI and the Raspberry Pi, powering it via the GPIO header.

To do that, you can hook up all the standard programming connections (remembering this is a 3.3V board) apart from VCC to your programmer.  You just need to ensure that the TX link to the RPi is disabled using that switch if you installed it.

MT32-Pi Contol - Pro Mini Programming_bb

If you didn’t include a switch, then you’ll have to take the add-on board off the clumsy MIDI board and power the Pro Mini from your programmer.

If you have one of those cheap programmers that claims a switch or jumper for 5V/3.3V operation, double check the VCC level.  Mine will switch RX/TX to 3.3V but VCC remains at 5V.  In my case, I connect 5V to the GPIO header 5V connection, which in turn powers the Pro Mini via the Raw input.  All other connections go to the programming header as normal.

The Code

Most of the code we’ve already met before. It is a combination of the following projects:

With a bit of extra glue to read the switches and turn it into a MIDI channel.  The switches will encode the channel in binary, being able to represent the numbers 0 to 15.  In use of course, the MIDI channel numbers are actually this plus one.  So switches set to binary 0000 is MIDI channel 1.  Switches set to binary 0111 (i.e. decimal 7) is MIDI channel 8, and so on.

The key decisions centre around the scheduling of reading and acting on the pots and switches, updating the display, and ensuring the MIDI filtering is running as fast as possible.

In the end I opted for a “state” counter in the main loop and schedule IO events on specific values for state as follows:

  • state = 10; read the switches
  • state = 20; read pot 1
  • state = 30; read pot 2
  • state > 0; reset state back to zero

I update the display every other time through the loop by watching the lowest bit of state.  If it is set, update the display, if it is clear don’t. This just means there is more time for MIDI handling compared to display handling.

The logic that checks if the values of the pots or switches has changed runs all the time, but of course only actually does anything significant if the values of the pots or switches change.

The other optimisation is to configure the MIDI library so that MIDI.read will return complete messages rather than single bytes.  This means that MIDI.read will keep servicing the serial ports whilst there are MIDI bytes to be read to complete a MIDI message.  Without this setting, each call to MIDI.read would only process a single byte at a time.

This seems to work fine for general use.  However, when I tested it against my Lo-Fi Orchestra – Jupiter from The Planets on the Timpani part (which is what I used the Arduino MIDI Filter – Revisited for) then it wasn’t able to keep up, so I need to do some further tweaking of the scheduling to see what can be done.

Possible optimisations include:

  • Scanning the IO even less – i.e. maybe once every 20 scans or slower.
  • Updating the display less – maybe every fourth scan or later.
  • Only reading the switches on power up.
  • Moving from Arduino digitalRead and analogRead to direct PORT manipulation.
  • Moving either the IO handling or the MIDI handling to an interrupt routine hanging off a timer, so they are independent.
  • Implement some kind of “variable scheduling” with logic that means that if no IO changes are occurring, they are scanned less, but as soon as something changes, they are scanned more.  This would make them responsive when turning pots or changing the switches, but then “fade” into the background when lots of MIDI is going on.
  • Alternatively, have some kind of “MIDI activity” indication so that when there is lots of MIDI data the IO is scanned hardly at all or even skipped completely.
  • Use more simplified MIDI handling that doesn’t require the entire MIDI library to function.
  • Switch to the 16MHz/5V Pro Mini and re-build the circuit appropriately.  The main reason for not using the 5V version in the first place was saving having to do logic level shifting on the TX-RX link from the Pro Mini to the RPi…
  • Drop the Arduino completely and using a more powerful board (e.g. the Trinket M0 or similar).

And of course, it isn’t impossible that the IO handling could eventually be incorporated into the MT32-Pi build itself as the built-in control surface matures.  But as I read things, this is aiming to replicate the original MT32 physical interface, whereas I particularly wanted two-pots: one for group and one for sound.

So at this point in time, this is a work in progress, but feel free to play.

Find it on GitHub here.

Closing Thoughts

There is still a fair bit to do, but the general hardware build is probably largely there now (unless I change microcontroller).  I’m largely pleased with the concept, but the performance is disappointing at the moment.  I was really hoping it would simply replace the extra Arduino I used in the LoFiOrchestra Jupiter, but it’s not ready for that yet.

In terms of enhancements, there are a few I’m thinking about:

  • I did wonder about including a visible MIDI indicator LED.  I might still do this, but for this first version, what I have is ok.
  • It might also be useful to have a switch that would get the Arduino to send the magic MIDI messages to the MT32 that tell it to change synth mode.  Then it could either be the MT32 or a FluidSynth GM module depending on the setting of this switch.
  • It would be nice for the Arduino to have a GM mode too, so that if the MT32-Pi is running in GM mode, the voices displayed on the second screen are GM voice names not MT-32 names!

Kevin

Leave a comment