MIDI splitter with a PIC16F876
The circuit
The firmware
My first prototype
Other realizations
A possible improvement
Conclusion and acknowledgements
Introduction
The MIDI protocol is a standard which is widely used since a while in the musical field. Its goal is to let electronic instruments communicate between them. Examples include master keyboards, expanders, synthesizer, effect generators and much more.
Put on the market at the beginning of the 1980's, this system has gained a widespread diffusion thanks to its intrinsic advantages and low-cost. Some sort of MIDI interface can thus be found on almost all electronic instruments which are a little more than toys. It is an asynchronous serial communication protocol, working at a speed of 31.25 kbit/s (which is quite low for the current standards such as FireWire or USB).
From the user point of view, a MIDI interface looks like two female 5-pins DIN connectors, called IN and OUT, with very often a third one called THRU. The input port (IN) is a receiver for the messages saying which notes have to be played, and with which instruments. The output (OUT) obviously is symmetrical. To connect a keyboard equipped with a MIDI interface with a sound expander, one needs to connect the OUT port of the keyboard to the expander.
From the communication protocol point of view, commands are sent via packets (messages) formed by a header, a body and a terminator. For each physical connection, 16 channels are available for messages. For example, a musician can use a piano associated to channel 0, a violin on channel 1, a viola on channel 2, a cello on channel 3 and so on. In this way, each note played sent via the MIDI interface will be played by the right instruments depending on which channel it is used.
What we want to describe in this article is a project using a PIC16F876, able to split MIDI message on two different outputs depending on the channel. This circuit thus has one input and two outputs. For each received message, it must recognize the channel and route it following a table held in memory.
A similar project is useful for those like me, owning several MIDI instruments but a simple computer interface with only one physical output. This circuit in fact can be used to control independently two devices.
The circuit
Since we chosen a flexible 4 MHz operated PIC, the resulting circuit is quite simple, since all the dirty work is done by the firmware. Watching the schematic circuit, it can be noted that the MIDI IN input is directly used to fed an optocoupler. This device plays a protection role against potentially dangerous voltages, but much more importantly avoids that ground loops appear between the different instruments.
I had a number of old MTC62 couplers obtained by a dismantled old clean room equipment (a RIE), and so I used one of them (just one half). Probably, by adjusting the pinout, it would be even better to use a fast optocoupler such as the PC900 by Sharp. In fact, this model is very often used for MIDI.
The input signal is then fed to pin 18 of the PIC, which is configured by the software to act as a serial receiver. The serial rate is also configured to be the one specified by the MIDI protocol. It is quite simple to receive serial data, since PIC16F876 owns a hardware USART, basically it does everything which is needed for the communication. Using MIDI is not very different than using a RS-232 and in fact I saw several years ago some cheap MIDI interfaces meant to be plugged on the RS-232 ports.
The ICSP (In Circuit Serial Programming) connector gives access to all signals needed to program the microcontroller without having to put it out of the circuit. This is very useful if you have a programmer wich can be adapted to use this fature. The B port of the PIC is devoted to the control of a HD44780 or compatible LCD display, showing 2 lines of 16 characters. The display is precious for the user interface in order to show and change the routing table. To do that, two buttons called DATA and SET are connected to lines A0 and A1 are used for the interaction.
The MIDI message are sent again to pin 17, and then routed thanks to the NAND gates contained in a SN74LS00 on the A or B MIDI outputs. Those gates are controlled by the C0 and C1 outputs of the microcontroller.
A note of folklore: as I said above, I used an optocoupler from a dismantled clean room RIE equipment, and the SN74LS00 comes from a prehistoric scanning electron microscope. In reality, it would be better to choose a 74HC00 which guarantees a more generous output current handling, useful to power up a led.
The firmware
Here is the source code of the firmware, ready to be compiled with MPASM and to be programmed on the PIC. The license here is GPL. I tried to put some meaningful comments in the software, hoping that it will be easy to be adapted to your needs.
Source: MIDI_splitter.asmCompiled: MIDI_splitter.hex
The only thing the software must do is to receive the MIDI packets, recognize the channel of each message and route it towards the output specified in the routing table. Of course, this table must be modifiable by the user at any time and it must be stored in EEPROM such as that it remains in memory during power off.
The PIC firmware is thus quite simple since all the difficult stuff concerning the serial communication is done by the hardware USART. In reality, we just have to configure it to the correct speed (31.25 kbit/s), 8 bits data with a stop bit and a start bit. The transmission is asynchronous, as specified by the MIDI standard. The USART will rise an interruption when a character has been correctly received and it is stored in the communication buffer.
In this way, everything which is related with the transmission and handling of MIDI signals takes place inside the interrupt handler, while the main loop is devoted to the (very simple) user interface. A MIDI message is composed by several bytes sent in a particular order. The first one is the header and it is the only byte having the most significative bit set. The seven remaining bits are used to recognize the message type (on 3 bits) as well as the channel (on 4 bits).
Two types of messages exist: the first one is composed by messages effectively referred to a certain channel, the second one is composed by messages affecting the global configuration of the MIDI device thus not being specific to one particular channel.
In the interrupt handler, the presence of a message header is recognized via a test done on the most significative bit. If a header is found, the program extracts the channel number as specified by the header and reads in the routing table where the channel has been routed. The physical routing is done by activating the C0 and C1 lines.
In the current version of the firmware, I have choosen not to give a complete handling of MIDI messages such as SDS o system exclusive, not associated to a particular channel. I should find the time to expand the code to handle this.
The microcontroller is in principle able to handle with PWM technique the LCD contrast, but for the moment this feature is not activated in the software since in my LCD the best contrast configuration is the one with the contrast pin tied to 0 V.
The user interaction is done via two buttons. The idea is that the DATA button allows to move the cursor through the menu elements, where the SET button allows to change the selected element. In the software, everything is handled via a state machine where each state corresponds to the active menu element and the action of the buttons (after debouncing) is used for the state change.
My first prototype
I assembled my first prototype on a breadboard and I used a backlit display. The power supply is assured by a wall wart which gives more or less 8 V DC, from which the 5 V are obtained thanks to a uA7805 regulator. The required current is less than 100 mA.
I put everything in a metal box, drilling the front panel to show the display and the buttons needed for the user interface. I use classic decals to write on the aluminium panel, covered by thin layers of transparent coating.
Other realizations
Floriano
Since the publication of this page, I have seen with pleasure that this circuit rose some interest. In particular, in 2007 I have been contacted by Floriano, who has even realized a PCB and drawn in a much more elegant way my hand drawn schematic. Floriano used a CNY 17 photo coupler and has been obliged to rise to 27 kΩ the resistance between pin 18 of the PIC and the positive power supply rail in order the transmission is working flawlessly. He also added a LED to the original circuit to show the income of MIDI messages to the circuit.
I publish here with a lot of pleasure the circuit schematic of his realization, as well as the photos he kindly sent to me. It is clear that his solution using a PCB is much professional and cleaner than mine!
Max Marenghi
In February 2013, Max sent to me some photographs of his circuit and autorized me to publish them on the site. Max has put his circuit in a box quite similar to mine and he is using it in his studio. While discussing about the splitter, Max suggested that it would be nice to show the routing table in some way, instead of just "Splitting..." while the circuit is working. I think it is a good idea, I hope to find the time to implement it someday!
A possible improvement
By discussing with Floriano, we understood that this project might be considerably expanded, controlling more than just two outputs. Everything can give a sort of "MIDI patch bay", able to deliver messages on several different physical outputs depending on which logical channel they are sent. To learn a little bit to use Eagle, I played a little with the concept and I tried to route the PCB, even if I never realized it.
Here is the complete archive containing this project, as it is. There is a double side PCB, quite dense (the minimum clearance is 10 mils) and which probably needs to be debugged. If you want to try it (at your own risk), let me know how it went. Always use the HC series for the logic gates, so 74HC245 and 74HC00. I added some LEDs, to indicate the MIDI activity on each output and on the input.
The board is small enough to be modified by the free version of Eagle. This means that you might modify the schematics as well as the PCB as you want. You can correct the errors that might be present in my design. I would be happy to be kept informed if this stuff works, since (I have to insist on that) I did NOT build this board and so it is untested. The PIC assembler file for this version of the circuit is contained in the archive. You can if you want use it for the base version of the circuit by changing the number of the outputs from 6 to 2 in one of the first definitions in the source code. Feel free to modify this project as you wish.
Conclusion and acknowledgements
Even if I have long wanted to explore the hardware part of the MIDI protocol in order, the idea from which everything started came from fruitful discussions with Daniele and Sebastiano, in the Nuova Elettronica forum. Sebastiano asked something slightly different and Daniele and I answered to his help request. From that, several interesting exchanges followed, about USART, software organization as well as the general project architecture.
Of course, if you have some comments or if you would like to send some photos of your realization, you can write to me using the email address: davbucciNoNsPaMmArE@tiscali.it, removing of course the NoNsPaMmArE part of the address.
License:
--------
Copyright (C) 2005-2007 Davide Bucci davbucci at tiscali dot it
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.