遊舎工房スタッフブログ

このブログは遊舎工房スタッフが交代で記事を書いていくというものです。自作キーボードにまつわるものなど、なんでもOKな縛りがないものとなっていますのでバラエティに富んだものになるかと思います。

【アドカレ】自キとの出会い、QMK Firmwareとの和解、8万円吹き飛んだ話

f:id:marby3:20211205193719p:plain

工房マンガ6

 

いつもお久しぶりですで始まってますがお久しぶりです。遊舎工房の倉庫の片隅でガタガタ震えているまーびいです。あと冒頭の漫画、珍しく目から描いてみたけどまぁ許容できる範囲でよかったです。

この度はキーボード #1 Advent Calendar 2021 - Adventarに参加させてもらいました。
前日はアンバーさんの「KATANA60 Clone を作った話」、翌日はsatromiさんの「 エルゴノミクスキーボードネタで何か」です。
遊舎工房に入舎して1年半ほどで、自キ歴も同じ時間なのでまだまだ初心者みたいな物ですが、これまで自作キーボードとどのように向き合ってきたかを書こうと思います。

今回は3本まとめてお話を書いてしまいます。

 

自キとの出会い

そもそも自キとの出会いは人によって様々だと思いますが、僕の場合は特に特殊だと思います。
というのも遊舎工房に入った瞬間に自キに触れるようになったので、
「遊舎工房というお店があるらしいぞ?いそげ~~~!!!」
って感じでした。

いつの間にか入っていたんですよね。不思議です。

しかし、今思うと自作キーボードって様々な人の要望に答えることができる素晴らしい土壌の宝庫のように感じます。
カジュアルであればキーキャップを変えることだけでも楽しめますし、レジンでアルチザンキーキャップを作る、はてはGBに参加する。キーボードを設計したり、ファームウェアで遊んでみたり、写真を撮ってみたりと、ユーザー側が介入できる要素がとても多いです。

もともとものづくりに興味があったので、僕の場合は設計沼に落ちていました。キーボードの設計は楽しいぞ。

 

QMK Firmwareとの和解

QMK Firmwareは自作キーボードコミュニティで特に使われているファームウェアだと思いますが、いつの間にか遊舎工房に入っていた僕はプログラムの知識がほぼありません(ちょっとかじっていたくらい)。

そして、日常ではRazer Orbweaverを使っていたため、ジョイスティックを使いたいと思いました。これが地獄の始まりだとは全く気が付きませんでした。

まずフットプリントがこの世にないので、自分で作る必要がありました。
Kailhのジョイスティックを使う予定なので、型番で調べます。なぜか複数ヒットしたのでAliexpressで問い合わせてみたところ、型番の印字を間違えてしまったとのこと(なんで…?)。

なんとか作ったら今度は電気的な回路が不明でした。

f:id:marby3:20211205150547p:plain

ジョイスティックのフットプリント

幸い一般的なジョイスティックの回路は見つかったので、テストすれば大丈夫そうでした。
そこで、ALLPCBの無料発注を利用してテスト基板を作りました。

f:id:marby3:20211205150503j:plain

ジョイスティックテスト基板

さて、基板は届いたのでファームウェアを書きます。

・・・どうやって?

わからない、わかりません・・・・・・。

ここまで順調だった分、何もわからん状態になりました。

まずは当然公式のドキュメントJoystick - QMKを読みます。
わかりますか?

わからないですよね?

そう、わからないんですよ。
ここで詰みました(約3ヶ月)。

ただ、ヒントがないわけではありませんでした。

ジョイスティックを実装しているキーボードがこの世にはないわけではありません。IC段階ですが、こちらで採用例がありました。>[IC] FLICC Gamepad : MechanicalKeyboards

また、僕と同じく左手キーボード難民のFF14プレイヤーの方が、分かりやすく解説をしてくれていました。>

Turing Hopper 日記「左手デバイス(アナログスティック) なければ作ってしまえ!【自作】 その1 ロストG13に備えて」 | FINAL FANTASY XIV, The Lodestone

他にも参考にしたサイトは多くありますが、特にこの2つによって開発が大きく進み、最終的にはパッド操作、アローキー入力、マウス操作ができるようになりました!
特に大変だったkeymap.cの記述を書いておきます(そして採用例が増えてくれれば舎でジョイスティックが買えるようになるかもしれない…!)。

/* joystick config */
#ifdef JOYSTICK_ENABLE
// Change this
char arrow_keys[4] = {KC_UP, KC_LEFT, KC_DOWN, KC_RIGHT}; // up, left, down, right
static int joystickThreshold = 6; // Value to prevent joystick drift
static int joystickResolution = 24; // Decide the movement speed of the joystick
// Don't chnage this
static uint8_t joystickMode = 0;
static uint8_t joystick_modes = 3; // amount of modes
static int actuation = 255; // actuation point for arrows (0-511)
bool arrows[4];

joystick_config_t joystick_axes[JOYSTICK_AXES_COUNT] = {
    [0] = JOYSTICK_AXIS_VIRTUAL,
    [1] = JOYSTICK_AXIS_VIRTUAL
};

void joystick_task(){
    switch (joystickMode) {
    case 0: // gamepad
        joystick_status.axes[0] = 128 - analogReadPin(F4)/4;
        joystick_status.axes[1] = analogReadPin(F5)/4 - 128;
        joystick_status.status |= JS_UPDATED;
        send_joystick_packet(&joystick_status);
        break;
    case 1: // arrows
        if (!arrows[0] && analogReadPin(F5) - 512 > actuation){
            arrows[0] = true;
            register_code16(arrow_keys[2]);
        }
        else if (arrows[0] &&  analogReadPin(F5) - 512 < actuation){
            arrows[0] = false;
            unregister_code16(arrow_keys[2]);
        }
        if (!arrows[1] && analogReadPin(F5) - 512 < -actuation){
            arrows[1] = true;
            register_code16(arrow_keys[0]);
        }
        else if (arrows[1] && analogReadPin(F5) - 512 > -actuation){
            arrows[1] = false;
            unregister_code16(arrow_keys[0]);
        }
        if (!arrows[2] && analogReadPin(F4) - 512 > actuation){
            arrows[2] = true;
            register_code16(arrow_keys[1]);
        }
        else if (arrows[2] &&  analogReadPin(F4) - 512 < actuation){
            arrows[2] = false;
            unregister_code16(arrow_keys[1]);
        }
        if (!arrows[3] && analogReadPin(F4) - 512 < -actuation){
            arrows[3] = true;
            register_code16(arrow_keys[3]);
        }
        else if (arrows[3] && analogReadPin(F4) - 512 > -actuation){
            arrows[3] = false;
            unregister_code16(arrow_keys[3]);
        }
        break;
    case 2: // mouse
        ;
        report_mouse_t currentReport = pointing_device_get_report();
        currentReport.x = (512 - analogReadPin(F4)) / joystickResolution;
        currentReport.y = (analogReadPin(F5) - 512) / joystickResolution;
        if (currentReport.x < joystickThreshold && currentReport.x > -joystickThreshold){
            currentReport.x = 0;
        }
        if (currentReport.y < joystickThreshold && currentReport.y > -joystickThreshold){
            currentReport.y = 0;
        }
        pointing_device_set_report(currentReport);
        pointing_device_send();
        break;
    }

このコードが動くようになったことで、QMK Firmwareの苦手意識が薄れました。
結果として、RGBMatrix等も理解できるようになりました。たくさん悩んだのと、SMKiJや自キ温泉のDiscordでたくさん質問をしていたので、色んな方に助けてもらった結果だと思います。大変助かりました! ありがとうございます!

実は課題として、左右のジョイスティックの認識を分けたりすることができていません。こちらは今後色々調べることで解決できると信じています。

 

8万円吹き飛んだ

現在に至るまで、販売していない物も含めそこそこキーボードを開発してきました。

  • TenkeyPad ver.Kailh Sun Switch:遊舎工房入舎1~3ヶ月ごろに初めて作ったキーボード。Sunスイッチ専用のテンキー。アクリルをスイッチプレートにしてしまったためゆるゆるで失敗(Sunスイッチはアクリルと相性が悪そう?)。

    f:id:marby3:20211205154539j:plain

  • Bigfoot:Bigスイッチを5つ差し込んで足で操作する基板。発注金額が高すぎて断念。あとスイッチだけで1万円超えちゃうよ。

    f:id:marby3:20211205154742j:plain

  • ESquared64:8x8のキーボード。斜めの人が上位互換を作っていたのでお蔵入り。

    f:id:marby3:20211205154805p:plain

  • Sumeishi:Meishi基板にProMicroを表面実装し、Sunスイッチにも対応。半導体不足による値段上昇で断念。

    f:id:marby3:20211205154858j:plain

  • Tempai13:雀魂(※麻雀のゲーム)をキーボードで操作できれば楽しそうじゃない?って思って1x13の配列で作成。別に遊んでないのに。形状的に不安定になりやすかったため、販売を保留している。

    f:id:marby3:20211205154944j:plain

  • Tyxos63:サリチル酸さんのキーボードプロジェクト「GL516」用に作成した基板。特に問題はなかったので、GL516が開始したらレイアウトを少し修正して販売するかも。

    f:id:marby3:20211205154612j:plain

  • Alico48:人間卒業キーボード。総当りマトリクスを使ってTRRS3本で左右分離をするという異常な発想によってのみできたキーボード。実は売ってる。

    f:id:marby3:20211205154506j:plain

  • HanTenKey17:コンセプト段階。テンキーの縦2Uを左側に移動して、左手テンキー用により使いやすくしたい。縦長ロータリーエンコーダーを使うかも。

    f:id:marby3:20211205155047p:plain

  • Gameco:コンセプト段階。あえてゲームコントローラー風な形状にした積層キーボードで、ジョイスティックとスイッチをつけてゲーム用に使いたい。あと静電容量もこれで使いたいかも。

    f:id:marby3:20211205155202j:plain

 

これだけたくさん作ってきた(作っている)のですが、遊舎工房に入舎した当初から考えていた「Razer Orbweaverと合わせて使う右手キーボード」という概念を導入したSIGNEプロジェクトという物も考えていました。

これは本当に本気で取り組みたかったので、キーボード設計ノウハウを蓄えてから作ることに決めていました。

そして、もう行けるだろう、ということで、Formy46と名前を変えて開発をスタートしました。

f:id:marby3:20211205160021j:plain

初期のFormy46

今考えると、レイアウト的に使いづらいな…とも思うのですが、これでPCBAまで行っちゃいました。20枚。8万円。

8万円もかかったんですよ…。

結果、GNDの配線に多数のミスが発生し、手配線が多数必要になり頒布不能となりました。ぼくのおちんぎんが……。

途中、撮影依頼をお願いした方や、余った基板を差し上げた方に大変ご迷惑をおかけしたのもあり、キーボードの設計は慢心しては駄目だと思い知りました。

みなさん、GNDはちゃんと接続しましょうね!!!!!

 

そして現在、フィードバック等を元にレイアウトを変化したのがFormy46改です。次失敗したら設計やめます……。

f:id:marby3:20211205160700j:plain

Formy46改

 

おわりに

ここまで長々と長文を書いてきましたが、自作キーボードはまだまだ盛り上がることができるコンテンツだと思っています。今年のアドカレが3まで行ったのは凄いことですし。

来年はアドカレ10まで行くといいですね!!!

 

このブログはWT60-C on Bezel(二層アクリルカスタム)で書きました。

f:id:marby3:20211205162532j:plain

 

自作キーボードのお店 遊舎工房

https://yushakobo.jp/