Alternative Controller for HHKBのススメ


## 概要
Alternative Controller for HHKBとは、Happy Hacking Keyboard(HHKB)のコントローラを入れ替えることで全てのキーをプログラマブルにできるコントローラのこと。
キーボード自体をプログラマブルにすることで、OSあるいは[AutoHotkey](https://autohotkey.com/)や[Karabiner] (https://pqrs.org/osx/karabiner/index.html.ja)などのソフトウェアに依存せずどの環境でも同じ動作をさせることができるようになる。

Alternative Controller for HHKBには、HHKB Professional, Professional 2, Professional 2 Type-S, Professional JP, Professional JP Type-Sに対応するモデルがある。HHKB本体はいずれもBluetooth非対応モデルだが、いくつか制約事項はあるもののBluetooth対応させることもできる。なお、HHKB Professional BTとは違い、Bluetooth対応させた場合でもUSB接続に切り替えることができる。
なお、形状が異なるHHKB Professional HYBRID(Type-Sも含む), HHKB Professional Classic, HHKB Professional BT, HHKB Lite2等には対応していない。

## 購入方法
[Topic: [TMK] Alt Controller Board for HHKB](https://geekhack.org/index.php?topic=71517.0)に書かれているのでしっかり読むこと。

2016/08/11時点で書かれている購入の流れをざっとまとめておくと、

1. Hasu氏にgeekhackのPrivate Messageまたはメールで購入したいAlternative controller for HHKBのモデルと自分のメールアドレス(Paypalのアカウント)を連絡する。
1. 連絡したメールアドレスにHasu氏からPaypalの請求書が届く。
1. Paypalで3日以内にクレジットカードで支払いを済ませる。遅れた場合は注文がキャンセルされる。
1. 日本郵便(追跡サービスあり)で郵送されてくる。

という感じ。Hasu氏は日本人で首都圏在住のようなので、本州なら数日で届くとみていい。

## 制約事項
[Topic: [TMK] Alt Controller Board for HHKB](https://geekhack.org/index.php?topic=71517.0)に書かれているのでしっかり読むこと。
Hasu氏は日本人だし日本語で聞けば答えてくれる、とは考えないほうがいい。最低限ここに書かれている内容を理解できる英語力は必要だと考えるべき。

2016/08/11時点で書かれている重要そうな制約事項をざっとまとめておくと、

* USB Hub機能なし
* DIPスイッチなし(ファームウェアの機能で代替できる)
* BT版はRN-42 Bluetoothモジュールの制約を受ける
 * Class 2 Bluetooth 2.1相当
 * HID Usage ID 0x65までしか送信できない(従ってJIS配列固有のキーは送信不可)
* BT版はLiPoバッテリは同梱されていない(動作実績のあるものを別途購入する必要がある)

となっている。特にBT版は色々と気に留めておく事項があるので注意。

USB Hub機能のあるHHKB Professional 2/Type-SのUSB Hubのケースの穴は、USB版は空いたまま、BT版はUSB・BTの切り替えスイッチや状態を示すLEDが見える穴になる。基板部へのほこりの侵入を防ぐためにキャップを作成する場合は、3Dプリンタでキャップを作った人がCADデータを公開してくれていたりするようなので利用するといいだろう。
逆に、USB Hub機能のないHHKB Professional JP/JP Type-Sは、BT版の場合はケースに穴を開ける必要があるようだ。
Alternative controller for HHKBのUSBコネクタは、HHKBと同じMini-Bと、Type-Cとが選択できるようになっている。Type-CのものでもUSB3.0やPDには未対応。

## コントローラの詳細
HHKBの内部には、静電容量無接点方式のキースイッチ部分の基板(ほぼ本体サイズ)と、そこからケーブルで接続されたコントローラ(本体の約1/4サイズ)の2つの基板があるが、この小さい方の基板をAlternative Controller for HHKBに差し替えることになる。

緑色の基板がHHKB(Pro2)、青色の基板がAlternative Controller for HHKB(Pro2 USB)。
![HHKB Controller](https://qiita-image-store.s3.amazonaws.com/0/28644/761e1553-910c-1c3c-49df-7c53eca255a1.jpeg "HHKB Controller")

差し替えるコントローラは、HHKB本体背面パネルの内側にネジ止めされている。HHKB本体背面のネジを外してフタを開け、背面パネル内側のコントローラのネジとコネクタを外せば取り外すことができる。ケーブルはそれほど長くないので、フタを開ける時は引っ張らないように注意。また、コネクタも若干外しづらいので無理に引っ張らないようにする。
コントローラを外したらAlternative Controller for HHKBを背面パネルにネジ止めし、コネクタを差して(BT版の場合はLiPoバッテリも)フタを閉めてネジ止めすれば差し替え完了。

Alternative Controller for HHKBの詳細を知りたい場合は[Keyboard Controller Board for HHKB](https://github.com/tmk/HHKB_controller)を参照すること。PCBのレイアウトやハンダ付けされている部品のリストがある。なお、PCBレイアウトは[KiCad](http://kicad-pcb.org/)で閲覧できる。

BT版もUSB版と同じPCBを用いているようなので、USB版を購入しても後で必要な部品をハンダ付けすればBT版になると思われるが、表面実装基板であることや部品のサイズを十分考慮し、それでもできる知識と自信がある人は挑戦してみてもいいと思う。

## ファームウェア
Alternative Controller for HHKBはファームウェアを書き換えることでHHKBのキーマップを自由に変更することができる。

対応しているファームウェアとして[Topic: [TMK] Alt Controller Board for HHKB](https://geekhack.org/index.php?topic=71517.0)に書かれているのは[TMK Keyboard Firmware Collection](https://github.com/tmk/tmk_keyboard)だが、TMK Keyboard Firmware Collection(TMK)から派生した[Quantum Mechanical Keyboard Firmware](https://github.com/jackhumbert/qmk_firmware)でも動作する。

Quantum Mechanical Keyboard Firmware(QMK)の方が色々と機能拡張されているので、キーマップの定義で少しだけ楽をしたかったり凝ったことをしたいのであればQMKを使うといいと思われる。QMKは機能拡張されている分、作成されるファームウェアのサイズも大きくなるため注意が必要だが、サイズが問題となることはおそらくない。万一、色々カスタマイズしてサイズが大きくなりすぎてしまった場合は、デバッグ出力など不要なオプションをなしにしてファームウェアをビルドすればサイズを小さくできる。

## ファームウェア機能紹介
ファームウェアの機能をいくつか紹介しておく。キーマップの定義方法は各Readmeやサンプルを参照。

### キーマップの切り替え
複数のキーマップ(32レイヤー)が定義でき、一時的に他のレイヤーを有効することができる。これにより、US配列やDvorak配列など配列自体を変更したり、DIPスイッチで行っていたようなキーの入れ替え、Fnキーを押しながら入力するF1〜F12キーやカーソルキーなどの定義ができる。

### マウスキー
使い勝手はあまりよくないが、マウスカーソルやマウスのボタン、ホイールが操作できるマウスキーが使用できる。

### メディアキー
OSがサポートしているメディアキー(音量操作、再生、停止、早送り、巻き戻し)が使用できる。

### システムキー
OSのスリープやシャットダウンなどの制御ができるシステムキーが使用できる。

### ファンクションキー
定義したアクションやマクロを割り当てたり、自分で書いたコードで制御できるキー。32キーまで定義できる。レイヤーを切り替えたりするのにも必要となる。
TMKではファンクションキーを定義しなければできないことでも、QMKならC言語マクロを使ってキーマップを定義できるように拡張されているため、基本的な機能ならファンクションキーを使わずに同等機能を実現できる。万一32キーでは足りない場合はQMKを使用するとよい。

### NKRO
複数キーを同時に押しても押したことを認識させられるn-key rolloverに対応。Alt、Ctrl、Shift、Meta(WindowsキーやCommandキー)のModifier Key(修飾キー)左右含めて8キー以外に、標準では6キーまで(7キー目以降は無視)認識されられるが、ビルドオプション`NKRO_ENABLE`を`yes`にすると120キーまで拡張できる。
128キーも同時に押せないし、押せたとしても何に使うのかは不明だが。

###### 2016/09/11追記

`NKRO_ENABLE`を`yes`にした時のHIDレポートサイズのデフォルト値が32byteに変更されたため、現在は248キーまでの同時押しが理論上可能になっている。

### Magic Commands
特定のキーの組み合わせで実行できるコマンド。hid_listenerを使ったデバッグ時に有用なコマンドや、一部のレイヤーへの切り替えができるコマンドがある。ビルドオプションによっては意味のないコマンドもある。

### Boot Magic Configuration
キーボードの電源ON時(USB接続ならUSB接続時)に特定のキーが押されていると実行できるコマンド。キーマップの変更なしで特定のキーを入れ替えたりもできる(Virtual DIP Switch)。

### キーアクション
1つのキーでCtrl+Alt+Deleteを押したようにするといったように、複数の修飾キーと1つの通常キーを組み合わせたアクションや、一定時間内にキーを押して離した時とそうでない場合とで違うキーになる(Dual role)キーを定義できる。

Dual roleの例としては、[SpaceFN](https://geekhack.org/index.php?topic=51069.0)のようにスペースキーを押しながらIJKLキーを押すとカーソルキーになったり、[Space Cadet Shift](http://stevelosh.com/blog/2012/10/a-modern-space-cadet/)のように、左右のShiftキーを一定時間内に押して離すと小括弧が入力され、押し続ければShiftキーとなるといったもの、[Karabiner](https://pqrs.org/osx/karabiner/index.html.ja)にあるようにUS配列のMacで左右のCommandキーを英数・かなキーとしても使えるようにする、といったものがある。

### レイヤーアクション
一時的あるいは永続的に(キーボードの電源が落ちるまで)レイヤーを切り替えることができる。
キーを押すと指定したレイヤーに切り替えるほか、HHKBのFnキーのようにキーを押している間別のレイヤーに切り替えたり、キーを次に押すまで違うレイヤーに切り替える、といったことができるキーを定義できる。

### マクロ
"Hello, world!"と順に入力するマクロを定義しておき、ファンクションキーに定義したマクロを割り当てることで、1つのキーで"Hello, world!"と入力させるようなことができる。

### ファンクションアクション
自分で定義したファンクション(メソッド)を実行するキーを定義できる。コードで書いた通りに実行できる一番汎用的なもの。

### タップダンス(QMKのみ)
一定時間内にキーを1回押して離した時と、一定時間内にキーを押して離すのを2回繰り返した場合とで違うキーになるようなキーを定義できる。

### リーダーキー(QMKのみ)
リーダーキーという特殊なキーを使って、リーダーキーに続けて特定のキーを一定時間内に押した場合に別の動作をさせるようなことができる。

## ファームウェアのビルド環境
本記事初稿時点から、特にQMKの方でビルド環境の構築手順がいくつか変更されたため、ビルド環境の構築手順は各ファームウェアのドキュメントを参照した方が良い。TMKの場合でもQMKのビルド環境をそのまま利用できること、QMKのビルド環境構築はスクリプトを1つ実行するだけで自動的に完了することから、[QMKのドキュメント](https://docs.qmk.fm/#/ja/newbs_getting_started)に従ってビルド環境を構築すると良い。

~~Windows(cygwin)、OSX、Linuxの各環境のツールチェーンがある。Linuxは各パッケージマネージャ、OSXはHomebrewを使って環境構築できるので便利。また、QMKはDockerやVagrantを用いたビルドもできるようなので、環境的な問題がある場合は試してみてもいいだろう。~~

~~環境構築手順はTMK、QMKそれぞれのReadmeに書いてあるので参照すること。TMK、QMKのいずれかの方法で環境構築すれば、後で使用するファームウェアを変更しても同じ環境をそのまま利用してビルドできるはず。~~

~~OSXの場合、QMKではAVR toolchainをソースコードをビルドしてインストールする手順になっているため時間がかかる。時間がかかるのが嫌で少し古いバージョンでもいいのであれば、TMKで示されている通りCrossPack for AVR Developmentを利用するとよい。~~

~~CrossPack for AVR Developmentをインストールする場合は、homebrew-caskを使って~~

```
brew cask install crosspack-avr
```

~~とインストールするとアンインストールも簡単にできて便利。~~

## ファームウェアのビルド方法

### TMKの場合

keyboard/hhkbのパスに移動して

```
make -f Makefile.<variant> KEYMAP=<yourkeymap>
```

でビルドできる。

variantはHHKB JP用なのか、BT用なのかで対象のMakefileを変更する。
Pro/Pro2 USBならばデフォルトのMakefileを使用するので、単に

```
make KEYMAP=<yourkeymap>
```

でよい。

KEYMAPに指定する値は、コンパイルするkeymap_xxx.cのxxxの部分に該当する値。省略するとkeymap_common.cがコンパイルされる。

### QMKの場合

~~keyboards/hhkbのパスに移動して~~

```
make KEYMAP=<yourkeymap>
```

~~または~~

```
make keymap=<yourkeymap>
```

~~でビルドできる。KEYMAPは大文字でも小文字でもいいようだ。
KEYMAPに指定する値は、keyboards/hhkb/keymaps以下のフォルダ名になる。フォルダ名を指定する代わりに、コンパイルするファイル名はkeymap.c固定となる。~~
~~makeを実行するパスを変えて、ビルドするキーボードとキーマップを指定する方法もある。~~

###### 2016/09/11追記

~~Makefileの構造の改修が入ったため、現在は上記以外にもQMKのルートフォルダで~~

```
make <yourkeyboard>-<yourkeymap>
```

~~と実行することでもビルドできるようになった。~~

###### 最新の方法
詳細は[初めてのファームウェアを構築する](https://docs.qmk.fm/#/ja/newbs_building_firmware)を参照。

```
make <yourkeyboard>:<yourkeymap>
```

## ファームウェアの書き込み

ファームウェアを書き込むには、Alternative Contoller for HHKBにある赤いスイッチ(DIPスイッチのあったところにある)を押してATmega32U4のブートローダを起動する必要がある。

### TMKの場合

keyboard/hhkbのパスに移動して

```
make KEYMAP=<yourkeymap> dfu
```

などとコンパイル時のオプションに`dfu`を追加することでファームウェアが書き込める。

ブートローダを起動するとHHKBはキーボードとして使用できなくなるので、コマンドを実行してから書き込みデバイス待機中に赤いスイッチを押してブートローダを起動するか、別のキーボードかソフトウェアキーボードを使用してコマンドを実行する。ファームウェアを書き込むと自動的に再起動され、再びキーボードとして使用できるようになる。
誤ってブートローダを起動した場合は、単にHHKBのUSBケーブルを抜くなどして電源を入れ直すか

```
dfu-programmer atmega32u4 reset
```

とコマンドを実行して再起動すると再びキーボードとして使用できるようになる。

### QMKの場合

###### 2016/09/11追記

~~Makefileの構造の改修が入ったため、現在は上記以外にもQMKのルートフォルダで~~

```
make <yourkeyboard>-<yourkeymap>-dfu
```

~~と実行することでもファームウェアの書き込みができるようになった。~~

###### 最新の方法
詳細は[ファームウェアを書き込む](https://docs.qmk.fm/#/ja/newbs_flashing)を参照。

```
make <yourkeyboard>:<yourkeymap>:flash
```

## 動作確認・デバッグ
ビルドオプションで`CONSOLE_ENABLE`を`yes`にしてビルドし、[The HID Listen Program](https://www.pjrc.com/teensy/hid_listen.html)を使うことで`dprint()`や`dprintf()`などで出力したデバッグメッセージが確認できる。押されているキー情報となるHIDのレポートも表示されるので非常に便利。

ちなみに、hid_listen(Windowsならhid_listen.exe、OSXならhid_listen.mac)を実行しただけではダメで、ファームウェアに実装されているMagic CommandsでデバッグONに切り替えなければならない。
Magic Commandsを実行するには、Magicキー(デフォルトでは左Shiftと右Shift)と対象のコマンド(デバッグのON/OFF切り替えの場合は`d`)の3つのキーを同時に押す。デバッグのON/OFF切り替え以外のコマンドはTMKのReadme参照。

## HIDレポート
hid_listenを使用してデバッグモードで見ることができるHIDレポートは`NKRO_ENABLE`が`yes`かどうかでレポートのサイズが変わる。

#### 6KROの場合

byte | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 
:---:|---|---|---|---|---|---|---|---
内容 | Modifier | 0x00(固定) | キー1 | キー2 | キー3 | キー4 | キー5 | キー6

Modifierの値は以下の通り。

bit | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
----|---|---|---|---|---|---|---|---
内容 | 左Ctrl | 左Shift | 左Alt | 左Gui | 右Ctrl | 右Shift | 右Alt | 右Gui

従って、左Ctrlと左Shiftを同時に押した場合、`0x03`となる。

各キーには、[HID Usage Tables 1.12](http://www.usb.org/developers/hidpage/Hut1_12v2.pdf)の10章Keyboard/Keypad Page (0x07)にあるUsage IDの値が設定される。

#### NKRO(NKRO OFF)の場合

byte | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15
:---:|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---
内容 | Modifier | 0x00(固定) | キー1 | キー2 | キー3 | キー4 | キー5 | キー6 | キー7 | キー8 | キー9 | キー10 | キー11 | キー12 | キー13 | キー14

`NKRO_ENABLE`を`yes`にするとHIDレポートサイズが倍になるため、同時押しを認識させられるキー数が増える。Magic CommandでNKROの設定をOFF(Magic Command+`s`で確認できる`keyboard_nkro`の値を`0`)にした場合は、6KROと同じ方式で値が設定されるため14キーまでの同時押しになる。

#### NKRO(NKRO ON)の場合

byte | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15
:---:|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---
内容 | Modifier | Usage ID 0x00〜0x07 | 0x08〜0x0F | 0x10〜0x17 | 0x18〜0x1F | 0x20〜0x27 | 0x28〜0x2F | 0x30〜0x37 | 0x38〜0x3F | 0x40〜0x47 | 0x48〜0x4F | 0x50〜0x57 | 0x58〜0x5F | 0x60〜0x67 | 0x68〜0x6F | 0x70〜0x77

Magic CommandでNKROの設定をON(Magic Command+`s`で確認できる`keyboard_nkro`の値を`1`)にした場合、Modifierの値は同じだがキーの値の設定方法が変わり、押されたキーのUsage IDのbitが`1`に設定される。
従って、1bitあたり1キーで8bit✕15byte=120キーの同時押し(厳密にはUsage ID 0x77までのキーの同時押し)が可能になる。

###### 2016/09/11追記

`NKRO_ENABLE`を`yes`にした時のHIDレポートサイズのデフォルト値が32byteに変更されたため、8bit✕31byte=248キーの同時押し(厳密にはUsage ID 0xF7までのキーの同時押し)が可能になる。Usage ID 0xE8以降は予約済みにはなっているものの未使用のため、理論上全キーの同時押しが可能となっている。

## Usage IDとキー
OSやキーボードの配列とキーの対応は以下の通り。空欄は未確認または無効キー。キーマップを定義して調べれば分かるはずだが面倒なので放置。

Usage ID | Usage Name | Windows(JIS配列) | Windows(US配列) | OSX(JIS配列) | OSX(US配列)
:-:|---|:-:|:-:|:-:|:-:
0x04 | Keyboard a and A | a A | a A | a A | a A
0x05 | Keyboard b and B | b B | b B | b B | b B
0x06 | Keyboard c and C | c C | c C | c C | c C
0x07 | Keyboard d and D | d D | d D | d D | d D
0x08 | Keyboard e and E | e E | e E | e E | e E
0x09 | Keyboard f and F | f F | f F | f F | f F
0x0A | Keyboard g and G | g G | g G | g G | g G
0x0B | Keyboard h and H | h H | h H | h H | h H
0x0C | Keyboard i and I | i I | i I | i I | i I
0x0D | Keyboard j and J | j J | j J | j J | j J
0x0E | Keyboard k and K | k K | k K | k K | k K
0x0F | Keyboard l and L | l L | l L | l L | l L
0x10 | Keyboard m and M | m M | m M | m M | m M
0x11 | Keyboard n and N | n N | n N | n N | n N
0x12 | Keyboard o and O | o O | o O | o O | o O
0x13 | Keyboard p and P | p P | p P | p P | p P
0x14 | Keyboard q and Q | q Q | q Q | q Q | q Q
0x15 | Keyboard r and R | r R | r R | r R | r R
0x16 | Keyboard s and S | s S | s S | s S | s S
0x17 | Keyboard t and T | t T | t T | t T | t T
0x18 | Keyboard u and U | u U | u U | u U | u U
0x19 | Keyboard v and V | v V | v V | v V | v V
0x1A | Keyboard w and W | w W | w W | w W | w W
0x1B | Keyboard x and X | x X | x X | x X | x X
0x1C | Keyboard y and Y | y Y | y Y | y Y | y Y
0x1D | Keyboard z and Z | z Z | z Z | z Z | z Z
0x1E | Keyboard 1 and ! | 1 ! | 1 ! | 1 ! | 1 !
0x1F | Keyboard 2 and @ | 2 " | 2 @ | 2 " | 2 @
0x20 | Keyboard 3 and # | 3 # | 3 # | 3 # | 3 #
0x21 | Keyboard 4 and $ | 4 $ | 4 $ | 4 $ | 4 $
0x22 | Keyboard 5 and % | 5 % | 5 % | 5 % | 5 %
0x23 | Keyboard 6 and ^ | 6 & | 6 ^ | 6 & | 6 ^
0x24 | Keyboard 7 and & | 7 ' | 7 & | 7 ' | 7 &
0x25 | Keyboard 8 and * | 8 ( | 8 * | 8 ( | 8 *
0x26 | Keyboard 9 and ( | 9 ) | 9 ( | 9 ) | 9 (
0x27 | Keyboard 0 and ) | 0 | 0 ) | 0 | 0 )
0x28 | Keyboard Return (Enter) | Return | Return | Return | Return
0x29 | Keyboard Escape | Escape | Escape | Escape | Escape
0x2A | Keyboard Delete (Backspace) | Backspace | Backspace | Backspace | Backspace
0x2B | Keyboard Tab | Tab | Tab | Tab | Tab
0x2C | Keyboard Spacebar | Spacebar | Spacebar | Spacebar | Spacebar
0x2D | Keyboard - and (underscore) | - = | - _ | - = | - _
0x2E | Keyboard = and + | ^ ~ | = + | ^ ~ | = + 
0x2F | Keyboard [ and { | @ \` | [ { | @ \` | [ {
0x30 | Keyboard ] and } | [ { | ] } | [ { | ] }
0x31 | Keyboard \ and &#x7C; | ] } | \ &#x7C; | ] } | \ &#x7C;
0x32 | Keyboard Non-US # and ~ | ] } | \ &#x7C; | ] } | \ &#x7C;
0x33 | Keyboard ; and : | ; + | ; : | ; + | ; :
0x34 | Keyboard ' and " | : * | ' " | : * | ' "
0x35 | Keyboard Grave Accent and Tilde | 半角/全角 | \` ~ | \` ~ | \` ~
0x36 | Keyboard , and < | , < | , < | , < | , <
0x37 | Keyboard . and > | . > | . > | . > | . >
0x38 | Keyboard / and ? | / ? | / ? | / ? | / ?
0x39 | Keyboard Caps Lock | Caps Lock | Caps Lock | Caps Lock | Caps Lock
0x3A | Keyboard F1 | F1 | F1 | F1 | F1
0x3B | Keyboard F2 | F2 | F2 | F2 | F2
0x3C | Keyboard F3 | F3 | F3 | F3 | F3
0x3D | Keyboard F4 | F4 | F4 | F4 | F4
0x3E | Keyboard F5 | F5 | F5 | F5 | F5
0x3F | Keyboard F6 | F6 | F6 | F6 | F6
0x40 | Keyboard F7 | F7 | F7 | F7 | F7
0x41 | Keyboard F8 | F8 | F8 | F8 | F8
0x42 | Keyboard F9 | F9 | F9 | F9 | F9
0x43 | Keyboard F10 | F10 | F10 | F10 | F10
0x44 | Keyboard F11 | F11 | F11 | F11 | F11
0x45 | Keyboard F12 | F12 | F12 | F12 | F12
0x46 | Keyboard PrintScreen | PrintScreen | PrintScreen |  |
0x47 | Keyboard Scroll Lock | Scroll Lock | Scroll Lock |  |
0x48 | Keyboard Pause | Pause | Pause |  |
0x49 | Keyboard Insert | Insert | Insert |  |
0x4A | Keyboard Home | Home | Home | Home | Home
0x4B | Keyboard PageUp | PageUp | PageUp | PageUp | PageUp
0x4C | Keyboard Delete Forward | Delete | Delete | Delete | Delete
0x4D | Keyboard End | End | End | End | End
0x4E | Keyboard PageDown | PageDown | PageDown | PageDown | PageDown
0x4F | Keyboard RightArrow | RightArrow | RightArrow | RightArrow | RightArrow
0x50 | Keyboard LeftArrow | LeftArrow | LeftArrow | LeftArrow | LeftArrow
0x51 | Keyboard DownArrow | DownArrow | DownArrow | DownArrow | DownArrow
0x52 | Keyboard UpArrow | UpArrow | UpArrow | UpArrow | UpArrow
0x53 | Keypad Num Lock and Clear | Num Lock | Num Lock | Clear | Clear
0x54 | Keypad / | / | / | / | /
0x55 | Keypad * | * | * | * | *
0x56 | Keypad - | - | - | - | -
0x57 | Keypad + | + | + | + | +
0x58 | Keypad Enter | Enter | Enter | Enter | Enter
0x59 | Keypad 1 and End | 1 | 1 | 1 | 1
0x5A | Keypad 2 and Down Arrow | 2 | 2 | 2 | 2
0x5B | Keypad 3 and PageDn | 3 | 3 | 3 | 3
0x5C | Keypad 4 and Left Arrow | 4 | 4 | 4 | 4
0x5D | Keypad 5 | 5 | 5 | 5 | 5
0x5E | Keypad 6 and Right Arrow | 6 | 6 | 6 | 6
0x5F | Keypad 7 and Home | 7 | 7 | 7 | 7
0x60 | Keypad 8 and Up Arrow | 8 | 8 | 8 | 8
0x61 | Keypad 9 and PageUp | 9 | 9 | 9 | 9
0x62 | Keypad 0 and Insert | 0 | 0 | 0 | 0
0x63 | Keypad . and Delete | . | . | . | .
0x64 | Keyboard Non-US \\ and \|  |  |  |  |
0x65 | Keyboard Application | Application | Application |  |
0x66 | Keyboard Power | Power | Power | Power | Power
0x67 | Keypad = | = | = | = | =
0x68 | Keyboard F13 | F13 | F13 | F13 | F13
0x69 | Keypoard F14 | F14 | F14 | F14 | F14
0x6A | Keyboard F15 | F15 | F15 | F15 | F15
0x6B | Keyboard F16 | F16 | F16 | F16 | F16
0x6C | Keyboard F17 | F17 | F17 | F17 | F17
0x6D | Keyboard F18 | F18 | F18 | F18 | F18
0x6E | Keyboard F19 | F19 | F19 | F19 | F19
0x6F | Keyboard F20 |  |  |  |
0x70 | Keyboard F21 |  |  |  |
0x71 | Keyboard F22 |  |  |  |
0x72 | Keyboard F23 |  |  |  |
0x73 | Keyboard F24 |  |  |  |
0x74 | Keyboard Execute |  |  |  |
0x75 | Keyboard Help |  |  |  |
0x76 | Keyboard Menu |  |  |  |
0x77 | Keyboard Select |  |  |  |
0x78 | Keyboard Stop |  |  |  |
0x79 | Keyboard Again |  |  |  |
0x7A | Keyboard Undo |  |  |  |
0x7B | Keyboard Cut |  |  |  |
0x7C | Keyboard Copy |  |  |  |
0x7D | Keyboard Paste |  |  |  |
0x7E | Keyboard Find |  |  |  |
0x7F | Keyboard Mute |  |  |  |
0x80 | Keyboard Volume Up |  |  |  |
0x81 | Keyboard Volume Down |  |  |  |
0x82 | Keyboard Locking Caps Lock |  |  |  |
0x83 | Keyboard Locking Num Lock |  |  |  |
0x84 | Keyboard Locking Scroll Lock |  |  |  |
0x85 | Keypad Comma |  |  |  |
0x86 | Keypad Equal Sign |  |  |  |
0x87 | Keyboard International1 | \ _ |  |  |
0x88 | Keyboard International2 | ひらがな カタカナ |  |  |
0x89 | Keyboard International3 | ¥ &#x7C; |  | ¥ &#x7C; 
0x8A | Keyboard International4 | 変換 |  |  |
0x8B | Keyboard International5 | 無変換 |  |  |
0x8C | Keyboard International6 |  |  |  |
0x8D | Keyboard International7 |  |  |  |
0x8E | Keyboard International8 |  |  |  |
0x8F | Keyboard International9 |  |  |  |
0x90 | Keyboard LANG1 |  |  | かな カナ |
0x91 | Keyboard LANG2 |  |  | 英数 |
0x92 | Keyboard LANG3 |  |  |  |
0x93 | Keyboard LANG4 |  |  |  |
0x94 | Keyboard LANG5 |  |  |  |
0x95 | Keyboard LANG6 |  |  |  |
0x96 | Keyboard LANG7 |  |  |  |
0x97 | Keyboard LANG8 |  |  |  |
0x98 | Keyboard LANG9 |  |  |  |
0x99 | Keyboard Alternate Erase |  |  |  |
0x9A | Keyboard SysReq/Attention |  |  |  |
0x9B | Keyboard Cancel |  |  |  |
0x9C | Keyboard Clear |  |  |  |
0x9D | Keyboard Prior |  |  |  |
0x9E | Keyboard Return |  |  |  |
0x9F | Keyboard Separator |  |  |  |
0xA0 | Keyboard Out |  |  |  |
0xA1 | Keyboard Oper |  |  |  |
0xA2 | Keyboard Clear/Again |  |  |  |
0xA3 | Keyboard CrSel/Props |  |  |  |
0xA4 | Keyboard ExSel |  |  |  |
0xB0 | Keypad 00 |  |  |  |
0xB1 | Keypad 000 |  |  |  |
0xB2 | Thousands Separator |  |  |  |
0xB3 | Decimal Separator |  |  |  |
0xB4 | Currency Unit |  |  |  |
0xB5 | Currency Sub-unit |  |  |  |
0xB6 | Keypad ( |  |  |  |
0xB7 | Keypad ) |  |  |  |
0xB8 | Keypad { |  |  |  |
0xB9 | Keypad } |  |  |  |
0xBA | Keypad Tab |  |  |  |
0xBB | Keypad Backspace |  |  |  |
0xBC | Keypad A |  |  |  |
0xBD | Keypad B |  |  |  |
0xBE | Keypad C |  |  |  |
0xBF | Keypad D |  |  |  |
0xC0 | Keypad E |  |  |  |
0xC1 | Keypad F |  |  |  |
0xC2 | Keypad XOR |  |  |  |
0xC3 | Keypad ^ |  |  |  |
0xC4 | Keypad % |  |  |  |
0xC5 | Keypad < |  |  |  |
0xC6 | Keypad > |  |  |  |
0xC7 | Keypad & |  |  |  |
0xC8 | Keypad && |  |  |  |
0xC9 | Keypad &#x7C; |  |  |  |
0xCA | Keypad &#x7C;&#x7C; |  |  |  |
0xCB | Keypad : |  |  |  |
0xCC | Keypad # |  |  |  |
0xCD | Keypad Space |  |  |  |
0xCE | Keypad @ |  |  |  |
0xCF | Keypad ! |  |  |  |
0xD0 | Keypad Memory Store |  |  |  |
0xD1 | Keypad Memory Recall |  |  |  |
0xD2 | Keypad Memory Clear |  |  |  |
0xD3 | Keypad Memory Add |  |  |  |
0xD4 | Keypad Memory Subtract |  |  |  |
0xD5 | Keypad Memory Multiply |  |  |  |
0xD6 | Keypad Memory Divide |  |  |  |
0xD7 | Keypad +/- |  |  |  |
0xD8 | Keypad Clear |  |  |  |
0xD9 | Keypad Clear Entry |  |  |  |
0xDA | Keypad Binary |  |  |  |
0xDB | Keypad Octal |  |  |  |
0xDC | Keypad Decimal |  |  |  |
0xDD | Keypad Hexadecimal |  |  |  |
0xE0 | Keyboard LeftControl | Left Ctrl | Left Ctrl | Left Ctrl | Left Ctrl
0xE1 | Keyboard LeftShift | Left Shift | Left Shift | Left Shift | Left Shift
0xE2 | Keyboard LeftAlt | Left Alt | Left Alt | Left Option | Left Option
0xE3 | Keyboard Left GUI | Left Windows | Left Windows | Left Command | Left Command
0xE4 | Keyboard RightControl | Right Ctrl | Right Ctrl | Right Ctrl | Right Ctrl
0xE5 | Keyboard RightShift | Right Shift | Right Shift | Right Shift | Right Shift
0xE6 | Keyboard RightAlt | Right Alt | Right Alt | Right Option | Right Option
0xE7 | Keyboard Right GUI | Right Windows | Right Windows | Right Command | Right Command

## My Keymap
QMKで作成したキーマップをPRしたらマージされた。[My Keymap](https://github.com/jackhumbert/qmk_firmware/tree/master/keyboards/hhkb/keymaps/shela)
Windows環境でレジストリをいじってもUS配列として認識されない環境があったため、JIS配列として認識されてもUS配列と同じ文字が入力できるレイヤーを作成している。

## まとめなど
HHKB以外にも、FilcoのMajestouchやCoolerMasterのQuick Fireといった既成品のキーボードのコントローラを差し替えてフルプログラマブルにする[Costar replacement controllers](https://deskthority.net/wiki/Costar_replacement_controllers)がある。

TMKやQMKは汎用キーボードファームウェアなので、Alternative Controller for HHKB以外にも、一部界隈で流行りの[ErgoDox Ez](https://ergodox-ez.com/)、DIYの省スペースキーボードである[Clueboard](http://clueboard.co/)や[GH60](http://blog.komar.be/projects/gh60-programmable-keyboard/)、[Planck](http://olkb.com/planck/)といったキーボードのファームウェアとしても使える。