🤖

330 円テンキーで作る 20% キーボード (ソフトウェア)

2022/05/04に公開

関連記事

20% キーボード

フルキーボードを片手サイズに収めようとする試みはいくつかあります。
一例を上げると CUT Key や、最近では奏配列[1]など。

従来のアプローチでは片手入力による制約を、入力速度を上げる工夫をこらすことで改善したと謳っていることが多いようです。
文章入力に特化した配列を選択したり、入力可能な記号を絞り込んだり。
一つの方向性とは思いますが、PC の汎用性に時には制限をかけてしまいます。

キーが少なくても、打鍵できるキーの数を妥協しないキーボードに仕立ててみました。
Windows で利用する想定です。ChromeOS, macOS でも検証しています。

基本コンセプト

この 20% キーボードの設計に当たっての基本コンセプトです。

  • アルファベットを First-class citizen とする。
    フルキーボード並に扱い、レイヤーに押し込めない。
  • 修飾キーは Ctrl, Shift を常にアクセス可能にする。
  • JIS フルキーボードを作る。

コンセプトを元に方針を決めました。

  • テンキーの横置きとする。
  • 上 3 行 (15 キー) を文字キーとする。
    下 1 行 (4 キー) を修飾キー・レイヤーキー専用とする。
  • アルファベットの領域を左右分割して、RAISE (+ キー), LOWER (- キー) レイヤーに割り当てる。
    基準のレイヤーとする。
  • シフトキーがレイヤーキーを兼ねる。
  • 記号、数字、操作、ファンクションキー、テンキーのレイヤーを設ける。
  • 基準、操作以外のレイヤーはワンショットとする。

実際に扱ってみて、下記の改良を加えました。

  • レイヤー遷移後は、遷移に使ったキーがシフトキーになる。
  • Fn キーとの同時押しで修飾キーをワンショットロックする。
  • 下 4 キーの同時押しで修飾キーのワンショットロックを全解除する。
  • BackSpace はどちらの基準レイヤーからも同じ操作で呼べるように配置する。
  • Raise, Lower キーの同時押しで半角/全角キーを送出する。
  • 修飾キーは文字キーの中に配置しない。

完成したキーマップは個人リポジトリで公開しています。
キーマップの名前は shuttle19 としました。手が左右で小刻みに動く様から。
クローンしてブランチ keypad12 を参照してください。

$ git clone -b keypad12 https://github.com/tryjsky/qmk_firmware.git
$ qmk flash -kb handwired/keypad12 -km shuttle19

レイヤー

RAISE

左手のアルファベットを送出するレイヤーです。
他レイヤーでの Raise キーがシフトキーになります。
レイヤー遷移と同時に大文字を入力するにはレイヤーキーを二度押しするイメージになります。

LOWER

右手のアルファベットを送出するレイヤーです。
Lower キーで遷移します。
他レイヤーでの Lower キーがシフトキーになります。

RAISE + Fn

記号と左の特殊キーを送出するレイヤーです。
RAISE レイヤーで Fn キーを押してワンショットで遷移します。
ローマ字入力でよく使う長音符号を Fn の対角に配置しています。
Nav は Fn と同時押しのみ、レイヤー遷移が有効です。

RAISE + Fn + Shift

記号と左の特殊キーをシフトキー付きで送出するレイヤーです。
RAISE + Fn レイヤーでシフトキーを押してワンショットで遷移します。

試作で不便に感じたのは、シフトキーを使った記号の連続入力でした。
一文字ごとレイヤーが戻るので、「```」の入力に 9 打鍵が必要になります。
2 つの修飾キーの同時押しはゴーストキーの原因となります。
シフトキーコードを送出する専用レイヤーを導入して連打できるようになりました。

LOWER + Fn

数字と日本語関連の特殊キーを送出するレイヤーです。
LOWER レイヤーで Fn キーを押してワンショットで遷移します。
Nav は Fn と同時押しのみ、レイヤー遷移が有効です。

LOWER + Fn + Shift

数字と日本語関連の特殊キーをシフトキー付きで送出するレイヤーです。
LOWER + Fn レイヤーでシフトキーを押してワンショットで遷移します。

操作キーを送出するレイヤーです。
ファンクションキー、テンキーのレイヤーキーが配置されます。
キーを押してもレイヤーは戻りません。

切り取り Shift + Del、コピー Ctrl + Ins、ペースト Shift + Ins は、レイヤー内で操作可能です。

FN

ファンクションキーと上の特殊キーを送出するレイヤーです。
NAV レイヤーで Fnc キーを押してワンショットで遷移します。
文字キー送出後は基準レイヤーに戻ります。

レイヤー遷移元が NAV のため、文字キーをリリースするタイミングでレイヤー 2 枚を無効化しています。

NUMPAD

テンキーを送出するレイヤーです。
NAV レイヤーで Num キーを押して遷移します。
キーを押してもレイヤーは戻りません。

このレイヤーだけ縦向きです。
常に数字を送出させたかったため、NumLock が無効の場合は NumLock キーコードも前後で送出しています。
ホストから通知された NumLock の LED で判定しています。
OS が LED を制御しない場合は、常に NumLock キーコードが送出されますが特に副作用は出ないようです。

同時押し

修飾キー・ワンショットロック

下 1 行にある Fn キーを押したまま他の修飾キーを押すと、押されたままの扱いになります。
文字キーを押すことで解放されます。

  • Fn + Ctrl Ctrl ロック
  • Fn + Raise Win ロック
  • Fn + Lower Alt ロック

修飾キー・ワンショット解除

下 1 行の修飾キーを全て同時に押すと、修飾キー・ワンショットロックで押されたキーが全て解放されます。
ただし、Key up イベントは無効にならず発生します。

半角/全角

Raise, Lower キーの同時押しで半角/全角キーコードを送出します。
IME ON/OFF のショートカットの扱いです。

ハードウェア固有の設定

NumLock LED

QMK Firmware の機能で NumLock LED は制御されますが、NUMPAD レイヤー遷移を ON/OFF で表現したかったため直接 I/O ポートを制御しています。

config.h
#define LED_PIN_ON_STATE 1

#define LED_NUM_LOCK_PIN D4
<keyboard>.c
#define KEYPAD12_NUMLOCK_LED 4 // D4

void numlock_led_on() {
    PORTD |= (1 << KEYPAD12_NUMLOCK_LED);
}

void numlock_led_off() {
    PORTD &= ~(1 << KEYPAD12_NUMLOCK_LED);
}
keymap.c
layer_state_t layer_state_set_user(layer_state_t state) {
    switch (get_highest_layer(state)) {
        case _NUMPAD:
            numlock_led_on();
            break;

        default:
            numlock_led_off();
    }
    return state;
}

bool led_update_user(led_t led_state) {
    // Control Numlock LED manually
    return false;
}

USB 消費電力

USB 接続時にホストに申告する消費電力が、QMK Firmware の既定値は 500mA です。
バス給電の USB ハブに接続すると給電能力不足と判断されることがあるため、値を修正します。
このキーボードの消費電力は実測で 20mA 前後です。

config.h
#define USB_MAX_POWER_CONSUMPTION 50

アンチ・ゴースト

メンブレンキーボードで同時押しを行うと、ゴーストキーが発生します。
QMK Firmware のアンチ・ゴースト機能を有効にすると、同時入力キーを制限することができます。

config.h
#define MATRIX_HAS_GHOST

未解決の課題

Alt キーを任意のタイミングでリリースできないので、Alt + Tab がうまく動きません。

さいごに

この記事は、キーボード handwired/keypad12 キーマップ shuttle19 で書きました。

脚注
  1. 20(4×5)キーボードを使って左手配列を創案した ↩︎

Discussion