君のキーボードは輝いてるかい？

[自作キーボードアドベンドカレンダー3枚目](https://adventar.org/calendars/3208)の21日目、ginjakeです
クリスマス→イルミネーション→輝き　という事で

・LED実装で滅茶苦茶苦戦した話(電子工作)
・押した箇所を光らせる＆電力不足対策(qmk)
・完全自作キーボードラブライブ9

の3つをしようとおもいます。
![Dux-ApKU0AMv9H_.png](https://qiita-image-store.s3.amazonaws.com/0/261659/009695b5-a636-3cb7-7c0c-201efc8986bf.png)


# LEDで苦戦した　~1つずつ確認しながらつける~
<img src="https://qiita-image-store.s3.amazonaws.com/0/261659/f2c5a427-2952-1172-bb1c-a7f837dfc107.jpeg" width="20%">

Helixやコルネ、ZincはLEDを付けることが出来ます。
・裏側に付け下のプレートを照らすunderglow(テープLED)
・表側に付け、キーキャップを照らすbacklight(チップLED)

がありますが、今回するのはbacklightの話です。
SK6812MINIというパーツを使うのですが
米粒より小さいのに4箇所もはんだをつける必要があります。(当然向きもあります)
搭載しているマイコンが熱に弱く、一瞬で壊れます。

自作キーボード3台目にCrkbd Cherryを作ったのですが、全部つけたあと点灯を確認したら全滅でした。
マイコンへの命令送信が直列で行われるため、死んだ箇所から先は全部光りません。
1番目を剥がして付け直しているうちに基板が抉れ、どうしようもなくなりました。

「熱でつける部品なんだから、いうてそこまで熱に弱いわけないだろう。」
事前調査、準備を怠った事が敗因でした。

Zincを作るときは反省し、作者さんにLEDの順番を教えてもらいながら1つずつ点灯を確認しつけていきました
(現在は公式[ビルドログ](http://www.sho-k.co.uk/tech/735.html)にLEDの順番を書いた図があります)

道具も試行錯誤しました。

### はんだごて
温度調節できる「白光 ダイヤル式温度制御はんだこて FX600」を購入。
基本は270度、失敗して剥がすときは350度くらいにしました。
こて先は1mmと0.5mmを別途購入し、1mmを使いました。
0.5mmだとコテ先をはんだに充てた瞬間温度が下がってしまい、低温ではうまく溶けてくれませんでした。

### はんだ
太さと融点をとにかく気にしました。
錫99%だと融点が高く、低温ではなかなか溶けてくれません。
太さ0.65mm、錫60%がいい感じでした。

### 吸い取り器
吸い取り線と吸い取り器両方お世話になりました。
完全に剥がすときは吸い取り線、盛りすぎて除去したいときは吸い取り器を使いました。
吸い取り線だと長時間温める必要があるため、LEDが壊れてしまいます。

## 光らないときのデバッグ方法
### firmwareを疑う
LEDをオンにするためはrules.mkで `BACKLIGHT_ENABLE = yes` にする必要があります
Zincではビルドログで指定された方法でコンパイルすればこのあたりを気にする必要はありません。

### 光らないLEDを疑う
熱で壊れてしまった可能性があります。
剥がして新品のLEDに変えましょう

### 光らないLEDの1つ前を疑う
データ送信部が熱で死んだ可能性があります。
剥がして新品のLEDに変えましょう

### 強い気持ち
何度も心が折れました。慣れないうちは成功率50%程度。
一度ハマると5,6回同じところで立ち止まります。
Crkbd Cherryで基板が抉れた悪夢が蘇り、心が折れそうになりました。
twitter上でいろいろ教えてくれたり、応援してくれた方ありがとうございました。
右手を作るのに40個壊しましたが、左手は慣れてきたため10個程度だと思います。

LEDのデバッグについては[こちら](https://marksard.github.io/2018/08/04/make-the-crkbd/)の記事もすごい参考になりました。


# 押した箇所を光らせてみる ~qmkの話~
LEDを光らせるには

```c

sethsv(h, s, b, (LED_TYPE *)&led[LED番号]); //hは360以下
```

で光り方を変更したいLEDに対して値をセットした後、

```c

rgblight_set();
```

で反映させることが出来ます。

押したキーの位置(キーコードではなく位置そのもの)を取得するには

```c

  for (uint8_t c = 0; c < MATRIX_COLS; c++) {
   for (uint8_t r = 0; r < MATRIX_ROWS; r++) {
     if (matrix_is_on(r, c)) {
       //rとcがそれぞれ押されたキーの縦、横の場所
     }
   }
 }
```

こんな感じにします。

ただし注意が必要です。
これはあくまでキーの押された位置であって、光らせるべきLED番号ではありません。
Zincを例に、キーの配列に分かりやすく番号をつけるとこんな感じですが

```


   * ,-----------------------------------------.             ,-----------------------------------------.
   * | 0    |   1  |   2  |   3  |   4  |   5  |             |   6  |   7  |   8  |  9   |  10  | 11   |
   * |------+------+------+------+------+------|             |------+------+------+------+------+------|
   * | 12   |  13  |  14  |  15  |  16  |  17  |             |  18  |  19  |  20  |  21  |  22  | 23   |
   * |------+------+------+------+------+------|             |------+------+------+------+------+------|
   * | 24   |  25  |  26  |  27  |  28  |  29  |             |  30  |  31  |  32  |  33  |  34  | 35   |
   * |------+------+------+------+------+------|             |------+------+------+------+------+------|
   * | 36   |  37  |  38  |  39  |  40  |  41  |             |  42  |  43  |  44  |  45  |  46  | 47   |
   * `-----------------------------------------'             `-----------------------------------------'
```   

LEDはこうなってます。

```   
   * ,-----------------------------------------.              ,-----------------------------------------.
   * | 5    |   4  |   3  |   2  |   1  |   0  |              | 5    |   4  |   3  |   2  |   1  |   0  |  
   * |------+------+------+------+------+------|              |------+------+------+------+------+------| 
   * | 6    |   7  |   8  |   9  |  10  |  11  |              | 6    |   7  |   8  |   9  |  10  |  11  |
   * |------+------+------+------+------+------|              |------+------+------+------+------+------| 
   * | 17   |  16  |  15  |  14  |  13  |  12  |              | 17   |  16  |  15  |  14  |  13  |  12  |  
   * |------+------+------+------+------+------|              |------+------+------+------+------+------| 
   * | 18   |  19  |  20  |  21  |  22  |  23  |              | 18   |  19  |  20  |  21  |  22  |  23  |     
   * `-----------------------------------------'              `-----------------------------------------' 
```

LEDは右上から左に折り返しでつながっている＆左右同じ番号ですね。

まずはキー番号→LED番号の変換用配列を作り

```c

//keyのmatrixの位置とLEDの番号を紐づける
int combined_key_to_led[] =
{
  0,1,2,3,4,5,
  11,10,9,8,7,6,
  12,13,14,15,16,17,
  23,22,21,20,19,18
};
```

```c

sethsv(100, 255, 255, (LED_TYPE *)&led[combined_key_to_led[MATRIX_COLS*r+c]]
```
みたいにする必要があります

また、左右同じ番号なのでこのままでは両方光ってしまいます。
マスターとスレーブで条件分岐させる必要がありそうです。
多分 `if(is_master) {}` で分岐させていい感じにすればいけると思いますが、
具体的なコードについては未完成です。
~~ここからは君の目で確かめよう！~~

あと関係ないですが、
Aqours 4th LoveLive! ～Sailing to the Sunshine 
のオタク棒を再現したらこんな感じのhsvの値になりました。

```c

int aqours_color_h[] = { 26, 340, 150,   0, 199, 220, 53, 265, 322};
int aqours_color_s[] = {255, 165, 255, 255, 255, 350, 255, 255, 255};
int aqours_color_v[] = {255, 255, 255, 255, 255, 255, 200, 255, 255};
```

花丸ちゃんのvの値が少し小さいのは理由があります。

### 電力不足
今回は輝きを増やすため

・underglowとbacklight同時実装(Zinc公式非推奨)
・`RGBLIGHT_LIMIT_VAL` を200 (MAXは255)

にしました。
`RGBLIGHT_LIMIT_VAL`は光の強さです。
zincではLEDの数によって`RGBLIGHT_LIMIT_VAL`を調整しており、LEDが16個以上の場合は120に設定されています。
この記述を消し、とりあえず200にしました。

(あまり無理させると電源ラインが想定外の加熱をしてしまうらしいです。自己責任で行って下さい)

また、underglowとbacklightを同時に付けることも非推奨です。
単純にLEDの数が増えるので電気を一杯食います。
制御にも問題があり

```c

sethsv(h, s, b, (LED_TYPE *)&led[1]); 
```

とやるとunderglowの1番目とbacklightの1番目両方が光ってしまいます。
同じピンから出力されているらしく、個別に制御出来ないようです。

と、このように電力をたくさん食う仕様にしたので当然不足します。
つないだ瞬間は動くのですが、10秒くらいするとスレーブが反応しなくなります。


まず若干目立たない一番上の列はhsvのvの値を下げました。

また、オタクライブに想いを馳せ色を切り替えていると、
花丸ちゃんのところでキーボードが必ずフリーズすることに気づきました。

黄色を表現するには赤と緑2つのLEDを1:1で点灯させる必要があります。
その為他の色に比べて電力を食っているのだと思います。
花丸ちゃんのvだけ他より下げているのはそういう理由です。
(青白い子が何故落ちてないのかは謎です)

### 限界まで輝く
`RGBLIGHT_LIMIT_VAL`をMAX値255にしたらやはり動きません。

USBの規格電流恐らく超えてますからね、当たり前です。

そういうわけで、データ転送機能のないケーブルをダイソーで購入し、スレーブに繋げました。
ケーブルを繋げる順序があるのでちょっと面倒ですが、この記事を書いている現在もうまく動作しています。
コツとしては、マスターとスレーブをTRSケーブルで接続しておき、まずはマスターだけ繋ぎます。
その後、電力不足でフリーズする前にスレーブを素早く差します。(あくまで自分の場合です)

type-CのProMicro互換にすれば動くのかなーとかいろいろ考えましたが、動いたので気にしないことにしました。
何度も言いますが自己責任でお願いします。Pro Microがそれなりに熱いので壊れても知りません。

とりあえず、qmkのコードを載せておきます。
[オタク色に輝くzinc](https://github.com/ginjake/qmk_firmware/tree/master/keyboards/zinc/keymaps/default)

# ラブライブ9
crkbdの制作者foostanさんが出している「[自作キーボード設計入門](https://pskbd.booth.pm/items/1044084)」を読み、
折角なのでなんか作りたいと思いました。
学生時代に作ったスクフェス(ラブライブのスマホ音ゲー)用自作コントローラーがあったのでキーボード化します。
(軸はサンワ軸を使用しています)

↓当時の動画
<script type="application/javascript" src="https://embed.nicovideo.jp/watch/sm23836865/script?w=640&h=360"></script><noscript><a href="https://www.nicovideo.jp/watch/sm23836865">【作ってみた】スクフェス専用コントローラー</a></noscript>

スクフェスのデータをroot取得済みAndroidからiPadに移した為、何年間かインテリア化していました。
しかし強い想い入れがあったため、
コントローラー機能を壊さないように既存の基板と併用出来るようにしました。

格闘ゲーム用アーケードコントローラーの基板を使っていた為、元の配線はこんな感じです。
<img src="https://qiita-image-store.s3.amazonaws.com/0/261659/51faacb9-ed8a-ea84-9797-e8472c2e7a5e.png" width=50%>

(格ゲー用コントローラーは8ボタン+スタートやセレクトという構成のため、足りなかった1キーは独立しています)

8ボタン目と9ボタン目をつなげて9*1列にしたり
混線しない用にスイッチをいろいろ空中配線していきます。ゲームコントローラーに戻すにはスイッチを切り替える仕組みです。
ProMicroの各ピンにソケット越しで配線しつつ、
USBを出すためドリルで穴をあけ、テーパーリーマーで穴を広げペンチやヤスリで整えます。

ついでに、プレートとボタンの外観がμ'sのままだったので、Aqoursにします
フォトショでサイズ調整しコンビニで印刷し、ラミネーターで閉じ、コンパスカッターで切り抜いていきます。
キーキャップ?の中にも各メンバーを埋め込みます。
このあたりはRAP(格ゲーコントローラー)改造に近いかもしれません。
<img src="https://qiita-image-store.s3.amazonaws.com/0/261659/35a06a65-50d7-8c07-5984-e0807c0a6b0f.jpeg" width=50%>

<img src="https://qiita-image-store.s3.amazonaws.com/0/261659/2263d36d-4339-89c9-627b-088e2f5fa5c2.jpeg" width=50%>

## qmk
ハードウェアは出来ても、firmwareが対応していないと動きません。
左右のシリアル通信等がなく非常にシンプルなキーボードのため、
[9key](https://github.com/ginjake/qmk_firmware/tree/master/keyboards/9key)　と
[christmas_tree](https://github.com/ginjake/qmk_firmware/tree/master/keyboards/christmas_tree) を参考にしました。

readmeとかコピペ元のままですが、こんな感じです。
[lovelive9](https://github.com/ginjake/qmk_firmware/tree/master/keyboards/lovelive9)

では最後に、qmkに標準搭載のクリスマスモードをお見せして終わりにしようと思います。
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">クリスマスモード <a href="https://t.co/fFZpCQuvVW">pic.twitter.com/fFZpCQuvVW</a></p>&mdash; 銀鮭⌨ (@sirojake) <a href="https://twitter.com/sirojake/status/1075467926126227457?ref_src=twsrc%5Etfw">2018年12月19日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

ありがとうございました。


(この記事はLibertouchとCrbkd Classicで書きました)