MIDI is an essential part of any serious piece of electronic music equipment. In a nutshell, MIDI is "a technical standard that describes a protocol, digital interface and connectors and allows a wide variety of electronic musical instruments, computers and other related devices to connect and communicate with one another". For example, it allows a consumer musical keyboard from one company to trigger notes or control audio within a piece of software developed by a completely different company, pretty much out-of-the-box.
You've probably seen from one of my previous blogposts that I use the MIDI messaging format to send note messages from the keyboard mechanism to the BeagleBone Black, however to make my toy piano synth fully MIDI-compatible I need to add some kind of MIDI input and output connections to the synth. In this blogpost I'm going to talk about the hardware and electronics I've used to allow MIDI messages to be sent to and from the BeagleBone Black, integrating a fully functional MIDI interface into my vintage toy synthesiser.
MIDI Hardware Transport Options
The original and most common hardware transport option for MIDI I/O is using a pair of five-pin DIN connectors, and I have planned on using this hardware transport option from the outset of this project because of the following reasons:
- They are the most common MIDI connectors found in commercial synthesisers
- They can quite simply be connected to one of the UARTs on the BeagleBone Black
- I've used MIDI-DIN connectors in past projects
A standard MIDI-DIN connector (left) and a pair of standard MIDI-DIN cables (right)
Throughout the project I have considered alternative or addition connections for sending and receiving MIDI messages, however for this project there weren't enough good reasons to use them. Other hardware transport options I had consider include the following:
- USB MIDI - MIDI can be sent over USB, and in regards to computer music it is becoming the most common hardware interface for MIDI. Most modern MIDI controllers include USB-MIDI, sometimes instead of MIDI-DIN connectors, as it allows MIDI hardware to be plugged straight into computers, however it is still not that common on commercial synthesisers. I believe that the mini USB port on the BBB can be used as a USB client port, making it a USB slave device (such as a commercial MIDI controller), however I'm not 100% sure of this as I haven't seen any examples, and I haven't had any experience with programming USB comms in Linux.
- Ethernet MIDI - MIDI can be transmitted over a network protocol such as Ethernet, and as the BBB includes a network port this would be an option for this project. However MIDI over Ethernet isn't as supported as the other options, plus I've not had as much experience with network comms compared to standard serial comms.
- Bluetooth MIDI - MIDI over Bluetooth is starting to become quite common on modern MIDI controllers that are designed to be portable and need to be wireless. However, even though it's fairly small, my vintage toy piano is a bit too bulky to be considered a 'portable' instrument, plus I'd need to attach a Bluetooth transmitter/receiver to the BBB for this option, which is a technology I've had no experience with, so it didn't make sense as a MIDI transport option for this project.
The Circuit
The circuit for the MIDI interface within my synth is made up of two separate circuits - a MIDI-in circuit and a MIDI-out circuit, which each connects a MIDI-DIN connector to a TX or RX serial port on the BBB. There are plenty of examples of these circuits and how they are connected to boards such as the BBB, and below I'm going to highlight the specific guides I used, as well as any of my own additions or changes.
MIDI-In
The guide I used for building the MIDI-in circuit was the Libre Music Production Arduino and MIDI in guide, which is fully transferable for the BBB.
The main components needed for the circuit are:
- 1 x female MIDI DIN connector
- 3 x 220 Ohm resistor
- 1 x 1N4148 diode
- 1 x 10kOhm resistor
- 1 x 6N138 optocoupler
As explained in the guide, an optocoupler is very important here as it allows the two electronic circuits (the BBB and the connected MIDI gear) to be electronically isolated from each other, which prevents the occurrence of ground loops and protects equipment from voltage spikes. Here is a breadboard diagram of the circuit from the guide that I used:
A couple of corrections and things to mention about this diagram:
- The anode of the diode should actually be connected to pin 3 of the optocoupler, not pin 4
- The viewport of the MIDI connector is from the back
- Obviously in my project this circuit is being attached to a BBB instead of an Arduino. I mention how this circuit is specifically connected to the BBB below.
MIDI-Out
The guide I used for building the MIDI-out circuit was the official Arduino MIDI guide, which again is fully transferable for the BBB.
The MIDI-out circuit is a lot simpler than the MIDI-in circuit, and it only requires the following components:
- 1 x female MIDI DIN connector
- 2 x 220 ohm resistors
Here is a diagram of the circuit from the guide that I used:
A couple of things to mention about this diagram:
- The viewport of the MIDI connector is from the front
- Again, in my project this circuit is being attached to a BBB instead of an Arduino.
The Combined Circuit
Here is a photo of the above two circuits combined onto a single piece of strip board for my project:
In the above photo, the wires at the top are going to the two MIDI-DIN connectors, and the wires on the left are going to the BBB.
Combining the two circuits into a single one has allowed me share the power and ground lines between the two, meaning I only need to use a single pair of wires from the BBB for power and ground.
You'll also notice that I've used a set of screw terminals for connecting the MIDI-DIN connectors to the circuit. I've done this so that, once everything is attached to the toy piano enclosure, I can remove this particular circuit from the piano if needed without having to remove the connectors too, or vice-versa.
Connecting to the BeagleBone Black
As mentioned above MIDI is a serial communication method, meaning that the above circuit can be simply attached to the BBB via a pair of UART pins. I'll be using UART2 for MIDI, therefore I've attached the circuit to the BBB using the following pins:
- Orange wire to BBB P9_21 pin (UART2 TXD), for sending MIDI messages from the BBB to an external device
- Green wire to BBB P9_22 pin (UART2 RXD), for receiving MIDI messages from an external device to the BBB
- Black wire to BBB P9_01 pin (a DGND pin), for allowing the MIDI circuit to be powered by the BBB
- Red wire to BBB P9_03 pin (a VDD_3V3 pin), for powering the MIDI circuit using the BBB
As per connecting the keyboard mechanism, this circuit needs to be powered by a 3.3V pin instead of 5V, as the BBB serial ports run at 3.3V.
Connections to UART 2 on the BBB
Setting the Required Serial Baud Rate in Linux
While this blogpost covers the electronics of the MIDI I/O connection within my toy piano synth, I just thought I'd briefly talk about how I successfully got MIDI messages being send from and to software running on the BBB, as this took me a little while due to the serial baud rate needed for MIDI.
MIDI communicates using a serial baud rate of 31250, which is not a standard or common baud rate. The code I've shown in a previous blogpost for setting up serial comms in Linux wouldn't work here as 31250 is not a recognised rate when using the most common method of setting up serial comms (or at least what I consider to be the common method!). After a lot of Googling I found this thread in which a very helpful man called Peter Hurley provided some example code on how to use the BOTHER method of setting a custom baud rate. Using this example code I have now replaced my serial setup code with the following in order to get work MIDI comms:
int SetupSerialPort (const char path[], int speed, bool should_be_blocking) { int fd; struct termios2 tio; // open device for read/write fd = open (path, O_RDWR); //if can't open file if (fd < 0) { //show error and exit perror (path); return (-1); } if (ioctl (fd, TCGETS2, &tio) < 0) perror("TCGETS2 ioctl"); tio.c_cflag &= ~CBAUD; tio.c_cflag |= BOTHER; tio.c_ispeed = speed; tio.c_ospeed = speed; if (ioctl( fd, TCSETS2, &tio) < 0) perror("TCGETS2 ioctl"); printf("[VB] %s speed set to %d baud\r\n", path, speed); return fd; }
Top Comments