はじめに
自作キーボードの世界に足を踏み入れ、splitkb.com の分割キーボードキット「Aurora Sofle v2」を組み立てた。単に組み立てるだけでなく、QMKファームウェアを使って自分好みの挙動に仕立てるところまでを目標にしている。この記事では、ハードウェアの構成からファームウェアのカスタマイズ、そして現在進行形で格闘しているトラブルまでを一通りまとめておく。
なぜSofle v2を選んだか
分割キーボードに興味を持ち始めて色々調べているうちに、オランダのsplitkb.comが出している Aurora Sofle v2 のキットにたどり着いた。完成品を買うという選択肢もあったが、せっかくなら自分の手でパーツを選び、組み立て、ファームウェアも自分好みに書き換えてみたいと思い、キットでの購入を決めた。
ハードウェア構成
今回組んだのは Aurora Sofle v2 Rev1。58キーの分割キーボードで、左右それぞれにOLEDディスプレイを搭載する構成にした。ロータリーエンコーダーは今回は使わない選択をしている。
主なパーツ構成は以下の通り。
| パーツ | 概要 |
|---|---|
| PCBキット | Aurora Sofle v2(MX Hotswap、58キー) |
| コントローラー | Liatris × 2(RP2040ベース、Pro Micro互換) |
| ソケット | Mill Max Low Profile Sockets(Pinsバージョン) |
| トッププレート | Black FR4 × 2枚 |
| ボトムプレート | Black Acrylic × 2枚 |
| 防音シート | Sound Dampening Sheet(Gray)× 2枚 |
| ハードウェアキット | スペーサー、ネジ、ゴム足一式 |
Liatrisは128Mbitフラッシュと23本のGPIOピンを持つRP2040系のコントローラーで、背面にブートローダーボタンがある。ホットスワップ仕様にしたので、MXスイッチであれば後から気軽に交換できる。ただしMX Hotswap版はアクリルのトッププレートが使えない、防音シートはChocスイッチ非対応、といった制約もあるので購入前によく確認しておくとよい。
キットに含まれるものと、別途用意したものを合わせるとこんな構成になった。
組み立てについて
splitkb.com の公式ビルドガイドに沿って進めた。Aurora Sofle v2はKyriaやCorne、Lily58、Helixなどと組み立て手順を共有するシリーズの一つで、ガイドは各ステップの冒頭に「省略可能かどうか」が明記されているのが親切だった。赤枠が注意点、青枠が補足情報という構成で、初めてでも迷いにくい。
組み立てにかかる時間の目安は4〜8時間とされている。はんだ付け経験がない場合は事前にチュートリアルを見ておくことが推奨されており、また組み立て前にPCBの破損チェックとマイコンのフラッシュ動作確認をしておくことが強く勧められている。一度でも組み立てを始めると返品ができなくなる点も見落とせないポイントだ。
QMKファームウェアのセットアップ
ローカルの ~/qmk_firmware を使い、キーマップは keyboards/splitkb/aurora/sofle_v2/keymaps/sofle_keymap/ に配置した。中身は以下のファイル構成になっている。
config.h
keymap.json
keymap.json.bak
led.c
readme.md
rules.mk
source.c
ビルドコマンドはこちら。標準のPro MicroではなくLiatrisを使うため CONVERT_TO=liatris を指定する。
bash
qmk compile \
-kb splitkb/aurora/sofle_v2/rev1 \
-km sofle_keymap \
-e CONVERT_TO=liatris
生成される splitkb_aurora_sofle_v2_rev1_sofle_keymap_liatris.uf2(約73KB)を、ブートローダーモードにしたLiatrisにドラッグ&ドロップして書き込む。Mac上ではブートローダーモードのLiatrisは RPI-RP2 という名前のドライブとして認識される。
書き込み時の注意点として、USB接続中にTRRSケーブルを抜き差ししないことが重要。作業の順番は「USBを外す → TRRSを接続・確認する → USBを接続する」を徹底している。
config.h の設定
c
#pragma once
#define OLED_TIMEOUT 0
#define OLED_BRIGHTNESS 96
#define SPLIT_LAYER_STATE_ENABLE
#define SPLIT_LED_STATE_ENABLE
#define SPLIT_ACTIVITY_ENABLE
#define SPLIT_TRANSACTION_IDS_USER RPC_ID_USER_STATE_SYNC
QMK標準のOLEDタイムアウトは無効化し、消灯処理は独自実装に委ねている。SPLIT_LAYER_STATE_ENABLE と SPLIT_LED_STATE_ENABLE で左右のレイヤー状態とLED状態を同期し、SPLIT_ACTIVITY_ENABLE で左右のキー入力アクティビティも同期する。SPLIT_TRANSACTION_IDS_USER はIME状態などを独自に同期するためのカスタムRPCチャンネルだ。
rules.mk
makefile
SRC += source.c
SRC += led.c
OLED_ENABLE = yes
レイヤー構成
キーマップは4つのレイヤーで構成している。
- Layer 0(ベース): 通常のMac用配列。QWERTY、Ctrl/Shift/Command/Option、Space。右手側の変換キーには
MT(MOD_RSFT, KC_MINS)を使い、タップで「-」、ホールドで右Shiftとして働く。 - Layer 1: F1〜F12、数字記号、矢印キー、括弧、バックスラッシュ、パイプ、
+='"などの記号類。Layer 3へ移動するためのMO(3)もここに配置している。 - Layer 2: Insert、Print Screen、Application、Page Up/Down、矢印、Caps Lock、数字入力などのユーティリティ系。
- Layer 3: 現状はRGB Matrix用のキーコード(
RM_TOGGやRM_HUEUなど)が並んでいるが、rgb_matrix: falseにしているため実質的に機能しておらず、整理候補になっている。
物理レイアウト上、メイン列の B と N の間には空きキー(XXXXXXX)が2つ挟まる点や、親指クラスターが左右5キーずつという構成は、標準的なSofleのASCII図とは異なるので勝手に変更しないよう気をつけている。
独自機能
IME切り替えキー
左右に1つずつ配置した LT(1, KC_NO) を、タップとホールドで使い分けている。
LT(1, KC_NO)
タップ → Ctrl + '(macOSのIME切り替え)
ホールド → Layer 1
タップ時の実装はシンプルで、source.c 側で以下のように送信している。
c
tap_code16(C(KC_QUOT));
Key Override
現在有効にしているKey Overrideは1つだけ。Ctrl+DをDeleteとして扱う。
c
const key_override_t ctrl_d_override =
ko_make_basic(MOD_MASK_CTRL, KC_D, KC_DEL);
const key_override_t *key_overrides[] = {
&ctrl_d_override,
};
導入時には unknown type name 'key_override_t' や implicit declaration of function 'ko_make_basic' といったコンパイルエラーに遭遇し、#include "process_key_override.h" を追加することで解決した。以前検討していたCtrl+HのOverrideは削除済みにしている。
OLEDのカスタム表示
左右のOLEDにはそれぞれ異なる情報を出している。
- 左OLED: 1行目に「LAYER」、その下に現在のレイヤー番号。さらに「CAPS」とON/OFFの状態。
- 右OLED: IMEがOFFのときは何も表示しない黒画面、ONのときだけ「IME」「ON」の文字を表示する。
5分間キー入力がないと左右のOLEDを消灯し、どちらか一方でもキーを押せば両方点灯する仕様を目指している。タイムアウト値はミリ秒指定でこう定義した。
c
#define OLED_IDLE_TIMEOUT 300000 // 300000ms = 5分
これらの状態(IME ON/OFF、OLEDスリープ状態)は独自のSplit Transactionでマスターからスレーブへ同期している。
c
typedef struct {
bool ime_on;
bool oled_sleep;
} user_sync_data_t;
直面している課題
Split通信の左右非対称問題
現在いちばん頭を悩ませているのがこれだ。症状はこうなっている。
- 右側をUSB接続した場合: 左右のキー入力もOLEDも正常
- 左側をUSB接続した場合: 左は正常だが、右のキー入力もOLEDも反応しない
右USB接続時にはすべて正常に動くことから、右側のLiatris自体が完全に故障している可能性は低いと見ている。疑わしいのは左→右方向のSplit通信そのもの、TRRSケーブルやジャック、通信ピン、あるいはSplit Transportやマスター/スレーブの設定周りだ。
切り分けのために、以下の手順を予定している。
- 左右のLiatrisに同一のUF2を書き込み直す
- カスタムOLED/RPC処理を一時的に外し、最小構成で症状を再現するか確認する
- 左USB・右USBそれぞれで、キー入力とOLEDの動作を個別にチェックする
- TRRSケーブル自体を疑い、別のケーブルで試す
- それでも解決しなければTRRSジャックや通信ラインの物理的な状態を確認する
OLEDタイムアウトからの復帰不良
以前、右OLEDだけが5分後に消灯したあと、キーを押しても復帰しないという問題があった。原因として、左右で別々のローカルタイマー(static uint32_t last_activity = 0;)を使っていることが疑われる。今後は、QMKが提供する last_input_activity_elapsed() を SPLIT_ACTIVITY_ENABLE と組み合わせ、左右どちらの入力でもアクティビティが正しく共有される構成に直す予定だ。
macOSとの付き合い方でのメモ
QMKにはMacの「本物のFnキー」をそのまま再現する標準キーコードは存在しない。MacのFnキーはHIDの標準的な仕組みとは別のApple独自の信号であり、加えてVID/PIDがApple製キーボードのものと一致しない限りmacOS側もFnキーとして認識してくれないためだ。非公式パッチで一部再現する試みもあるが、QMK公式にはサポートされていない。結局のところ、レイヤー機能で代替するのが現実的で、今回の構成でも LT(1, KC_NO) のようなレイヤーキーがFnキーの役割を十分に果たしている。
一方で、スクリーンショットのようなmacOS標準ショートカットは、修飾キーの組み合わせとしてそのままQMKに落とし込める。たとえば全画面スクリーンショット(Cmd+Shift+3)は次のように書ける。
c
LGUI(LSFT(KC_3))
今後の優先順位
現時点で残っているタスクを優先度順に並べるとこうなる。
- Split通信の正常化 — 左USB接続時に右側が反応しない原因を特定する
- OLEDタイムアウトの修正 —
last_input_activity_elapsed()を使い、左右どちらの入力でも正しく復帰するようにする - IME状態同期の確認 — IME OFFで右OLEDが黒画面に、ONで「IME / ON」表示になることを実機で検証する
- コードの整理 — 使っていないSplit Transactionや、
rgb_matrix: falseにもかかわらず残っているLayer 3のRGBキー、重複した処理などを削除し、できるだけシンプルな構成に近づける
キーマップ
現在のキーマップは次のとおり。
=== L0 (Base) ===
+-----+-----+-----+-----+-----+-----+ +-----+-----+-----+-----+-----+-----+
| ` | 1 | 2 | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 0 | |
+-----+-----+-----+-----+-----+-----+ +-----+-----+-----+-----+-----+-----+
| Tab | Q | W | E | R | T | | Y | U | I | O | P | Bsp |
+-----+-----+-----+-----+-----+-----+ +-----+-----+-----+-----+-----+-----+
| Ctl | A | S | D | F | G | | H | J | K | L | ; | Ent |
+-----+-----+-----+-----+-----+-----+ +-----+-----+-----+-----+-----+-----+
| Sft | Z | X | C | V | B | | N | M | , | . | / | S/- |
+-----+-----+-----+-----+-----+-----+ +-----+-----+-----+-----+-----+-----+
| Gui*| Alt |MO(2)|MO(1)| Spc | | Spc |MO(1)| Ctl | Alt | Gui*|
+-----+-----+-----+-----+-----+ +-----+-----+-----+-----+-----+
=== L1 ===
+-----+-----+-----+-----+-----+-----+ +-----+-----+-----+-----+-----+-----+
| | | | | | | | | | | | | |
+-----+-----+-----+-----+-----+-----+ +-----+-----+-----+-----+-----+-----+
| Esc | ! | @ | # | $ | % | | ^ | & | * | ( | ) | Del |
+-----+-----+-----+-----+-----+-----+ +-----+-----+-----+-----+-----+-----+
| --- | 1 | 2 | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 0 | Pip |
+-----+-----+-----+-----+-----+-----+ +-----+-----+-----+-----+-----+-----+
| --- | --- | --- | \ | ` | ~ | | = | + | ' | " | [ | ] |
+-----+-----+-----+-----+-----+-----+ +-----+-----+-----+-----+-----+-----+
| --- | --- | --- | --- | --- | | --- | --- | --- | --- | --- |
+-----+-----+-----+-----+-----+ +-----+-----+-----+-----+-----+
=== L2 ===
+-----+-----+-----+-----+-----+-----+ +-----+-----+-----+-----+-----+-----+
| | | | | | | | | | | | | |
+-----+-----+-----+-----+-----+-----+ +-----+-----+-----+-----+-----+-----+
|MO(3)| F11 | F12 | | | Cap | | Mut | VoD | VoU | Prv | Nxt | Stp |
+-----+-----+-----+-----+-----+-----+ +-----+-----+-----+-----+-----+-----+
| --- | F1 | F2 | F3 | F4 | F5 | | Lft | Dwn | Up | Rgt | | Ply |
+-----+-----+-----+-----+-----+-----+ +-----+-----+-----+-----+-----+-----+
| --- | F6 | F7 | F8 | F9 | F10 | | Hom | PgD | PgU | End | | |
+-----+-----+-----+-----+-----+-----+ +-----+-----+-----+-----+-----+-----+
| --- | --- | | | --- | | --- | --- | --- | --- | --- |
+-----+-----+-----+-----+-----+ +-----+-----+-----+-----+-----+
=== L3 ===
+-----+-----+-----+-----+-----+-----+ +-----+-----+-----+-----+-----+-----+
| | | | | | | | | | | | | |
+-----+-----+-----+-----+-----+-----+ +-----+-----+-----+-----+-----+-----+
| | | | | | | | 0 | 7 | 8 | 9 | | Bsp |
+-----+-----+-----+-----+-----+-----+ +-----+-----+-----+-----+-----+-----+
| | | | | | 0 | | 0 | 4 | 5 | 6 | | Ent |
+-----+-----+-----+-----+-----+-----+ +-----+-----+-----+-----+-----+-----+
| | | | | | . | | 0 | 1 | 2 | 3 | | |
+-----+-----+-----+-----+-----+-----+ +-----+-----+-----+-----+-----+-----+
| | | | | | | 0 | . | | | |
+-----+-----+-----+-----+-----+ +-----+-----+-----+-----+-----+
凡例
---: 透過キー(下のレイヤーの割り当てがそのまま有効)- 空白セル: 未割当(キーなし)
S/-: タップで-、ホールドで右ShiftGui*: タップ英数/ホールドGUI、タップかな/ホールドGUIMO(n): ホールドでレイヤーnに一時切替
おわりに
分割キーボードは組み立ての物理的な工程だけでなく、QMKでの挙動設計そのものが楽しい部分でもある。IME切り替えやOLED表示のような細かい作り込みができるのはQMKならではの魅力だと感じている。Split通信の不具合はまだ解決していないが、切り分けを一つずつ進めながら、最終的には左右どちらからUSB接続してもすべての機能が動く状態を目指していく。