In light of the COVID-19 stay-home order this week, I decided to get my MIDI keyboard working again.

(for some context on the keyboard, skip to the section at the bottom)

I had used this keyboard through the MIDI ports of a Firewire interface before, but my current computer doesn’t have any Firewire ports, and the interface that I use with it doesn’t have MIDI ports – so I had to find another way to get MIDI into my computer.

After some looking around, I found out that any Arduino with multiple Serial connections could act as a MIDI interface.

The entire build took a little over 12 hours from the beginning to getting note data into my DAW. What should I call this? MIDIduino? MIDIuino? MIDuino?

Hardware

This project is centered around an Arduino. It is worth noting that you need an Arduino that can support two different Serial streams. All Arduinos have a set of RX/TX serial pins on digital pins D0/D1, but these are usually connected in parallel with the pins used to send serial data across the USB connection. You need two streams so that you can (1) receive data from your MIDI device, and (2) send the data in 3 byte packets to your computer. I used an off-brand version of an Arduino Mega 2560 that has four sets of RX/TX pins.

The rest of the build seemed straightforward: The keyboard already outputs MIDI, so I just had to build the input circuit by following the schematic in the MIDI spec (picture attached below from their website):

To build the input circuit, I just needed a couple of resistors, a current limiting diode, and an optocoupler1

I had loads of resistors and diodes on hand from my older brother’s workshop and among the scraps collected from my EE classes, but I don’t have any optocouplers.

I tried connecting the circuit without it, and I was grabbing garbage values. Probably because the electrical signals are meant to be sent from output to input as a current loop. Other factors could have been ground loops or impedance mismatches that 115200 baud didn’t like2. Everything would be solved with the optocoupler. Who would have thought that following the offical design specification was actually recommended…

After some searching around, I found that optocouplers are commonly used to break ground loops in switching power supplies! Other than an early exposure to the engineering field, the second best thing about growing up around engineers was that I had a disgusting surplus of wall warts and power bricks that I could take apart.

After taking apart two wall warts that didn’t have optocouplers, I finally found one. It had a Cosmo C1010 . This was neither an HP 6N138 nor a Sharp PC-900, both of which were commonly used by MIDI manufacturers: The HP chip had a cascaded Darlington pair of BJT’s for a higher output gain, while the Sharp had both an amplfiier and a voltage regulator to accept a wider range of input voltages.

The Cosmo was the simplest with a single BJT, but that was enough to drive something as simple as an Arduino input pin!

As usual, I didn’t think to keep photos of things before taking them apart, so the picture below shows the supply after I had taken the photocoupler out: see the unpopulated part of the PCB right in front of the MOV oriented parallel to the camera, labelled “PC01”.

Thank you for your service.
Unrelated: the two MEMS PCBs, dollar bill

Software

The Arduino is spitting out actual MIDI frames according to the protocol, but it’s doing as a serial interface. I need my computer to see these same messages come from a MIDI interface for my DAW could use it. Here’s the software I had running:

  • Arduino IDE to write the Arduino code. It reads the MIDI frames coming into one serial connection (“Serial1” object) one message (3 bytes) at a time, and sends it to my computer over another serial connection through USB (“Serial” object). This doesn’t have to be running once the program is deployed.
  • Hairless MIDI to Serial Bridge to make a MIDI device out of the serial device.
  • loopMIDI to make the MIDI visible to other software in my computer (i.e. my DAW). The Hairless program is configured to output its MIDI data to a loopMIDI hub, which my DAW picks up.
  • Reaper as my DAW to host my VST instruments. Also comes with some nice factory plugins, like ReaControlMIDI (shown below) that includes SysEx support and a convenient monitor!

It’s worth noting that you have to prepare a couple things, depending on how your DAW handles MIDI. For Reaper:

  • Make sure your MIDI channels are set right. Every MIDI stream can send data down one or more of 16 channels. Make sure that your channels are matched across whatever your physical device is sending, what your track is receiving, as well as what your virtual instrument in that track is receiving. If you’re only using one track and one instrument, there should be an “all channels” or “omni” setting that receives messages from any channel.
  • Turn on input monitoring, and then arm your instrument track for recording! This mostly applies if you’re hosting your instrument on a recording-centric DAW; I think the monitoring functionality is assumed to be on by default for more live-performance-based DAWs.

Other Useful Reading

  • A pretty comprehensive guide that covers everything from explaining MIDI frames, to examples of Arduino code for handling messages
  • A nice Instructable that covers the use of Hairless MIDI and some test cases to send and receive to and from the computer
  • A SparkFun tutorial that about MIDI hardware only, but expains how high/low signals are sent across the current loop
  • A nice blog post comparing latency using different drivers and custom Arduino firmware.

Appendix: The Keyboard

The keyboard itself is worth writing about as well! It’s a Yamaha keybed assembly (GH88) from a cousin’s Clavinova digital piano. The lubricant used in the key action started to eat away at the keys (can someone say Sony PCB glue ?), causing them to stick when depressed. This was such a common issue for units that were produced a number of years back, that Yamaha offered to send a technician to replace the entire assembly to any Clavinova affected by this issue.

The Yamaha folks would often leave the old keybed for the piano owner to dispose, probably because it was (1) bulky for them to dispose of, (2) of little salveagable use since it lacked the rest of the piano circuitry that made it function like an actual piano, and (3) the fact that it was broken. The Clavinovas had MIDI capabilities, the circuitry that converted the keybed data into MIDI was found further downstream of the keybed.

The picture below shows the keybed’s hammer action. It’s worth noting that this keybed sends out note-off velocities (instead of commonly sending a note-on message at 0 velocity). This can be used to model some neat parts of a real piano, (damper noise for some nasty pianos?). You can also see the notorious grease in toothpaste-green seen underneath the front of the key.

A fellow named Paul Banks from the UK had decoded a good amount of the IC that packetizes the keybed sensor data into proprietary messages. Another fellow named Armin Riemer from Germany picked up this work and added enough documentation to make a working MIDI converter ! I reached out to Armin years ago, and he not only graciously provided me with the schematics for a working Yamaha-to-MIDI converter, but also offered to ship programmed microcontroller and bare PCB for me to populate3.

This keybed actually holds a fair bit of sentimental value for me, because it was the first audio- or music- related project that I was involved in. I’m glad that I can put it to use again.

Footnotes


  1. also known as an optical isolator, optoisolator, or photocoupler. These terms have roughly 4.5M, 708000, and 572000 search results, respectively, but optocoupler beat the others with 10.8M. “Optical coupler” has 13.6M results, but that sounds a little funny to me. ↩︎

  2. The baud rate to which had set the Arduino Serial connection. The MIDI protocol runs on 31250 baud, but remember that it is physically connected to my computer as a serial interface. Again, even though the messages are already encoded in MIDI, the device becomes MIDI proper after a software conversion. ↩︎

  3. At the time that Armin had reached out to me, the website post that I had linked above this footnote did not exist. Also, the PCB was put together entirely done by my brother, who was just starting college at the time. ↩︎