Run out of ISA card slots in your PC? Want a real MIDI interface instead of the toy interface that is built-into your sound card? Got a COM port handy? Then build the Serial MIDI Interface.
This page describes how to build this full-bandwidth single-port (one input and one output) MIDI interface. The interface is buffered (that is, if the PC gets behind you won't lose data) and it works in Windows 3.1 and Windows 95 using a special (and very well-behaved) device driver. The version described here uses a low-power, low-cost 20-pin Atmel microprocessor. A similar version, using a 40-pin Intel 80C51/80C31 microprocessor is described here.
Some specifications:
To build the Serial MIDI Interface, you'll need the following parts. Most of these parts are available from electronics distributors such as Digi-Key, Marshall Electronics, Jameco, B.G. Micro, and others.
| Qty | Part Number | Description | Reference Des. |
| 1 | Cap, 33 uF, 16V, Elect. | C1, C5 | |
| 2 | Cap, 10 uF, 16V, Elect.. | C2 | |
| 2 | Cap, 22 pF, Cer. | C3, C4 | |
| 1 | Cap, 0.1 uF, Cer. | C6 | |
| 5 | 1N5817 | Diode, Schottky | D1, D2, D3, D4, D5 |
| 1 | 1N4148 | Diode, Silicon | D7 |
| 1 | 1N5232B | Diode, 5.6V Zener, 500mW | D6 |
| 2 | Connector, DIN, 5 pin, 180deg, PCB mount | J1, J2 | |
| 1 | Connector, DB-9 Female, PCB mount | P1 | |
| 1 | 2N2222A | Transistor, NPN | Q2 |
| 1 | 2N2907 | Transistor, PNP | Q1, Q3 |
| 1 | Resistor, 6.8K, 1/8W | R11 | |
| 6 | Resistor, 10K, 1/8W | R2, R3, R4, R5, R12, R13 | |
| 3 | Resistor, 220, 1/8W | R1, R9, R10 | |
| 2 | Resistor, 33K, 1/8W | R6, R7 | |
| 1 | Resistor, 4.7K, 1/8W | R8 | |
| 1 | AT89C2051-12PC | Microprocessor, 128 byte RAM, 2K EEPROM | U1 |
| 1 | PC-900 | Optoisolator, Sharp | U2 |
| 1 | TL064CN | Quad Opamp | U3 |
| 1 | Crystal, 12 MHz | Y1 |
Depending on your available resources, you have several choices for the microprocessor, in decending order of preference:
![[Serial MIDI Schematic]](smidia.gif)
Figure 1. Serial MIDI Interface Schematic
Click on this image to see a larger, printable version.
If you can't find the Sharp PC-900 opto-isolator, substitute the more common 6N138. It uses a different pinout, so you'll need to connect it like this:
![[6N138]](../6n138.gif)
I also have a quantity of PC-900s available. Order here.
Remove U1, U2, and U3 from the board. You did socket them, didn't you? Connect the board to a serial port. Run HyperTerminal or some other terminal program and select the COM port that is attached to the interface. Measure the voltage (from ground) at U1 pin 20, U2 pin 6, and U3 pin 4. In each case it should be between +5 and +6 volts. Likewise, measure the voltage at U3 pin 11. It should be between -5 volts and -15 volts. Exit the terminal program and disconnect the interface from the computer.
If all is well, install the ICs and reconnect the interface. Exit Windows into DOS. Run the supplied test program, SERTEST.EXE. The program accepts two optional parameters, the COM port (1, 2, 3, etc.) and the IRQ. If your interface is not connected to COM2, you will have to specify the COM port (and possibly IRQ, if the COM port is using a non-standard setting). Run the program from a DOS prompt (not in a Windows DOS box). The program should locate the interface and report the I/O port and IRQ. Then, connect a MIDI cable between the MIDI input and output connectors and type some characters on the PCs keyboard. The program will send each byte out the MIDI output and display whatever is received. If everything is working, you should see what you type on the keyboard. Congratulations!
If things are not working, try the following steps:
Once you have the interface working using SERTEST, you are ready to install the Windows device driver and start using your new interface.
To install the driver in Windows 95:
To install the driver in Windows 3.1:
Once the driver is installed and Windows has restarted, run a Windows MIDI application (a good test program is MidiSpy--an example program from Maximum MIDI: Music Applications in C++. You can download the program as part of the book's demo here.) The program should list "SERMIDI In" as an input device and "SERMIDI Out" as an output device. Make sure the interface is connected to the proper COM port and select these two MIDI ports as active devices. Using the program, check to see that MIDI is properly received and sent using the interface.
That's all there is to it.
The interface performs a simple function--simple to name, that is. Its sole function in the universe is to convert between two serial baud rates, 31,250 baud (MIDI) and 38,400 (PC). If the 8051 microprocessor had two serial ports this would be a trivial task. (For the purposes of this discussion, the Atmel AT89C2051 is identical in operation to the Intel 8051 series of microprocessors). By setting one serial port to 31,250 baud and the other one to 38,400 baud and sending bytes received by one using the other, the job would be done.
But this won't work using an 8051. Some of you in the audience might be thinking one or both of the following questions. If an 8051 can't do it, why not find some other chip that will? The PC has a serial port, MIDI is a serial protocol, can't you just set the PC to 31,250 baud and be done with it?
Two answers: cost, and no. While there are microprocessors out there that have two (or even more) serial ports, they are all much more expensive (and more rare) than an 8051. There are other single-serial-port microprocessors that could do the job as well as (that is, no worse than) the 8051, but the author finds that MIDI is very easy to implement using this device.
The PC's serial port cannot be programmed to work at the MIDI baud rate. Because it is implemented using integer divisors, the timing crystal that is used on PCs means that the serial port can go 19,200 baud or 38,400 baud, but never 31,250 baud.
Thus, a way had to be found to implement a second serial port using software in the 8051. This serial port runs at 38,400 baud and operates using a fancy 25-state state machine. (A state machine is a software scheme where the microprocessor jumps from state to state in response to external and internal events.) Each state in the code is carefully timed so that all of the processes can occur without skipping a beat.
The interface uses a handshake algorithm to pace the transfer of data between the microprocessor and the PC. For example, if the PC has a byte for the interface, it asks the interface if it can accept a byte for MIDI output by pulsing the PCRTS line low (/RTS). The interface might not be able to accept another byte if it is in the middle of sending one already. When it can accept a byte, the interface responds by toggling the state of the IFCTS signal (CTS). In response, the PC sends the byte to the interface.
The reverse process is similar. If the interface has a byte to send to the PC (i.e., recieved MIDI data), it toggles the state of the IFRTS signal (DSR). If the PC is not busy (i.e, performing disk I/O or some other non-interruptable process), it responds by pulsing PCCTS low (/DTR). The interface can then send the serial data to the PC.
The PCRTS and PCCTS are inputs to the interface. They are both normally high and only pulse low for very short durations. These signals are designed to function this way because they also serve to provide power for the interface.
Some PC serial ports, especially those found on laptops, are heavily filtered to reduce EMI emissions. This filtering slows the rise and fall times of signals that the interface can process. To ensure that the Serial Port MIDI Interface will work with these slower rise-time COM ports, the driver measures the minimum pulse width that the port can handle and adjusts itself accordingly.
For most computers, that's all you need to know to use the Serial Port MIDI Interface. But there are a few computers (notably some Compaq laptops and Gateway 2000 systems) that don't behave as expected. These systems often have non-standard serial hardware and custom VxDs to handle this oddball hardware. As a result, you may experience some problems using the interface on these systems.
If you do, try adding the following line to your system.ini file. This applies to both Windows 3.1 and Windows 95. In the [SERMIDI] section, add the line:
[SERMIDI]
AlwaysUseIrq=1
This will change certain driver behaviors and allow the interface to work with these systems.