30年前のキーボードをUSBキーボードとして復活させる

この記事はOUCC Advent Calendar 2014の18日目の記事のはずでした。

作ったもの

父親が30年前に会社から拾ってきたらしいPC-8801のキーボードをUSB HID化した。

f:id:domitry_h:20130918160742j:plain

キーボードの仕組み

キーボードから出ている端子には14本のピンが存在し、写真のように配線されている。

f:id:domitry_h:20141217181534p:plain

表にはキーボードコントローラとパスコンが実装されている。

f:id:domitry_h:20141217185010p:plain

マイコンに刻印されていた型番を検索すると、データシートを見つけることができた。

Texas Instruments SN74159N

データシートの図を見ると、入力ピンが4つ、出力ピンが16つとなっている。出力ピンは常に15本がHigh、1本がLowになっていて、24=16種類の入力に対しLowのピンがひとつづつ変わっていく仕組みだった。

f:id:domitry_h:20141217180236p:plain

f:id:domitry_h:20141217180336p:plain

(出所: "SN54159, SN74159 4-LINE TO 16-LINE DECODERS/DEMULTIPLEXERS WITH OPEN-COLLECTOR OUTPUTS", Texas Instruments社)

一般的なキーマトリクスは以下のようになっているようだ。

(出所: "NicoKeyboardのスイッチ同時読み -- 個人ページ")

これによると、キーボードコントローラのOUTPUTのピン数16 * キーボードの外に出ているINPUTのピン数8 = 128のキーを配置することができると思われる。

いくつまで同時押しできるかでキーマトリクス上のダイオードの配置がわかるとのことだが、制作当時はそこまでは試さなかった。キーマトリクスも奥が深い。

制作

工作

国電子で購入した赤黒2本をまとめたケーブルを7つ用意しArduinoに接続する。 このままキーボード上の端子に接続できた。基板のピッチ長(0.1インチ)は変わらないんだなあと感動する。

ケースはiPod touchの入れ物だったプラスチックケースを適当に加工して使用。

キーマップの作成

Arduino UNOのデジタルピン14+6本の内、4本を出力、8本を入力に充てる。5VとGND、入出力の14本のコードをキーボード上の端子につなぐ。

あるキーを押したままINPUTSの組み合わせをすべて試すと、ある組み合わせのときに一つのINPUTピンがLOWになった。

これをすべてのキーで試し、USBキーボードのキーコードと対応させることでキーマップを作成することができる。USBキーボードのコードの表は以下の通り。

USBキーボードのキーコード

現代のキーボードとPC-8801のキー配列が一部異なっていたため、足りないキー(Functionalキー等)は適当なキーに割り当てた。できたキーマップが以下の通り。

const int pins[16][4] =  {
    {LOW,LOW,LOW,LOW},
    {LOW,LOW,LOW,HIGH},
    {LOW,LOW,HIGH,LOW},
    {LOW,LOW,HIGH,HIGH},
    {LOW,HIGH,LOW,LOW},
    {LOW,HIGH,LOW,HIGH},
    {LOW,HIGH,HIGH,LOW},
    {LOW,HIGH,HIGH,HIGH},
    {HIGH,LOW,LOW,LOW},
    {HIGH,LOW,LOW,HIGH},
    {HIGH,LOW,HIGH,LOW},
    {HIGH,LOW,HIGH,HIGH},
    {HIGH,HIGH,LOW,LOW},
    {HIGH,HIGH,LOW,HIGH},
    {HIGH,HIGH,HIGH,LOW},
    {HIGH,HIGH,HIGH,HIGH}
};
 
const unsigned char key_code[16][8] = {
    {0,0,0,0,0,0,0,0},
    {0,68,67,66,0,0,40,0},
    {8,7,6,5,4,47,10,9},
    {8,15,14,13,12,11,18,17},
    {24,23,22,21,20,19,26,50},
    {24,137,48,29,28,27,45,46},
    {55,33,32,31,30,39,36,35},
    {55,54,51,52,38,37,135,56},
    {0,227,42,79,82,76,224,229},
    {226,61,60,59,58,53,41,44},
    {0,0,70,80,81,43,57,65},
    {0,0,0,0,64,63,0,0},
    {0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0}
};

key_codeの行がOUTPUTの組み合わせ、列がINPUTのピンに対応している。

ArduinoのUSB HID化

Arduiono UNOには2つのAVR(ATMega328Pと16U2)が搭載されており、後者がUSBコントローラとして使われている。こちらは普段シリアル通信モジュールとして振る舞っているが、USB HIDとして振る舞うようなファームウェアを焼いてやるとArduinoをキーボードとして使えるようになる。

この部分に関しては以下の記事が詳しい。

【ArduinoUNO】HID USBキーボードシミュレータ?を作ってみた。(その1): じむの(とりあえず)やってみたの巻

スケッチの作成

PCにスキャンコードを送信するには、シリアル通信のAPIを使って16U2と通信する。以上をArduinoのスケッチにしたものを以下に示す。

gistcadb9e01d299db91c3fd

まとめ

かなりわかりやすいキーボードを弄ったことで仕組みがよく理解できた、と思う。正直去年の出来事なのであまり覚えていない。

安上がりにメカニカルキーボードを手に入れられたのは非常によかった。制作当時HHKBを買う余裕はなかったが、こちらはケーブル代、Arduino代、デバッグにつかったLED代くらいで済んだ。

おまけ

CAPSキー・かなキーが面白かった。

f:id:domitry_h:20141217184825g:plain

この記事はOUCC Advent Calendar 2014の18日目の記事のはずでしたが、あまりにも長くなりすぎたので記事を分けました。こちらは分離された方の記事です。

OUCCでは古いガジェットを復活させたい部員も募集しています