QMK Firmware で adjust レイヤーへの切り替え方法

40%キーボードを使用している場合、raise,lower 同時押しで adjust とする設定はよく使われていると思われる。QMK Firmware での設定方法を3つ記載する。

前提

レイヤーは以下の4つとし、それぞれ記載の通りとする。

  • base … デフォルトレイヤー
  • lower … デフォルトレイヤーからアクティブにできる
  • raise … デフォルトレイヤーからアクティブにできる
  • adjust … lower,raise レイヤーからアクティブにできる

レイヤーキーのみで実装する方法

レイヤーキーはホールド状態でアクティブになる LT,MO を使用する。この記事ではより簡易的な MO で説明する。

  • MO(layer) … ホールド状態で layer をアクティブにする。
  • LT(layer, kc) … ホールド状態で layer をアクティブにする。タップで kc を送信する。

base レイヤーに MO(lower) や MO(raise) を設定する。また lower,raise レイヤーには MO(adjust) を設定する。最もシンプルで、プログラムが苦手な人にも実装しやすい。

const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
    [_BASE  ] = LAYOUT( MO(_LOWER)  , MO(_RAISE ) ),
    [_LOWER ] = LAYOUT( XXXXXXXX    , MO(_ADJUST) ),
    [_RAISE ] = LAYOUT( MO(_ADJUST) , XXXXXXXX    ),
    [_ADJUST] = LAYOUT( XXXXXXXX    , XXXXXXXX    ),
};

レイヤーキーの詳細は QMK Firmware のドキュメントを参照。

サンプルを用意した。

レイヤーキー + update_tri_layer

以下のように lower,raise のカスタムキーコードを設定する。

enum custom_keycodes {
    C_LOWER = SAFE_RANGE,
    C_RAISE,
};

const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
    [_BASE  ] = LAYOUT( C_LOWER     , C_RAISE     ),
    [_LOWER ] = LAYOUT( XXXXXXXX    , C_RAISE     ),
    [_RAISE ] = LAYOUT( C_LOWER     , XXXXXXXX    ),
    [_ADJUST] = LAYOUT( XXXXXXXX    , XXXXXXXX    ),
};

カスタムキーコードを MO(lower) の代わりに C_LOWER としてキーマップに設定する。process_record_user 関数でカスタムキーコードに対する処理を実装し、layer_on,layer_off と一緒に update_tri_layer を記述する。

bool process_record_user(uint16_t keycode, keyrecord_t *record) {

    switch (keycode) {
        case C_LOWER:
            if (record->event.pressed) {
                layer_on(_LOWER);
                update_tri_layer(_LOWER, _RAISE, _ADJUST);
            } else {
                layer_off(_LOWER);
                update_tri_layer(_LOWER, _RAISE, _ADJUST);
            }
            return false;
            break;

        case C_RAISE:
            if (record->event.pressed) {
                layer_on(_RAISE);
                update_tri_layer(_LOWER, _RAISE, _ADJUST);
            } else {
                layer_off(_RAISE);
                update_tri_layer(_LOWER, _RAISE, _ADJUST);
            }
            return false;
            break;

        default:
            break;
    }

    return true;
}

この方法で実装すると以下のような動きになる。

  1. C_LOWER をホールド。lower レイヤーがアクティブになる。
  2. C_RAISE をホールド。( lower,raise の掛け合わせで) adjust レイヤーになる。
  3. C_RAISE を離す。lower レイヤーがアクティブになる。
  4. C_RAISE をホールド。( lower,raise の掛け合わせで) adjust レイヤーになる。
  5. C_LOWER を離す。raise レイヤーがアクティブになる。

上記の挙動は MO,LT で実装する方法では出来ない、より直感的な操作になる。

update_tri_layer の詳細は QMK Firmware のドキュメントを参照。

サンプルを用意した。

レイヤーキー + update_tri_layer_state

update_tri_layer と類似した機能。layer_on,layer_off で layer_state_set_user が呼び出されるため、その中で update_tri_layer_state を実装する。

layer_state_t layer_state_set_user(layer_state_t state) {
    return update_tri_layer_state(state, _LOWER, _RAISE, _ADJUST);
}

bool process_record_user(uint16_t keycode, keyrecord_t *record) {

    switch (keycode) {
        case C_LOWER:
            if (record->event.pressed) {
                layer_on(_LOWER);
            } else {
                layer_off(_LOWER);
            }
            return false;
            break;

        case C_RAISE:
            if (record->event.pressed) {
                layer_on(_RAISE);
            } else {
                layer_off(_RAISE);
            }
            return false;
            break;

        default:
            break;
    }

    return true;
}

簡易的に実装する場合は update_tri_layer_state、細かい制御をしたい場合は update_tri_layer と使い分けすると良さそうだ。

update_tri_layer_state の詳細は QMK Firmware のドキュメントを参照。

サンプルを用意した。

まとめ

enum custom_keycodes {
    C_LOWER = SAFE_RANGE,
    C_RAISE,
    C_ADJUST,
};

const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
    [_BASE  ] = LAYOUT( C_LOWER     , C_RAISE     ),
    [_LOWER ] = LAYOUT( XXXXXXXX    , C_ADJUST    ),
    [_RAISE ] = LAYOUT( C_ADJUST    , XXXXXXXX    ),
    [_ADJUST] = LAYOUT( XXXXXXXX    , XXXXXXXX    ),
};
        case C_ADJUST:
            if (record->event.pressed) {
                layer_on(_ADJUST);
                update_tri_layer(_LOWER, _RAISE, _ADJUST);
            } else {
                layer_off(_ADJUST);
                update_tri_layer(_LOWER, _RAISE, _ADJUST);
            }
            return false;
            break;

私は正しく理解しない状態でこの実装を行い、半年以上も直感的でない操作にモヤモヤしていた。改めてドキュメントに目を通してみると答えはそこに書かれていたのだ。ドキュメントは偉大である。

QMK Firmwareでの自分のソースコード管理

QMK Firmwareの自分のキーマップの管理方法について、自分なりの形ができたためメモを兼ねて書いてみる。基本的にはMacの話だが、Windowsでも同様のことは可能だと思う。 画像なし、文章のみ。

個人的な問題点

  • キーマップなどの情報をkeyboardフォルダ配下で管理するように設計されているが、自分のキーマップはQMKにプルリクするつもりがない。
  • keyboard配下のフォルダは階層が深い。深い位置でgit管理したくない。
  • QMK最新版を取得する時は別フォルダで管理したいが、そのたびにローカルクローンを作成したくない。

理想の環境

  • 自分のソースコードはDocument配下でgit管理。
  • QMK本体とは違う場所にあるkeymapのソースをビルドしたい。→課題!

課題の解決方法

  • keyboardフォルダ配下にフォルダのショートカットを作成してビルドするイメージ。
  • ただし通常のショートカットではビルドできないため、シンボリックリンクを使用する。

シンボリックリンクを作成する方法

シンボリックリンクはTerminal.appからコマンドで作成する。コマンドは以下。

$ ln -s (実ファイルのフルパス) (リンクを作成するフルパス)
$ ln -s ~/Document/keyboard/crkbd /QMK/qmk_firmware_hogehoge/keyboard/crkbd

“-s”をつけ忘れると「ハードリンク」が作成される。間違えて作成した場合はゴミ箱へ捨てて作り直せば良い。

参考

https://webrandum.net/alias-symbolic-link/ https://atmarkit.itmedia.co.jp/ait/articles/1605/30/news022.html

シンボリックリンク作成までの手順

  • 自分のソースコードをgitで管理し、Document配下にクローンを作成する。
  • QMK最新版を取得する。
  • QMKのkeyboard配下のフォルダを全て削除する。
  • 以下の流れでシンボリックリンクを作成する。(極力手打ちしない方法)
  • keyboard配下に作成したいシンボリックリンクのフォルダを作成する。
    • Terminal.app を起動し、”ln -s “を入力する。
    • Terminal.app に対して、Document配下のフォルダをD&D。後ろにスペース追加。
    • Terminal.app に対して、keyboard配下のフォルダをD&D。
    • keyboard配下に作成したフォルダを削除
    • Terminal.app のコマンドをenterで実行
    • QMKのmakeコマンドを実行し、ビルドできることを確認

最後に

自分用のメモを兼ねて記事に書いてみた。書いて気になった点を挙げておく。

  • QMKの最新版を別フォルダで管理するのであれば、それごとにローカルクローンを作成した方がいいのではないか。バージョン別にその時ビルドできた環境が残るメリット。(QMK Firmwareのバージョンを分けたい気持ちが強いのでそこまでしなくてもいいかな?微妙)
  • キーボード単位にシンボリックリンクを作成するのではなく、keyboardフォルダ自体のシンボリックリンクの方が手間が減りそう。

ソースコード(キーマップ)をgitで管理できるのはやっぱり大きい。キーマップの変更をバージョン管理できるし、キーマップ以外の部分でがっつり変えたいときはブランチを分けて試すことができる。

ちなみにQMK Firmwareではハイフンのついたフォルダ名はビルド出来ないようなので別ブランチの名前(もしくはcloneするフォルダ名、またはシンボリックリンク名)にはハイフンを入れず、アンダースコアなどで対応した方が良い。

以上

[kp3s] 印刷が始まるまでに時間がかかるのを解消 [備忘録]

kp3sで印刷を開始したところ、ノズルの温度が安定せず10分近く経ってようやく印刷が始まった。

 

そのことをつぶやいていたらアドバイスをいただけた。

 

 

意味を少しでも理解するために以下のサイトを参考。

PID autotune | Marlin Firmware

PID Tuning/ja - RepRap

 

なんとなく分かった気になれたので、200度設定で実行してみる。

  • M303 E0 S200 C8

 

実行するとシリアルモニタには次々出力されるがとりあえず無視し、数分経ったところでシリアルモニタの動きが止まった。

その結果をmoyashiさんから教えてもらったように実行!

印刷を始めたところ、3分後(ヒートベッド60度の時間を含む)には印刷が始まった。

 

思い返すとkp3sを購入した頃はこのくらいで始まっていた気がする。

それが徐々に5分、7分とかかるようになり10分を超えてしまった。

まだ詳しく調べ切れてはいないが、パーツの消耗も関係しているように思うのでその辺りも注意していきたい。

 

cocot46 簡易ビルドログ

cocot46を組み立てたのでビルドログ。

 

パーツチェック

f:id:Hemus:20210918164932j:plain

 

抵抗の半田付け。

f:id:Hemus:20210918165055j:plain

 

ホットスワップの半田付け

f:id:Hemus:20210918165133j:plain

 

ProMicroとアンダーグロウの半田付け

 ※不得意なパーツ。一つも光らなかったので後で直そうかな。

f:id:Hemus:20210918165206j:plain

 

ロータリーエンコーダの半田付け

 ※全部で五箇所半田付けするので、簡単に交換できないんだなと認識。ロータリーエンコーダ沼の人大変そう。

f:id:Hemus:20210918165257j:plain

 

最近愛用しているGateron Yellow Proを装着!

f:id:Hemus:20210918165617j:plain

 

可愛いキーキャップをはめて完成!

 ※写真映え&家での使用には明るくていいかなってキーキャップ。

f:id:Hemus:20210918165703j:plain

 

完全体まであと2点。

1. ロータリーエンコーダのノブがまだ届いてない。

2. 1uトラックボールがまだ届いていない。

 

もともとCorne Cherryが好きなので、キー配列は問題なし。

楽しみなのはロータリーエンコーダとトラックボール。はよ届け。

ロータリーエンコーダには横スクロールを割り当てれると嬉しいんだけど、できるかどうかはわかっていない。

打鍵音・打鍵感は特に問題なく、気持ちよく打鍵できている。

見た目もスリムでカッコいいのでおすすめできるキーボードです。

 

この記事はcocot46で書きました。

 

プログラムでナンプレを解こうとしたら長旅が始まった話3 完

前回

hemus.hatenablog.com

 

前回解けなかったナンプレ

しばらく考えたけど解けそうにもないので、9x9の要素ごとに切り分けて考えていく。

 

左上の9x9を、候補として残る値を表示してみた(*始まりが未確定)。

f:id:Hemus:20210913224943p:plain

左上の9x9

こうしてみると、右下の3x3部分が「他の9x9と連結する」部分で確定しているにも関わらず候補が多く残っているのがわかる。ヒントが足りておらず、解がいくつかあるパターンなのだと思う。連結部分が確定しているので他への影響はないので、仮置きで解いてしまう。

f:id:Hemus:20210913225446p:plain

左上の9x9の解

 

他の部分も見るとわかるが、候補値が非常に多く残っている。この大きさで仮置きしても解けない要因。

これを解くためには先ほどと同じように9x9で解いていくこと。9x9だと解はいくつかあるため一旦解いて当てはめて別の9x9が解けなかったら仮置きが間違ってたと評価しつつ進めていく。

f:id:Hemus:20210913230237p:plain

全体像

 

そんなこんなで、矛盾が出ないよう仮置きしつつ解き進めるとようやく全体が解けた。

f:id:Hemus:20210913230857p:plain

回答

プログラムでビッと決まらず残念ではあるが、解けたことに満足。

 

以上。