Guide to Using the PC_keyboard-to-MIDI Adapter

( -Alan Probandt November 10, 2003 contact me)

A PC keyboard can be a excellent alternative to a full-sized piano keyboard. It's light, portable, inexpensive, and standard throughout the world. It allows a tone module, connected to a small amplifier or boom box, to be easily used as a portable instrument that provides a wide range of musical voices ready to be added to a small musical group or impromptu guitar jam session. It adds new life to old tone modules previously locked into a studio rack or stored in a closet.

This adapter allows a standard PC keyboard to be used as a MIDI note generator. Pressing down a key on the PC keyboard sends a MIDI note-on message and releasing the key sends a MIDI note-off message. The function keys select a new voice by sending a MIDI program change message. The keypad allows you to enter two digits to select a new voice also with a program change message.

On a small piece of perfboard, build the circuit shown in the schematic diagram "schematic.gif".

Schematic for PC MIDI

- Plugging it in

There are three connections to the little board. The power connector is a +8 to +15 volt DC source which is usually a 'wall-wart' battery adapter. This provides power for both the processor inside the PC keyboard and the AVR microcontroller on the little board. Most modern PS2 keyboards (with a Mini-DIN6 connector, same as a mouse) use less than 10 milliAmps of current and the AVR processor uses about 5 milliAmps. Therefore the power adapter does not have to be very big. Even a 9V battery will work OK for at least four hours.

The PC keyboard should be plugged into the Mini DIN 6 connector and the MIDI cable goes into the larger DIN 5 connector. The other end of the MIDI cable goes into the MIDI INPUT of the synthesizer tone module.

-Playing it

All the MIDI commands from the adapter are sent on MIDI channel one.

The four rows of alphanumeric keys (1,2,... - Q,W,E,R,... - A,S,D.... - Z,X,C...) correspond to two rows of piano keys. The 1,2,... row is the black keys (sharps and flats) and the Q,W,E,... row is the white keys of the first (lower octave) piano key row. The A,S,D... is the black key row and the Z,X... is the white key row of the second group of piano keys. There's three and a half octaves total range. Pressing the space bar sends the All_Notes_Off command (" B0 7B 00 ").

Please see the diagram GIF file "MIDIkeys.gif" for the exact correspondence between keys and notes.

Pressing the Caps-Lock key toggles the Sustain petal. After the first press of the Caps-Lock key, all the key presses will send only the Note-On MIDI message. The notes remain sounding after the key is released. The second press of the Caps Lock key turns off the sustain. Now, releasing the key will send a Note-off MIDI message for that key.

This range can be shifted up or down by octave using the Up-Arrow and Down-Arrow keys. The DOWN arrow (towards the front of the keyboard) shifts the range higher in frequency by one octave and the UP arrow (pointing towards the back of the keyboard) shifts the range lower in pitch by an octave.

-Changing the Synthesizer voices

The function keys F1 to F12 correspond to the first twelve voices of the tone module when the adapter is first powered on. For example pressing F2 sends the MIDI command " C0 01 " (these are hex numbers of the MIDI protocol) to the tone module that will change the voice to number two). Pressing the ALT key and a function key will assign the current voice number to the selected function key.

You can select the next voice number with the Right-Arrow key and the previous voice number with the Left-Arrow key. Pressing the Left-Arrow at voice one (hex 00) rolls the voice number to 128 (hex 7f), and the Right-Arrow key will roll-over to voice one (hex 00) when at voice 128.

You can select an individual voice number from 00 to 99 by entering two digits on the key pad. If voice 24 is an excellent string pad then you can activate it by pressing '2' then '3'. Since internal MIDI voice numbers start a 0 instead of 1, the voice listings in the manual will be one greater than the digit selection.

-Limitations

The PC keyboard was engineered for typists who rarely have more than two keys pressed at a time. Therefore the keys are scanned by the keyboard's internal CPU in rows and columns. This means that some key combinations don't get acknowledged at all. On my keyboard there is a 'dead spot' near the 'P' key that only plays one note at a time. If this causes a problem for your playing style, try shifting the octave range to another part of the keyboard.

-Suggestions

- Use the UART of the AVR AT90S2313 to add PC serial port MIDI access. - Split the keyboard top and bottom between two MIDI voices. -Add an EEPROM chip to store custom voice information that gets sent to the tone module. This allows custom voices to be added to tone modules like the Roland MT-32 that don't have an internal battery to store data. -Add a second MINI DIN6 for a mouse. Interpret mouse movements as MIDI pitch-bend and Mod wheel data.

****** The circuit internals and 'PCkb.asm' source code ****

The adapter uses an Atmel AVR microcontroller to read the serial pulses from the keyboard and generate the serial pulses for the MIDI interface. Although designed and coded for the AT90S2313 version of the AVR, the code can be used on any chip of the AVR family. If you use the low-end AVR model AT90S1200, then use the source code file "PCkb1200.asm" instead of "PCkb.asm" because of the limitations of the low-end 1200 model. The 1200 code uses a different look-up table for the keypresses than the code for the other AVRs. I believe that this circuit will work with the $0.54 Tiny11 AVR using the code for the 1200. However the 1200 EEPROM table would be placed into Flash memory and accessed by using the LPM instruction. The Tiny11 does not have in- circuit programming like the 1200.

This design's AVR system clock is set by a standard 3.579MHz color-burst TV crystal. Using a different crystal or the internal AVR R-C clock requires adjusting the delay timing value for the MIDI output. This is the constant called 'b' located in the subroutine PUT_MIDI of the source code. The input from the keyboard triggers an interrupt with each falling transition and is not dependent on any system clock speed.

Running the ATMEL Windows assembler will give the message "Code Too Big". To use this assembler, split the source file into two parts called PCkb.asm and PCkb2.asm at line 565. Then uncomment the 'include' directive located at that line. Other assemblers don't have this idiotic problem.

The files 2313def.inc and 1200def.inc provide reference definitions for the processors.

*****Atmel AVR resources:

AVR microcontrollers are available at Digikey. The connectors can be removed from old, used PC motherboards.

PDF data sheets, assemblers, and code simulators for the Atmel AVR microcontrollers are found at the Atmel website. The simulator is called AVRstudio.exe Version 3.56 is easiest to use and learn.

The best programmer either the Atmel STK500 board for $80 or the free PC parallel port programmer found at: "Programming a spider's brain." This program code is SP12.exe. I've built and used 'Ken's Dongle' to program AVRs with no problems. The command line interface is a little tricky, but be patient, make little tests, and re-read the documentation until everything comes together for you.

GNU AVR C compiliers and lots of information, tutorials, and help is found at: AVR Freaks

All the keyboard interfacing information below is on the web at: Craig Peacock's site


Interfacing the AT keyboard.

Why would you want to interface the Keyboard? The IBM keyboard can be a cheap alternative to a keyboard on a Microprocessor development system. Or maybe you want a remote terminal, just couple it with a LCD Module.

Maybe you have a RS-232 Barcode Scanner or other input devices, which you want to use with existing software which only allows you to key in numbers or letters. You could design yourself a little box to convert RS-232 into a Keyboard Transmission, making it transparent to the software.

An interfacing example is given showing the keyboard's protocols in action. This interfacing example uses a 68HC705J1A MCU to decode an IBM AT keyboard and output the ASCII equivalent of the key pressed at 9600 BPS.

Note that this page only deals with AT Keyboards. If you have any XT keyboards, you wish to interface, consider placing them in a museum. We will not deal with this type of keyboard in this document. XT Keyboards use a different protocol compared to the AT, thus code contained on this page will be incompatible.



PC Keyboard Theory

    The IBM keyboard you most probably have sitting in front of you, sends scan codes to your computer. The scan codes tell your Keyboard Bios, what keys you have pressed or released. Take for example the 'A' Key. The 'A' key has a scan code of 1C (hex). When you press the 'A' key, your keyboard will send 1C down its serial line. If you are still holding it down, for longer than its typematic delay, another 1C will be sent. This keeps occurring until another key has been pressed, or if the 'A' key has been released.

    However your keyboard will also send another code when the key has been released. Take the example of the 'A' key again, when released, the keyboard will send F0 (hex) to tell you that the key with the proceeding scan code has been released. It will then send 1C, so you know which key has been released.

    Your keyboard only has one code for each key. It doesn't care it the shift key has been pressed. It will still send you the same code. It's up to your keyboard BIOS to determine this and take the appropriate action. Your keyboard doesn't even process the Num Lock, Caps Lock and Scroll Lock. When you press the Caps Lock for example, the keyboard will send the scan code for the cap locks. It is then up to your keyboard BIOS to send a code to the keyboard to turn on the Caps lock LED.

    Now there's 101 keys and 8 bits make 256 different combinations, thus you only need to send one byte per key, right?

    Nop. Unfortunately a handful of the keys found on your keyboard are extended keys, and thus require two scan code. These keys are preceded by a E0 (hex). But it doesn't stop at two scan codes either. How about E1,14,77,E1,F0,14,F0,77! Now that can't be a valid scan code? Wrong again. It happens to be sent when you press the Pause/break key. Don't ask me why they have to make it so long! Maybe they were having a bad day or something?

    When an extended key has been released, it would be expect that F0 would be sent to tell you that a key has been released. Then you would expect E0, telling you it was an extended key followed by the scan code for the key pressed. However this is not the case. E0 is sent first, followed by F0, when an extended key has been released.

    Keyboard Commands

    Besides Scan codes, commands can also be sent to and from the keyboard. The following section details the function of these commands. By no means is this a complete list. These are only some of the more common commands.

      Host Commands

      These commands are sent by the Host to the Keyboard. The most common command would be the setting/resetting of the Status Indicators (i.e. the Num lock, Caps Lock & Scroll Lock LEDs). The more common and useful commands are shown below.

      EDSet Status LED's - This command can be used to turn on and off the Num Lock, Caps Lock & Scroll Lock LED's. After Sending ED, keyboard will reply with ACK (FA) and wait for another byte which determines their Status. Bit 0 controls the Scroll Lock, Bit 1 the Num Lock and Bit 2 the Caps lock. Bits 3 to 7 are ignored.
      EEEcho - Upon sending a Echo command to the Keyboard, the keyboard should reply with a Echo (EE)
      F0Set Scan Code Set. Upon Sending F0, keyboard will reply with ACK (FA) and wait for another byte, 01-03 which determines the Scan Code Used. Sending 00 as the second byte will return the Scan Code Set currently in Use
      F3Set Typematic Repeat Rate. Keyboard will Acknowledge command with FA and wait for second byte, which determines the Typematic Repeat Rate.
      F4Keyboard Enable - Clears the keyboards output buffer, enables Keyboard Scanning and returns an Acknowledgment.
      F5Keyboard Disable - Resets the keyboard, disables Keyboard Scanning and returns an Acknowledgment.
      FEResend - Upon receipt of the resend command the keyboard will re- transmit the last byte sent.
      FFReset - Resets the Keyboard.


      Commands

      Now if the Host Commands are send from the host to the keyboard, then the keyboard commands must be sent from the keyboard to host. If you think this way, you must be correct. Below details some of the commands which the keyboard can send.


      FAAcknowledge
      AAPower On Self Test Passed (BAT Completed)
      EESee Echo Command (Host Commands)
      FEResend - Upon receipt of the resend command the Host should re-transmit the last byte sent.
      00Error or Buffer Overflow
      FFError or Buffer Overflow


Scan Codes

    The diagram below shows the Scan Code assigned to the individual keys. The Scan code is shown on the bottom of the key. E.g. The Scan Code for ESC is 76. All the scan codes are shown in Hex.

    Scancodes - Keyboard

      As you can see, the scan code assignments are quite random. In many cases the easiest way to convert the scan code to ASCII would be to use a look up table. Below is the scan codes for the extended keyboard & Numeric keypad.

    Scancodes -  Numeric Keypad


The Keyboard's Connector

    The PC's AT Keyboard is connected to external equipment using four wires. These wires are shown below for the 5 Pin DIN Male Plug & PS/2 Plug.

    5 Pin Din Numbering (Male Plug)
    5 Pin DIN
    1. KBD Clock
    2. KBD Data
    3. N/C
    4. GND
    5. +5V (VCC)
    PS2 Numbering (Male Plug)
    PS/2
    1. KBD Clock
    2. GND
    3. KBD Data
    4. N/C
    5. +5V (VCC)
    6. N/C

    A fifth wire can sometimes be found. This was once upon a time implemented as a Keyboard Reset, but today is left disconnected on AT Keyboards. Both the KBD Clock and KBD Data are Open Collector bi-directional I/O Lines. If desired, the Host can talk to the keyboard using these lines.

    Note: Most keyboards are specified to drain a maximum 300mA. This will need to be considered when powering your devices


The Keyboard's Protocol
    Keyboard to Host

    As mentioned before, the PC's keyboard implements a bi-directional protocol. The keyboard can send data to the Host and the Host can send data to the Keyboard. The Host has the ultimate priority over direction. It can at anytime (although the not recommended) send a command to the keyboard.

    The keyboard is free to send data to the host when both the KBD Data and KBD Clock lines are high (Idle). The KBD Clock line can be used as a Clear to Send line. If the host takes the KBD Clock line low, the keyboard will buffer any data until the KBD Clock is released, ie goes high. Should the Host take the KBD Data line low, then the keyboard will prepare to accept a command from the host.

    The transmission of data in the forward direction, ie Keyboard to Host is done with a frame of 11 bits. The first bit is a Start Bit (Logic 0) followed by 8 data bits (LSB First), one Parity Bit (Odd Parity) and a Stop Bit (Logic 1). Each bit should be read on the falling edge of the clock. From the first falling edge to the last rising edge is usually 880 microseconds.

    Keyboard to Host Protocol Waveform

    The above waveform represents a one byte transmission from the Keyboard. The keyboard may not generally change its data line on the rising edge of the clock as shown in the diagram. The data line only has to be valid on the falling edge of the clock. The Keyboard will generate the clock. The frequency of the clock signal typically ranges from 20 to 30 Khz. The Least Significant Bit is always sent first.

    Host to Keyboard

    The Host to Keyboard Protocol is initiated by taking the KBD data line low. However to prevent the keyboard from sending data at the same time that you attempt to send the keyboard data, it is common to take the KBD Clock line low for more than 60us. This is more than one bit length. Then the KBD data line is taken low, while the KBD clock line is released.

    The keyboard will start generating a clock signal on its KBD clock line. This process can take up to 10mS. After the first falling edge has been detected, you can load the first data bit on the KBD Data line. This bit will be read into the keyboard on the next falling edge, after which you can place the next bit of data. This process is repeated for the 8 data bits. After the data bits come an Odd Parity Bit.

    Host to Keyboard - Protocol Waveform

    Once the Parity Bit has been sent and the KBD Data Line is in a idle (High) state for the next clock cycle, the keyboard will acknowledge the reception of the new data. The keyboard does this by taking the KBD Data line low for the next clock transition. If the KBD Data line is not idle after the 10th bit (Start, 8 Data bits + Parity), the keyboard will continue to send a KBD Clock signal until the KBD Data line becomes idle.

    Copyright 1999-2001Craig Peacock - 19th August 2001.