【無限の可能性ビルドガイド】基板設計無しでオリジナルJIS分割キーボードを楽しく自作する

#キットじゃないオリジナル自キー
2019GWあたりにMint60を作ってからUT47.2 → Project Keyboard Alice と来て，
JIS配列も欲しいなーと思ってキットを探してみていたところ，
自分の求める以下の要件に当てはまるものが見つけられなかった[^1]．

- JIS配列
- 60%
- 左右分割
- Row-staggered[^2]
- 方向キーが付いている

早い話がJIS版Mint60みたいなやつ．
そこで，前々から気になっていた[無限の可能性](https://swanmatch.booth.pm/items/1279346) と [ProMicroSocket(プロマイクロのおうち)](https://swanmatch.booth.pm/items/1073313)，
あと各種便利ツールを利用して，ノリと勢いでオリジナルキーボードを作ってみた．
以下備忘録．
![DSC_1873.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238423/8e47a461-c805-a2ab-b1b1-ec85d664b902.jpeg)
命名：Sakura Innocence
「キーキャップの色」「JIS配列 → 日本を連想する花」「69キー → 無垢（むく）」より．



#やったこと
1. [配列・プレート作成](#配列プレート作成)
    1. 「Keyboard Layout Editor」でお手軽にオリジナル配列を作成
    2. 「Plate & Case Builder」でトッププレートのCADデータ(.dxf)を作成
    3. お好きなCADでdxfを読み込み，トッププレートとボトムプレートの作成
    4. プレート発注
2. [パーツ購入](#パーツ購入)
3. [製作](#製作)
    1. 無限の可能性にダイオードとLEDを半田付け
    2. プレートにスイッチをはめる
    3. スイッチに無限の可能性を半田付け
    4. ProMicroSocketと無限の可能性との配線（+, -, Col, Row, LED）
    5. ProMicroをProMicroSocketに半田付け
    6. プレートで基板をサンドイッチ
    7. キーキャップを付ける
4. [ファームウェア](#ファームウェア)
    1. 各ソースコードの書き換え
    2. ProMicroへの書き込み
5. [トラブルシューティング](#トラブルシューティング)




#配列・プレート作成
JIS配列のキーキャップで簡単に手に入りそうなものの一つに
[FILCOのMajestouch用キーキャップセット](https://www.diatec.co.jp/shop/det.php?prod_c=4129)があったので，
これを使えるような配列を作ることにした．

####「Keyboard Layout Editor」でお手軽にオリジナル配列を作成
[Keyboard Layout Editor](http://www.keyboard-layout-editor.com/) (KLE)を使えば直感的にキーボードの配列を自作できる．
これだけで何時間でも潰せる．
今回は分割キーボードなので右と左を分けて作ってみた．
![Screen Shot 2020-03-10 at 19.28.58 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238423/d7e8d57e-9015-dff9-3c8b-28b73a1b8dab.png)
いろいろ考えた結果，左手30キー，右手39キーの計69キーで，
下2行が外側にそれぞれ0.125Uだけ膨らんだ感じになった．
Q行A行間は0.25Uずれ，A行Z行間は0.375Uずれになっている（邪道感ある）[^3]．
![DSC_2066(7).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238423/4882bf63-9d84-fbe3-d3a1-6d9ab2b8b34a.jpeg)



####「Plate & Case Builder」でトッププレートのCADデータ(.dxf)を作成
配列ができたら，KLE の Raw data タブで出てくる配列データを[Plate & Case Builder](http://builder.swillkb.com/)にコピペする．
Edge Padding とか Plate Corners を良い感じに設定したら CAD Output して.dxfで保存．
![Screen Shot 2020-03-10 at 18.13.43 2 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238423/2a6075f5-2544-d82a-4f21-e17f0ff1ad39.png)


####お好きなCADで.dxfを読み込み，トッププレートとボトムプレートの作成
CADソフトに.dxfをインポートして，スケッチを編集してトッププレートを作る．
スペーサーを取り付けるためのネジ穴（直径2㎜）を適当に空けたり，左右合体できるように階段状の部分を作ったりした．
また，同じネジ穴を持つボトムプレートもここで作成する．
ボトムプレートには，ProMicroSocketを取り付けるスペースと，ProMicroSocket固定用の4つのネジ穴を追加する．
![Screen Shot 2020-03-10 at 18.13.43 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238423/01dac3ff-f878-4011-d937-805b5fde2667.png)
できたらまた.dxfで出力しておく．


####プレート発注
できたCADデータをレーザーカットサービスにお願いしてプレートにしてもらう．
アクリルとか悩んだけど結局[LASERBOOST](https://www.laserboost.com/)の1.5㎜厚アルミプレートにした[^4]．
発注したデータに不備があったので修正のための追加料金が発生したりもした．
![DSC_1768.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238423/a6138078-0a94-62ac-daa4-418bd32b6379.jpeg)




#パーツ購入
| 購入先（だいたい通販） | 品名                                          | 単価（一部適当） | 個数 | 金額  |
|------------------------|-----------------------------------------------|------------------|------|-------|
| 魔界鍵盤店 (BOOTH)     | 無限の可能性「ネクサス」                      | 500              | 3    | 1500  |
|                        | ProMicroのおうち                              | 200              | 2    | 400   |
| 遊舎工房               | ProMicro+コンスルー                           | 1,000            | 2    | 2000  |
| LASERBOOST             | アルミプレート（本体＋レーザーカット代）      | 8,283            | 1    | 8283  |
|                        | （CADデータ修正サービス）                     | 4,351            | 1    | 4351  |
| 秋月電子               | 3.5mm4極(TRRS)ジャック                        | 50               | 2    | 100   |
|                        | タクトスイッチ                                | 20               | 1    | 20    |
|                        | ポリウレタン銅線                              | 180              | 1    | 180   |
| TALP KEYBOARD          | 1N4148 ダイオード(100pcs)                     | 150              | 1    | 150   |
| KBDfans                | 2Uスタビライザーセット（プレートマウント）    | 1,338            | 1    | 1338  |
| 廣杉計器               | ジュラコンスペーサーAS-2010B (M2, 長さL=10mm) | 4                | 50   | 200   |
|                        | 鉄ナベ小ネジF-0204-E (M2, 長さL=4mm)          | 18               | 100  | 1800  |
| Akibaピカリ館          | IC入りRGBチップLED SK6812MINI (100pcs)        | 2,500            | 1    | 2500  |
| Drop                   | Invyr Panda キースイッチ (70pcs)              | 8,814            | 1    | 8814  |
| DIATEC                 | Majestouch用JISキーキャップセット（ピンク）   | 3,036            | 1    | 3036  |
| 忘れた                 | TRS(3極)ケーブル                              | 0                | 1    | 0     |
|                        |                                               |                  | 計   | 34672 |

送料とか何とかを加味して40000円弱、えっ、いや、高っか……（ドン引き）
修論終わりのテンションで正気を失っていたのがよくわかる．


#製作
Ortholinear配列(直交配列，格子配列)だと無限の可能性の半田付け必要数が大幅に減るが，
今回はわざわざ行で切り離してずらして半田付けしなおすので，思ったより時間がかかった（でも楽しい）．

#### 無限の可能性にダイオードとLEDを半田付け
切り離す前の無限の可能性に，ダイオードとチップLEDを半田付けしていく．
このLEDは死ぬほど熱に弱くて実際死ぬので，先駆者のやり方を参考に，
温調こてを使って慎重に手早く付ける．
っていうかラボの留学生に手伝ってもらったら全部できてた．
![resized_DSC_1751.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238423/a55b4185-ec59-2066-d274-d73332d1d8b2.jpeg)


#### プレートにスイッチをはめる
アルミのトッププレートにキースイッチを嵌めていく．楽しい．
ちなみにスイッチのハマる穴は14㎜四方．


#### スイッチに無限の可能性を半田付け
スイッチをはめ終わったらプレートをひっくり返し，いい感じに切り離しておいた無限の可能性を挿して半田付けする．
下図中の赤枠で示すように，なるべく切り離さずに使うと半田付けの回数を減らせる．
![resized_DSC_1772.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238423/bbedc8f8-1972-6b10-fb79-64d57ef42774.jpeg)


#### ProMicroSocketと無限の可能性との配線（+, -, Col, Row, LED）
[本家の使い方ガイド](https://swanmatch.github.io/MxLEDBitPCB/)を参考に，ペイントソフトで適当に配線図を描いた．
結局のところ，

- ＋を全部つなぐ
- －を全部つなぐ
- Colを縦向きに全部つなぐ
- Rowを横向きに全部つなぐ（切り離してないところは既につながっている）
- DI→DOを光らせたい順番に全部つなぐ

という感じになる．
この時点でキーマトリクスのインデックスを振っておくとファームウェア作るときに捗ると思う．
（自分はやってなかったので後々ミスる）
ProMicroのピン番号は左右で同じものを使ったほうが良いかも．
（例えば，Rowは左右ともに4～8ピンを使い，Colは左右ともにA3～A0，15～9ピンを使う）
![DSC_1772.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238423/9cce3d18-c7e5-9727-af10-a5dc8d17cf3a.png)
あとは推しVTuberの動画を連続再生しながらポリウレタン導線を使ってひたすら配線していく．
![DSC_1777.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238423/f8f6a74e-9297-2ab2-aea0-77e62e03cf0a.jpeg)
うわぁ……


####ProMicroをProMicroSocketに半田付け
ショート防止のため，ProMicroSocketへの配線が全て終わってから，ProMicroを実装する．
ちなみにProMicroには事前に[Moge Microへの対策](https://scrapbox.io/self-made-kbds-ja/%E3%82%82%E3%81%92%E4%BA%88%E9%98%B2)を施してある．


#### プレートで基板をサンドイッチ
配線ができたらスペーサーを挟んでボトムプレートをネジ止めし，サンドイッチ．
ProMicroもネジ止めする．
![DSC_1770.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238423/9ca700cf-5978-c788-2c25-a69520a01fc0.jpeg)


#### キーキャップを付ける
キーキャップ付けるの楽しいですよね．
![DSC_1778.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238423/16b57dba-b975-6f33-ea5a-b672d6d17749.jpeg)



#ファームウェア
QMK Firmwareの環境構築は割愛．
「[QMK Firmware でオリジナルキーボードのファームウェアを作成する](https://qiita.com/mizuhof/items/0c34308c2d57c9345f3a)」を参考に，

```
$ cd qmk_firmware
$ ./util/new_keyboard.sh
```

としてできたフォルダ内の以下のファイルを編集していく．

- Sakura_innocence.h
- rules.mk
- config.h
- keymaps/default/keymap.c 

主にMint60の各ファイルを参考にした．


####Sakura_innocence.h
ここでは，```#define LAYOUT()```を書き換えることで，
キーボードのレイアウトを定義する対応表みたいなのを作っているっぽい．

```
#pragma once
#include "quantum.h"

#define LAYOUT( \
  L00,  L02,L03,L04,L05,L06,    R00,R01,R02,R03,R04,R05,R06,R07,R08, \
  L10,   L12,L13,L14,L15,L16,     R11,R12,R13,R14,R15,R16,R17, \
  L20,    L22,L23,L24,L25,L26,     R21,R22,R23,R24,R25,R26,R27,R28, \
  L30,     L32,L33,L34,L35,L36,     R31,R32,R33,R34,R35,R36,R37,R38, \
  L40, L41, L42, L43, L44, L45,     R41, R42,  R44, R45,R46,R47,R48 \
) \
{ \
  { L00, KC_NO, L02, L03, L04, L05, L06,   KC_NO, KC_NO }, \
  { L10, KC_NO, L12, L13, L14, L15, L16,   KC_NO, KC_NO }, \
  { L20, KC_NO, L22, L23, L24, L25, L26,   KC_NO, KC_NO }, \
  { L30, KC_NO, L32, L33, L34, L35, L36,   KC_NO, KC_NO }, \
  { L40, L41,   L42, L43, L44, L45, KC_NO, KC_NO, KC_NO }, \
  { R08,   R07, R06, R05, R04, R03,   R02, R01, R00   }, \
  { KC_NO, R17, R16, R15, R14, R13,   R12, R11, KC_NO }, \
  { R28,   R27, R26, R25, R24, R23,   R22, R21, KC_NO }, \
  { R38,   R37, R36, R35, R34, R33,   R32, R31, KC_NO }, \
  { R48,   R47, R46, R45, R44, KC_NO, R42, R41, KC_NO }, \
}
```

ちなみに，Mint60を参考に右手側を下のように書いたら，
半田付けした列の並びが逆だったので，後ほど上のように修正したのだった．

```
  { R00,   R01, R02, R03,   R04, R05, R06, R07, R08   }, \
  { KC_NO, R11, R12, R13,   R14, R15, R16, R17, KC_NO }, \
  { KC_NO, R21, R22, R23,   R24, R25, R26, R27, R28   }, \
  { KC_NO, R31, R32, R33,   R34, R35, R36, R37, R38   }, \
  { KC_NO, R41, R42, KC_NO, R44, R45, R46, R47, R48   }, \
```

要するに全部のスイッチが繋がってさえいれば，行列の順番とかはソフト側でなんとかなるようになっているのだ．


####rules.mk
rules.mk の SPLIT_KEYBOARD と RGBLIGHT_ENABLE を yes にする．

```
～略～
# Build Options
#   change yes to no to disable
#
BOOTMAGIC_ENABLE = no       # Virtual DIP switch configuration
MOUSEKEY_ENABLE = no        # Mouse keys
EXTRAKEY_ENABLE = yes       # Audio control and System control // トラブルシューティングで後述
CONSOLE_ENABLE = no         # Console for debug
COMMAND_ENABLE = no         # Commands for debug and configuration
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
SLEEP_LED_ENABLE = no       # Breathing sleep LED during USB suspend
# if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
NKRO_ENABLE = no            # USB Nkey Rollover
BACKLIGHT_ENABLE = no       # Enable keyboard backlight functionality
RGBLIGHT_ENABLE = yes       # Enable keyboard RGB underglow
MIDI_ENABLE = no            # MIDI support
BLUETOOTH_ENABLE = no       # Enable Bluetooth with the Adafruit EZ-Key HID
AUDIO_ENABLE = no           # Audio output on port C6
FAUXCLICKY_ENABLE = no      # Use buzzer to emulate clicky switches
HD44780_ENABLE = no         # Enable support for HD44780 based LCDs

SPLIT_KEYBOARD = yes
```


####config.h
いろいろ書き換える．
MATRIX_ROW_PINS とかのピン番号 D4 とか F7 とかは，
[ProMicroとAVRマイコンの各ピンの対応表](https://deskthority.net/wiki/Arduino_Pro_Micro#Pinout)を参考に，実際に半田付けしたピンと照らし合わせる．
SOFT_SERIAL_PIN は D2 にしとくと良いっぽい．

```
～略～

/* key matrix size */
#define MATRIX_ROWS 10  // 5 * 2 (Left and right)
#define MATRIX_COLS 9

#define MATRIX_ROW_PINS { D4, C6, D7, E6, B4 }
#define MATRIX_COL_PINS { F4, F5, F6, F7, B1, B3, B2, B6, B5 }
#define UNUSED_PINS

/* COL2ROW, ROW2COL*/
#define DIODE_DIRECTION COL2ROW

#define SOFT_SERIAL_PIN D2  // or D0, D1, D3, E6

#define RGB_DI_PIN D3
#ifdef RGB_DI_PIN
  #define RGBLED_NUM 69
  #define RGBLIGHT_HUE_STEP 10
  #define RGBLIGHT_SAT_STEP 17
  #define RGBLED_SPLIT {30, 39}    // トラブルシューティングで後述
  #define RGBLIGHT_LIMIT_VAL 127   // トラブルシューティングで後述
  #define RGBLIGHT_ANIMATIONS
#endif
～略～
```

####keymaps/default/keymap.c 
JIS配列のキーマップを書きやすくするため，qmk_firmware/quantum/keymap_extras にある keymap_jp.h を拾ってきて，keymaps/default  に置いておく．
そして keymap.c の先頭に ```#include "keymap_jp.h"``` を追記し，キーマップを書き換える．
これもMint60のキーマップを参考にした．

```
#include QMK_KEYBOARD_H
#include "keymap_jp.h"

// Defines names for use in layer keycodes and the keymap
enum layer_names {
    _BASE,
    _FN
};

// Defines the keycodes used by our macros in process_record_user
enum custom_keycodes {
    RGBRST = SAFE_RANGE
};

const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
    /* Base */
    [_BASE] = LAYOUT(
        KC_GRAVE,     KC_1,  KC_2,  KC_3,  KC_4,  KC_5,      KC_6,  KC_7,  KC_8,    KC_9,    KC_0,     KC_MINS, JP_CIRC, JP_YEN, KC_BSPC,   \
        KC_TAB,        KC_Q,  KC_W,  KC_E,  KC_R,  KC_T,      KC_Y,  KC_U,  KC_I,    KC_O,    KC_P,     JP_AT,   JP_LBRC,                     \
        XXXXXXX,        KC_A,  KC_S,  KC_D,  KC_F,  KC_G,      KC_H,  KC_J,  KC_K,    KC_L,    KC_SCLN,  JP_COLN, JP_RBRC, KC_ENT,          \
        KC_LSFT,         KC_Z,  KC_X,  KC_C,  KC_V,  KC_B,      KC_N,  KC_M,  KC_COMM, KC_DOT,  KC_SLSH,  JP_BSLS, KC_UP,  KC_RSFT,         \
        KC_LCTL, MO(_FN),KC_LGUI, KC_LALT, JP_MHEN, KC_SPC,     KC_BSPC,  JP_HENK,  KC_RALT,  KC_RCTL,    KC_LEFT, KC_DOWN,KC_RGHT          \
    ),
    [_FN] = LAYOUT(
        KC_ESC,       KC_F1,  KC_F2,   KC_F3,   KC_F4,   KC_F5,       KC_F6,    KC_F7,  KC_F8,   KC_F9,   KC_F10,   KC_F11,  KC_F12,  XXXXXXX, KC_DEL,    \
        RGB_TOG,       RGBRST, RGB_HUI, RGB_SAI, RGB_VAI, KC_VOLU,     XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_PSCR,  XXXXXXX, XXXXXXX,                    \
        KC_CAPS,        RGB_MOD,  RGB_HUD, RGB_SAD, RGB_VAD, KC_VOLD,     XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,          \
        _______,         XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_MUTE,      XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, _______, KC_PGUP, _______,         \
        _______, _______, _______,  _______,  XXXXXXX,   XXXXXXX,          KC_DEL,  XXXXXXX,   _______,  _______,       KC_HOME, KC_PGDN, KC_END           \
    )
};


bool process_record_user(uint16_t keycode, keyrecord_t *record) {
    switch (keycode) {
        case RGBRST:
            #ifdef RGBLIGHT_ENABLE
                if (record->event.pressed) {
                eeconfig_update_rgblight_default();
                rgblight_enable();
                }
            #endif
        break;
    }
    return true;
}
```


####ProMicroへの書き込み

```make Sakura_innocence:default:avrdude``` して，片方のProMicroをPCにUSB接続し，
```Detecting USB port, reset your controller now......``` というメッセージが出たらリセットボタンを押す．
するとファームウェアが書き込まれる．
左右それぞれにファームウェアを書き込めば完了．




#トラブルシューティング
####数か所のLEDが点かない
配線忘れが2か所と，LED故障が1か所だった．
光らないときは，該当LEDのDINと隣のLEDのDINにジャンパ線を当ててみたりするとよい．
[このページ](https://marksard.github.io/2018/08/04/make-the-crkbd/)が参考になった．

####右手と左手のLEDが連動しない
LEDをオンにするとマスタの左側のみオンになってスレーブの右側が反応しなかった．
調べたら出てきた[このページ](https://skyhigh-works.hatenablog.com/entry/2019/01/21/220043#RGBLED)に従い config.h 内に

```
#define RGBLED_SPLIT {30, 39}    // {LEFT_NUM, RIGHT_NUM}
```

を追記すると連動するようになった．


####LED全点灯した数秒後に文字が全く打てなくなる
打てなくなったとき普通に「お？早速死んだか？」と思ったがどうやら電力不足っぽかったので， config.h 内の

```
#define RGBLIGHT_LIMIT_VAL 255
```

の255を127に落としたら，光ってても文字が打てるようになった．


####音量操作KC_VOLUとかが効かない
rules.mk に以下を追加すると効くようになった．

```
EXTRAKEY_ENABLE = yes
```


#おわりに

この記事はオリジナル自作キーボード Sakura Innocence で書きました．


#スタビライザーの追加（2020/3/13追記）
無限の可能性にはスタビライザー設置用の穴が当然開いていないので、
よくあるPCBマウントタイプのスタビライザーが使えない．
そこで，プレートマウントタイプのスタビを買って設置してみた．
本来はスイッチを半田付けする前に設置しないといけないものを後から無理やり付けた．
エンターが結構重くなって良い音になった（気がする）．
![DSC_1890.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238423/7e7fbfa8-5665-e819-f0b5-165bc4bef4ad.jpeg)
![DSC_1892.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238423/a989066f-f773-6c77-8893-c132e70489f9.jpeg)




[^1]: [7sPlus+J](https://salicylic-acid3.hatenablog.com/entry/current-task-list-1#7sPlusJ)とか[Nin76](https://booth.pm/ja/items/1370844)とかあるにはあったけど開発中だったり売り切れだったりした．
[^2]: Row-staggered配列: キーボードの各行(段)が横方向にずらしてある配列の総称．よく見るキーボードはこの配列．他にも各列が縦方向にずれたColumn-staggered配列や、縦横ずらさず格子状にキーが並ぶOrtholinear配列などがある．https://scrapbox.io/self-made-kbds-ja/Normal_staggered
[^3]: 普段使ってるのがA行Z行間0.25Uずれで，一般的なキーボードだと0.5Uずれが多いっぽいので，間を攻めたということでひとつ．
[^4]: プレートマウントのスタビライザー（1.5㎜プレートに対応）をつけたかったので，欠けのリスクと強度の心配があるアクリルを避け，1.5㎜厚アルミにした．アルミだと1.5㎜厚でも十分すぎるほどの強度がある．