Practical MIDI packs generating / transmitting

by Jordan D. Petkov


After the publication of my MIDI keyboard controller project, I received a lot of questions about MIDI signals physical nature: what the levels are, what is bit order, how start - stop bits are inserted, how to connect the controller to standard MIDI device instead of PC etc. This article answers these questions.

ELECTRICAL POINT OF VIEW

There are two possible ways to use self-made MIDI controllers, no matter what technology are they based on. The first one is connecting to PC souncard wich has embedded MIDI synthesizer. The second is to use standard MIDI stuff at the other end. Both ways are different when it comes to requirements to generated signals, more specially to their electrical characteristics. Timing characteristics are strictly defined by MIDI standard.

In order to be connected to PC soundcard MIDI controller (keyboard etc.) should generate TTL compatible signals on its output. Here are TTL levels definitions:



NOTE: The TTL levels are defined only in 0..+5V window. If you are usind non-TTL levels (for example: CMOS at 9V), yu should convert output levels to TTL specified. Else you could damage your PC soundcard! The undefined zone between 0- and 1-levels may vary for different TTL types and different items.

Usually PC MIDI interface is combined with joystick controller and both interfaces are placed at the computer's back as an 25 pins connector. Here is description of typical MIDI/Joystick connector:

Picture Pin Description
1
+5v
2
X button for joystick A
3
X potentiometer for joystick A
4
Ground
5
Ground
6
Y potentiometer for joystick A
7
Y button for joystick A
8
+5v
9
+5v
10
X button for joystick B
11
X potentiometer for joystick B
12
MIDI out
13
Y potentiometer for joystick B
14
Y button for joystick B
15
MIDI In

NOTE: You can use the joystick interface connector to power up your MIDI design, but I don't know what is the maximal current you may draw from there. Using such supply is on your own responsibility.
Pins concerning PC MIDI are shown in bold font.

Every MIDI controller generating MIDI packs at TTL levels (like my MIDI keyboard controller) can be connected to PC MIDI interface this way:



NOTE: For such connection you could use 2(3) wires cable. The power supply from PC joystick port is optional. Use it only if you are sure that your device will draw current less than 10-20 miliamperes. It's good idea to use shielded cable (shield is GND connected).

When it comes to connecting self-made MIDI-controller to standard MIDI device (synth etc.), the signals requirements are different from above mentioned. Here comes so called "current circuit loop". What this means?

In order to assure that there will be no electrical connection between different MIDI devices on stage, an optical connection is used instead electrical one. The optical connection is done by opto-couples, embedded in standard MIDI devices. This is an standard requirement imposed by MIDI standard. (see Bob McQueer's article). Such devices usually consist of LED (Light Emitting Diode) and photo-transistor placed in common pack:


Some of opto-couples have additional protective diode parallel/reverse connected to LED. It is good practice to add external protective diode the way it is shown on next figure.

NOTE: The MIDI controller and the MIDI device should have their OWN power supply(Vcc) and ground (GND) lines and there is NO electrical connection between controller Vcc and device Vcc as well as between controller GND and device GND! The only one connection is the current loop sourced by controller and driving LED. In fact connection is done by optical channel embedded in opto-couple.

The right part (transistor) is connected to input circuits of the receiver (standard MIDI device UART). The current thru LED should come from transmitter (self-made MIDI controller) in such way that when transmitter transmits logical '0', the LED is on, and when '1' is transmitted, the LED is off. From the other side of this opthical connection photo-transistor goes in conductive state (on) when the LED is on, and back in non-conductive state (blocked) when LED is off. This way its emitter voltage is high (logical 1) when LED is off, and low (logical 0) when on. The standard circuit for coupling MIDI controller and MIDI device is like this one:



NOTE:The picture represented here is from Jalkanen Album by Timo Jalkanen. You may also obtain the last version of the album on Timo's site.

The left part of schematic shows the stuff needed to be included at the controller's side (i.e. keyboard). The right part shows what is (has to be) included in standard MIDI device (synthesizer for example). Note that this is the MIDI standard statement. I couldn't guarantee that every MIDI controller have this module included.

Obviously there should be some requirements to MIDI controller output signal, since it has to drive a LED. The most common requirement to drive such LED's are to be capable to source current of 10 miliamperes. When using +5v supply (most common case) this means to connect LED between power and ground using serially connected resistors at approximately 500 Ohm (summary). Usually two identical resistors are used connected to both LED ends. Their value can be 200 - 250 Ohm. I myself use 2x220 Ohm.
These opto-couples are considered to be best for using in MIDI devices:
PC-900 and 6N138.
You are not indebted to use additional TTL buffers like shown on the picture if your controller is capable to source current needed for LED driving. In this case you could connect your device directly to MIDI out connector (ofcource using two 220 Ohm resistors).

 

MIDI PACK CONSTRUCTION

a.STATUS BYTE

While discussing the pack construction, we will take into these considerations:

The best way to show how the MIDI pack is constructed is to show step by step constructing that comes into PIC processor working in MIDI keyboard controller. I shall use different colours to represent different bit groups.

Suppose that a key C has been pressed on our MIDI keyboard. The MIDI controller has recognized the keynumber and translated it into MIDI note number (60). Now it should generate MIDI command NoteOn for note 60 (C) at velocity 64 and transmit it to MIDI synth on MIDI channel #0 (most used MIDI channel in PC soundcards). The NoteOn command consists of three bytes: the first is Status byte holding event code and channel number, the second is Data byte, holding Note number, the third is Data byte, holding Velocity value. Since a bit can contain only 0 or 1, we have to represent all digits into binary format. Thus we talk about note number '0111100' (7-bit value) and velocity value '1000000' (7-bit value). (By the way, you can use the standard Windows Calculator for such conversions.)

First, we shall construct the Status byte.
As I said, the most significant bit have to be '1' by default, since this is bytetype marker and shows the MIDI device that this byte is Status. The next three bits represent real MIDI command (also called event). Possible values are from '000' (dec.0) to '111' (dec.7). Thus, eight different events are possible. Here are all the MIDI events:

Event number
Event binary code
(3 bit)
Event name Event description
MIDI pack contains
0
000
Note Off An key has been released - switch off its note.

3 bytes:
Status byte
Data1 byte (Note number 0..127)
Data2 byte (Velocity 0..127)

1
001
Note On An key has been pressed - switch on its note. 3 bytes:
Status byte
Data1 byte (Note number 0..127)
Data2 byte (Velocity 0..127)
2
010
Polyphonic Key Pressure (Aftertouch) An key has been slightly moved up or down after Note On event has been generated for this key - change its velocity 3 bytes:
Status byte
Data1 byte (Note number 0..127)
Data2 byte (New velocity 0..127)
3
011
Control Change Change controller's value. 3 bytes:
Status byte
Data1 byte (Controller number 0..127)
Data2 byte (New value 0..127)
4
100
Program Change Change the patch (instrument) number.

2 bytes:
Status byte
Data1 byte (New patch number 0..127)

5
101
Channel pressure (Aftertouch) An key has been slightly moved up or down after Note On has been generated for this key - change all notes velocity. 2 bytes:
Status byte
Data1 byte (New velocity 0..127)
6
110
Pitch Wheel Change The pitch wheel position has changed - change new pitch value.

3 bytes:
Status byte
Data1 byte (Least significant byte of new pitch value 0..127)
Data2 byte (Mist significant byte of new pitch value 0..127)

7
111
System Exclusive Used for all things non-supported by MIDI messages 0..1. Different manufacturers use this different way. Commonly, self-made MIDI stuff doesn't support this message.

Here I'll show channel numbers binary representation to avoid talking about decimal to binary converting:

Channel number
Channel binary number (4 bit)
0
0000
1
0001
2
0010
3
0011
4
0100
5
0101
6
0110
7
0111
8
1000
9
1001
10
1010
11
1011
12
1100
13
1101
14
1110
15
1111

In our case we should generate NoteOn event. It's code is '001'. The right byte nibble (4 bits) should hold the channel number. This is a number between '0000' (dec.0) and '1111'(dec.15). As we should use MIDI channel #0, we put '0000' in this nibble. This way combining bytetype flag, event code and channel number, we constructed the first byte:

Status byte:
1
0
0
1
0
0
0
0


b.DATA BYTES

Next, we construct the first Data byte.
The left bit (most significant) have to be set to 0 to mark byte as Data. The next seven bits have to be set at value 0 - 127 to pass Note number to MIDI device. As I said, Note number is '0111100' (7 bit) for C (dec. 60). Combining flag bit with note number, we construct the first data byte:

Data byte 1:
0
0
1
1
1
1
0
0

Finally, we construct the second Data bute.
The left bit (most significant) have to be set to 0 again. The next seven bits have to be set at value 0 - 127 to pass Velocity to MIDI device. The Velocity in our case is '1000000'. The second data byte looks like this:

Data byte 2:
0
1
0
0
0
0
0
0

c.FULL 'NOTE ON' PACK

Now we have all three bytes, but they are not MIDI pack yet. In order to make MIDI pack, we have to order the bytes this way:

Status
Data1
Data2
1
0
0
1
0
0
0
0
0
0
1
1
1
1
0
0
0
1
0
0
0
0
0
0

Almost done. But we've missed two things. First: to insert startbit having value 0 at the start of every of our three bytes, second: to paste stopbit (value 1) at the end of each byte.

NOTE: There is something very important about transmitting order. Bytes are transmitted in this order: Status, Data1, Data2. Bits into every byte are transmitted in reverse order, starting with rightmost bit(Least significant).

This means that before transmitting every of bytes above has to be reverted. Most significant bit becomes rightest and Least significant bit becomes leftest. Now, the bit order looks like this:

Status
Data1
Data2
0
0
0
0
1
0
0
1
0
0
1
1
1
1
0
0
0
0
0
0
0
0
1
0

The last thing to do is to insert Start/Stop bits:

Status Data1
Data2  
0
0
0
0
0
1
0
0
1
1
0 0
0
1
1
1
1
0
0
1
0 0
0
0
0
0
0
1
0
1

In order easy to track bits transformation in the above pictures, they are coloured as follows:

Bytetype bits
Startbits
Stopbits
MIDI event bits
MIDI channel bits
MIDI note bits
Velocity bits

That is it. The pack is ready to transmit and consists of 30 bits. Transmitter should place every bit on its output for time period exactly 32 microseconds.
First is transmitted the leftmost bit on diagram shown above, then next and next etc. At the end the line status should remain logical 1. I should mention that the interval between single bytes in pack is not reglamented, so controller can, if needed, make pauses between single bytes (I mean: between stopbit of previous byte and startbit of next).

Following example given above one can compose every MIDI pack described in MIDI specification. An MIDI pack is composed every way when it comes to MIDI command transmission. The difference is as comes to MIDI event, MIDI channel and other parameters. Byte count depends on event type. There are one-, two-, three- and more byted commands. The MIDI commands format is described well enough and I have no intention to do this here.

Starting this article I was intending to place here some flowchart-diagrams explaining how the keyboard controller does keyscanning and MIDI pack generation, but coming to this point, it seems to me, this is needless. Maybe sometimes in the future I shall write another article dedicated to programming aspects of MIDI controllers...

DIAGRAMS

Next picture shows how the MIDI signals, generated as described above, should be seen using oscylloscope.

NOTE: As defined by MIDI standard, logical 1 is set when line is in passive state (i.e. no data transmitted). Each Byte starts with startbit (low level) and ends with endbit (high level) which can be as long as needed, but not less 32 microseconds. The stopbit of the last byte in the message becomes actually the line passive state.

©Jordan D. Petkov 2000
[email protected]
www.geocities.com/jdpetkov/

 

 

Hosted by www.Geocities.ws

1