Reverse Engineering an Air Traffic Control Keyboard – Part One

Reverse Engineering an Air Traffic Control Keyboard – Part One

Recently, my friend bought an old ARTS (Automated Radar Terminal System) keyboard, hoping to be able to use it for Virtual Air Traffic Control with VATSIM. As the resident hardware hacker, I was tasked with designing an interface to allow it to be connected to his computer.

The keyboard, and it’s accompanying trackball.

First things first, let’s get a high level overview of what we’re dealing with. On the left-hand side of the above photo is the brains of the operation. This board screws onto the back of the keyboard and, via a 20-pin header, interfaces with each row and column of the keyboard matrix, along with providing power for the incandescently backlit keys. The board also has two DB-15 connectors, one to interface with the trackball, and the other to communicate to the terminal. The trackball was manufactured by Orbit Instrument, which mainly caters to the military. Unlike the keyboard, the trackball appears to be a sort of universal part, as it’s product page (archive) lists a very diverse set of use applications. After poking around Orbit’s website some more, it appears they are now the manufacturer for the newer STARS keyboards, but after some digging it appears as ARTS and STARS keyboards use widely different interfaces, so any information Orbit would have is useless for my case.

The keyboard module. Manufactured Feb 19, 2000

On the keyboard module, we have: two Atmel AT89C51 microprocessors, two Linear LT1085 regulators, a Maxim MAX548 DAC, a National DS9637 and DS9638 to communicate over RS-422, and a Sipex MAX232ACP to communicate over RS-232.

After playing Follow-the-Trace for a bit, I have determined that the RS-422 circuitry is used to communicate to the trackball, and send that data to the bottom microprocessor. The bottom microprocessor then forwards these messages, along with any key presses, to the MAX232, which then sends all of that data to the terminal via RS-232. Now, any data coming from the terminal is sent to the top microprocessor, which is mainly responsible for commanding the DAC to change the backlighting via a transistor connected to the adjustment pin of the LT1085’s. The keyboard and trackball backlighting is powered with a 12V circuit, isolated from the 5V logic circuitry on the rest of the board.

The board speaks RS-232 at 9600 baud

After temporarily wiring a USB-UART adapter to the UART output on the MAX232, I was able to communicate with the keyboard using my computer. And after writing a quick python script, I now have the keycode for every key.

[
{
“61E1”: “M1”,
“62E2”: “M2”,
“65E5”: “M3”,
“66E6”: “M4”,
“67E7”: “CON”,
“68E8”: “MAP”,
“69E9”: “M5”,
“6AEA”: “M6”,
“6BEB”: “M7”,
“6CEC”: “M8”
},
{
“63E3”: “M9”,
“64E4”: “M10”,
“6DED”: “M11”,
“6EEE”: “M12”,
“6FEF”: “TRK”,
“70F0”: “USR”,
“71F1”: “M13”,
“72F2”: “M14”,
“73F3”: “M15”,
“74F4”: “M16”
},
{
“5FDF”: “CLEAR”,
“3ABA”: “BACK SPACE”,
“3BBB”: “SPACE”,
“3CBC”: “ENTER”
},
{
“0080”: “INIT CNTL”,
“0181”: “TRK RPOS”,
“0282”: “TRK SUSP”,
“0383”: “TERM CNTL”,
“0484”: “HDN OFF”,
“0585”: “FLT DATA”,
“0686”: “MULTI FUNC”,
“0787”: “F8”,
“3DBD”: “TRIANGLE”,
“3EBE”: “DOT”
},
{
“0888”: “F9”,
“0989”: “F10”,
“0A8A”: “CA”,
“0B8B”: “F12”,
“0C8C”: “F13”,
“0D8D”: “F14”,
“0E8E”: “TGT GEN”,
“0F8F”: “F16”,
“3FBF”: “IFR +”,
“40C0”: “VFR /”
},
{
“41C1”: “A”,
“42C2”: “B”,
“43C3”: “C”,
“44C4”: “D”,
“45C5”: “E”,
“46C6”: “F”,
“47C7”: “G”,
“31B1”: “1”,
“32B2”: “2”,
“33B3”: “3”
},
{
“48C8”: “H”,
“49C9”: “I”,
“4ACA”: “J”,
“4BCB”: “K”,
“4CCC”: “L”,
“4DCD”: “M”,
“4ECE”: “N”,
“34B4”: “4”,
“35B5”: “5”,
“36B6”: “6”
},
{
“4FCF”: “O”,
“50D0”: “P”,
“51D1”: “Q”,
“52D2”: “R”,
“53D3”: “S”,
“54D4”: “T”,
“55D5”: “U”,
“37B7”: “7”,
“38B8”: “8”,
“39B9”: “9”
},
{
“56D6”: “V”,
“57D7”: “W”,
“58D8”: “X”,
“59D9”: “Y”,
“5ADA”: “Z”,
“5BDB”: “*”,
“5CDC”: “MIN”,
“5DDD”: “DEC”,
“30B0”: “0”,
“5EDE”: “INC”
}
]

I’m still working on finding the exact commands to control the brightness, but so far, I’ve discovered that 0xA0 followed by any non-zero byte seems to turn the lights on.

At 12 volts, the lights draw around 1.4 amps.

After fiddling around in Eagle for a bit, this is what I’ve managed to come up with for an interface:

My adapter uses a MAX232 and a SparkFun Pro Micro. The Pro Micro was used because of it’s ATmega 32u4’s ability to act as a human interface device. I could’ve built the 32u4 into the design directly, but that was too much work for a one-off project.