Controlling Musical Floppy Drives Directly via MIDI

One of my first thoughts on how to improve Moppy was to drive it directly via MIDI. At the moment, the format of serial messages sent to the drive controller is proprietary and requires using the “MoppyDesk” application on your PC to convert MIDI notes into playable pins and wave periods.

What if we can skip the PC altogether and simply plug a MIDI cable into the floppy drive controller? The goal of this experiment is just to see if this is feasible.


If I have eight musical floppy drives running already, you might be asking the question: Why rework the entire setup to run via MIDI rather than using MoppyDesk? I have a few reasons:

1. No host PC

If you set up the drives to run on an embedded system using MIDI, there’s no need for a host computer. You could drive the setup directly from a MIDI device like a digital keyboard.

2. No Moppy Software

As ubiquitous as Java is, controlling the drives with Moppy still requires you to download and compile the MoppyDesk program onto your device of choice. With class-compliant MIDI support, the drives could connect to any device that supports MIDI and start playing with no configuration necessary.

3. Direct Connections

If you can act as a native MIDI device, it also allows you to hook directly into DAW programs such as Ableton. Rather than installing third party software, emulating a MIDI port, compliling and running MoppyDesk, setting all of the parameters, and only then starting to play notes, you can set the drives as MIDI device directly and you’re off to the races!

4. No mandatory reset

This is a smaller issue, but without any other circuitry the Arduino controlling the drives automatically resets on serial connect / disconnect. This causes a hard reset of the drives, which makes an irritating noise.

Stepping Stones

What I’m doing in this post will not accomplish all of this – at least not yet. This is just a first step in the right direction.


For this experiment I’m using two microcontrollers: an Arduino Micro and an Arduino Uno. The Micro features an ATmega32U4 microcontroller, which has two available serial ports: its native USB to serial, and an on-board UART. (This is in contrast to the Uno, which has only one serial port that it also uses for USB serial communication.)

The Arduino Micro connected to the Arduino Uno controlling the floppy drives – from Test #3.

I’m using the Micro as a “MIDI to Moppy” conversion board, and the Uno as a dummy Moppy controller. In an actual setup, it’s unlikely that the Moppy driver would have enough overhead to do the math for this, at least not once you start taking into account polyphony.

I set the Micro on a solderless breadboard and connected its ‘TX’ pin (#0) to the ‘RX’ pin on the Uno (also, conveniently, pin #0) using a jumper wire.

For the first two tests both boards were connected, via USB, to my PC. For the third test the Uno was powered separately and only connected to the PC via the Micro’s serial line.

An Aside: Native USB

I understand that the Micro has the capability to act as a native USB device, and I could make it act as a native MIDI device rather than using USB to serial. For this experiment though, I wanted to keep the code for the embedded side of things simple.

Arduino Code

Let’s look at the programs running on the Arduinos.


The code for the Arduino Micro is barebones, although it does do some bit-level math which may be confusing if you’re never seen it before. I’d recommend reading this tutorial on the MIDI protocol.

First, the program checks if a new serial byte is available, and if so it checks if that byte is the start of a MIDI message. If the message is either a “Note On” or “Note Off” message, the program waits for the next two bytes to arrive (note # and velocity), builds a new Moppy-formatted message, and then sends the Moppy message over the second serial port.

The sketch uses a “MIDItoMoppy” library that I’ve been working on in my spare time. The library is intended to convert MIDI notes into the “micro-periods” used by Moppy. It’s still in the early stages (at the moment it’s just a glorified lookup table), but both the ‘getPin()’ and ‘getPeriod()’ functions work – which is all that this program needs.

If you wanted to replicate this without the library, all you would need is an array of the stepper motor pins (corresponding to channels) and an array of the microsecond periods adjusted to the Moppy interrupt resolution you’re using. Look at the MoppyDesk source code for reference.

Here is the Micro’s sketch in its entirety. “Serial” is the USB to serial port, while “Serial1” is the board’s UART, connected to the Uno.


The Uno code is far simpler. I’m not driving any floppy drives, I just want to see if the Arduino successfully received the serial data.

This sketch checks to see if 3 bytes have been received, and if so it prints the pin number and the combined 16-bit wave period.

Commence Testing Protocol!

Test #1: One MIDI Packet

Let’s start simple: what happens if we send a custom-formed MIDI packet, the results of which are predictable?

I started by opening the Arduino IDE’s serial monitor for COM7, which is my Arduino Uno. This will show me the received message confirmations.

For this test, I’m using a software called Realterm, which is perfect for debugging serial interfaces.

I connected Realterm to the Arduino Micro (COM12 at 115200 baud) and sent the following three bytes, represented in hexadecimal:

0x90 0x3C 0x3C

In MIDI, this is:

  • 0x90: Note On for Channel 1
  • 0x3C: Note 60 (Middle C)
  • 0x3C: Velocity 60

(Note that velocity is ignored by Moppy, but the third byte is needed to complete the MIDI message.)

Immediately, the Uno’s serial monitor popped up with:


Test #2: Connecting to a DAW

That was surprisingly easy! Let’s see if we can turn it up a notch. What if we send the Arduino setup some actual MIDI data?

For this test I’m using two pieces of software:

Together, the two allow you to transform MIDI data from musical software into generic serial data for other devices, like an Arduino. Check out this post for more information.

The “Digital Audio Workstation” (DAW) software I’m using is Ableton Live 9 Lite. I started loopMIDI and configured it as an output in Ableton. I then started Hairless and set the MIDI input to loopMIDI and the serial output to the Arduino Micro (COM12). Again, I’m monitoring the output of the Uno (COM7) in the Arduino IDE’s serial monitor.

Note: If you set the DAW to use ‘All MIDI Inputs’, you’ll get the signals you send to loopMIDI back from the loopMIDI input. It’s a loop, get it?

With everything connected, I played a few notes using my desktop keyboard. The result?

 Success again! Changing the MIDI channel in Ableton properly changes the Moppy pin, and note periods look accurate.

Test #3: Connecting to Musical Floppy Drives

Screw it, let’s go all in. The last two tests worked perfectly, so why not plug into the floppy drives themselves and see how it goes?

I connected the Micro to the Uno driving the floppy drives in the same way as the test board: ground to ground, Micro TX to Uno RX. I then loaded up loopMIDI, Hairless, and MoppyDesk. Here is the data path:

  1. MoppyDesk reads a MIDI file and sends properly formatted MIDI data for channels 1 through 8 to a virtual MIDI port created by loopMIDI.
  2. Hairless takes the MIDI data from loopMIDI and forwards it over a USB serial port to the Arduino Micro.
  3. The Arduino Micro transforms the MIDI data into properly formatted Moppy data and sends it to the Arduino Uno, driving the floppy drives.

With everything connected and configured I loaded a MIDI file and pressed play. The result?


The drives are successfully working over MIDI, with the PC doing no data transformations. The laptop is only being used as the MIDI source – MoppyDesk is not required at all. I also hooked up a MIDI keyboard as a source in Hairless (i.e. no MoppyDesk or loopMIDI) and could play notes successfully.

To my ears, the drives sound identical to the serial-controlled version. I tried out a few other songs, some with more complex note patterns, and I couldn’t hear any anomalies.

The above gif was made while the drives were once again playing “Cara Mia Addio”. You can vaguely see the MIDI status messages from Hairless scrolling by on the laptop’s screen in the background (the same messages as in the featured image for this post). The red light on the Arduino Micro blinks every time it sends a new packet of Moppy data to the Uno.

Known Limitations

This is mostly a proof of concept that ended up being far more successful than I anticipated. Because of that, I wanted to take a minute to point out a few of the limitations that I’m aware of (and probably even more that I’m not):

Native MIDI

A smaller issue, but one worth mentioning. I’ll need to get the Micro running as a native MIDI device in the near future, to avoid using the additional loopMIDI and Hairless software to do the packet routing.

Out of Range Notes

With the code above, the ‘getPin()’ and ‘getPeriod()’ functions return values of “0” for out of range notes. This mostly means that the slow 9600 baud serial line could potentially be clogged with extraneous data. An easy thing to check for in software, but worth noting nonetheless.

MIDI Message Support

As you can see in the Micro code above, the only messages supported are “Note On” and “Note Off”. Other MIDI messages, such as “mute all” are not, at least in that code, interpreted. So pausing or stopping a MIDI song while a note is playing will cause that note to be continuously played until another MIDI note is sent on that channel.

Blocking Message Loop

This is another smaller issue, but at the moment the “Note On” and “Note Off” modes are blocking while waiting for the full MIDI packet. The downside of this is that if a MIDI message is truncated (e.g. by disconnection), successive bytes will cause junk information to be sent to the Moppy controller.


This is the most significant limitation, and the one that will take the most work to overcome.

With the way the test code is written, the Micro isn’t keeping track of what notes are playing. So if a second note is played on a channel before the first one is muted, the second note will replace the first. More troublesome is that if the first note is then muted, the second note will stop.

The solution to this is to build some software to keep track of notes, but that’s a project for another day.


I’ll call this experiment a rousing success! Everything worked exactly as intended (that is, after I fixed an issue reading two-byte MIDI packets!). It’s not “production-ready” at this stage, but I think with a little work it’s going to be an improvement over the serial version.

I’m hoping to polish up the transformation library and publish it to Github in the near future, so keep an eye out for that and other Moppy improvements still to come.

2 thoughts on “Controlling Musical Floppy Drives Directly via MIDI”

  1. Hi! Great Job!,

    I was reading your note and looking for the “MIDItoMoppy.h” library but I can’t find it. Could you post it or send a link where I can get it?
    Do you know if the code would work with a MIDI Shield (Sparkfun) connected to an Arduino Mega 2560 with a MIDI Keyboard..?



    1. Hi Emanuel! Thanks for the kind words.

      You’re in luck! This post was written with some experimental code, but just last night I got around to publishing the first draft of the “MIDItoMoppy” library on Github. You can find it here: This is still a first draft, so it may have a few bugs that need to be ironed out.

      Check out the “HardwareSerial” example, which uses the Arduino MIDI Library. It *should* work out of the box with the Mega and a MIDI shield once you set the proper serial ports, although I don’t have the hardware to test it. Be aware that you’ll only be able to play one note at a time unless you write some code to account for collisions, though.

      Let me know if it works for you!

Leave a Reply

Your email address will not be published. Required fields are marked *