HHKBのコントローラーを換装した話

2018.12.19 hhkb keyboard

こんばんはるかです。

Alternative Controller for HHKBのススメ という記事を見つけて面白そうだったのでやってみました。

*以降この記事では当該コントローラーを本家の掲示板に記載されているHHKB Alt Controllerと記載します。

HHKB Alt Controller とは

HHKB Alt Controllerはhasuさんが開発・販売しているサードパーティ製のコントローラーです。

純正のコントローラーをこのHHKB Alt Controllerに換装することでキー配列を自由に設定できるようになります。

コントローラー基盤を置き換えるだけで改修できます。

購入先

[TMK] HHKB Alt Controller

こちらのトピックに記載されているメールアドレス宛に必要な購入したいHHKB Alt ControllerのモデルととPayPalのアカウントを記載する必要があります。
住所はPayPalの住所に送られるのでしっかり確認してください。

今回はUSB接続のタイプを購入しました。

換装

Alternative Controller for HHKBのススメに詳しいので詳細は省きますが

  1. HHKB本体裏のネジを外す
  2. 純正コントローラーにつながっている虹色のケーブルを外す
  3. 純正コントローラーを外しHHKB Alt Controllerに置き換える
  4. ケーブルを繋ぎ直す
  5. 動作確認
  6. 本体を元に戻してネジ止めする。

この流れになります。
ケーブルが結構硬いのでケーブルにダメージ行かないように注意してください。

キーマップ

WindowsとMacを行ったり来たりするのでWindows用とMac用のレイヤーを用意しました。
まだ詰めきれてはいないのですが、現状のキーマップは以下。

ファームウェアはQMKのものを使っています。

/*  -*-  eval: (turn-on-orgtbl); -*-
 * default HHKB Layout
 */
#include QMK_KEYBOARD_H

#define BASE 0
#define WIN 1
#define HHKB 2

const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
    
    /* BASE Level: Default Layer
     |-------+---+---+---+---+---+---+---+---+---+---+-------+-----+-------+---|
     | Esc   | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | -     | =   | \     | ` |
     |-------+---+---+---+---+---+---+---+---+---+---+-------+-----+-------+---|
     | Tab   | Q | W | E | R | T | Y | U | I | O | P | [     | ]   | Backs |   |
     |-------+---+---+---+---+---+---+---+---+---+---+-------+-----+-------+---|
     | Cont  | A | S | D | F | G | H | J | K | L | ; | '     | Ent |       |   |
     |-------+---+---+---+---+---+---+---+---+---+---+-------+-----+-------+---|
     | Shift | Z | X | C | V | B | N | M | , | . | / | Shift | Fn0 |       |   |
     |-------+---+---+---+---+---+---+---+---+---+---+-------+-----+-------+---|
     
     |------+------+-----------------------+------+------|
     | LAlt | LGUI | ******* Space ******* | RGUI | RAlt |
     |------+------+-----------------------+------+------|
     */
    
    [BASE] = LAYOUT( //  default layer
                    KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSLS, KC_GRV,
                    KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSPC,
                    KC_LCTL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT,
                    KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, MO(HHKB),
                    KC_LALT, MT(KC_LGUI, KC_LANG2), /*        */ SFT_T(KC_SPC), MT(KC_RGUI, KC_LANG1), KC_RALT),
    
    /* BASE Level: Default Layer
     |-------+---+---+---+---+---+---+---+---+---+---+-------+-----+-------+---|
     | Esc   | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | -     | =   | \     | ` |
     |-------+---+---+---+---+---+---+---+---+---+---+-------+-----+-------+---|
     | Tab   | Q | W | E | R | T | Y | U | I | O | P | [     | ]   | Backs |   |
     |-------+---+---+---+---+---+---+---+---+---+---+-------+-----+-------+---|
     | Cont  | A | S | D | F | G | H | J | K | L | ; | '     | Ent |       |   |
     |-------+---+---+---+---+---+---+---+---+---+---+-------+-----+-------+---|
     | Shift | Z | X | C | V | B | N | M | , | . | / | Shift | Fn0 |       |   |
     |-------+---+---+---+---+---+---+---+---+---+---+-------+-----+-------+---|
     
     |------+------+-----------------------+------+------|
     | LGUI | LAlt | ******* Space ******* | RAlt | RGUI |
     |------+------+-----------------------+------+------|
     */
    
    [WIN] = LAYOUT( //  default layer
                    KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSLS, KC_GRV,
                    KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSPC,
                    KC_LCTL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT,
                    KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, MO(HHKB),
                    KC_LGUI, KC_LALT, /*        */ SFT_T(KC_SPC), KC_RALT, KC_RGUI),
    
    /* Layer HHKB: HHKB mode (HHKB Fn)
     |------+-----+-----+-----+----+----+----+----+-----+-----+-----+-----+-------+-------+-----|
     | Pwr  | F1  | F2  | F3  | F4 | F5 | F6 | F7 | F8  | F9  | F10 | F11 | F12   | Ins   | Del |
     |------+-----+-----+-----+----+----+----+----+-----+-----+-----+-----+-------+-------+-----|
     | Caps |     |     |     |    |    |    |    | Psc | Slk | Pus | Up  |       | Backs |     |
     |------+-----+-----+-----+----+----+----+----+-----+-----+-----+-----+-------+-------+-----|
     |      | VoD | VoU | Mut |    |    | *  | /  | Hom | PgU | Lef | Rig | Enter |       |     |
     |------+-----+-----+-----+----+----+----+----+-----+-----+-----+-----+-------+-------+-----|
     |      |     |     |     |    |    | +  | -  | End | PgD | Dow |     |       |       |     |
     |------+-----+-----+-----+----+----+----+----+-----+-----+-----+-----+-------+-------+-----|
     
     |------+------+----------------------+------+------+
     | **** | **** | ******************** | **** | **** |
     |------+------+----------------------+------+------+
     
     */
    
    [HHKB] = LAYOUT(
                    KC_PWR, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_INS, KC_DEL,
                    KC_CAPS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_PSCR, KC_SLCK, KC_PAUS, KC_UP, KC_TRNS, KC_BSPC,
                    KC_TRNS, KC_VOLD, KC_VOLU, KC_MUTE, KC_TRNS, KC_TRNS, KC_PAST, KC_PSLS, KC_HOME, KC_PGUP, KC_LEFT, KC_RGHT, KC_PENT,
                    KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_PPLS, KC_PMNS, KC_END, KC_PGDN, KC_DOWN, KC_TRNS, KC_TRNS,
                    KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS)};

const uint16_t PROGMEM fn_actions[] = {
    
};

const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
{
    // MACRODOWN only works in this function
    switch (id)
    {
        case 0:
            if (record->event.pressed)
            {
                register_code(KC_RSFT);
            }
            else
            {
                unregister_code(KC_RSFT);
            }
            break;
    }
    return MACRO_NONE;
};

換装した感想

今までDIPスイッチいじって対応していた部分がデフォルトレイヤーの切り替えで対応できるようになったのでかなり楽になりました。

QMKの方の機能でもっといろいろカスタムできそうなので使いやすいようにキー配列調整していきたいと思います。

あと全然関係無いんですけど、Realforce Hi-proのキーキャップ(無刻印)だけ販売とかしてほしいので東プレさんお願いします…