キーボードを作ろう

Denpaというキーボードを設計し、組み立てました。

仕様を決める

まずキーボードに欲しい仕様を考えます。今回欲しかった仕様は

  • 無線(Bluetooth)対応
  • 充電式
  • 打鍵感や音もある程度良くしたい
  • パームレスト無しで使える程度の厚み
  • オーソリニア
  • 60%ぐらい

というものです。

Bluetooth対応の自作キーボードにはBLE Micro Pro(BMP)が使われることが多いのでこれを使います。 BMPにはインジケータ機能が用意されており、バッテリー残量や接続状況をledで表せるのでこれにも対応することにします。

BMPの電源にはコイン電池や単4乾電池が使われることが多いのですが、リチウムイオン二次電池を使って充電式にします。リチウムイオン電池は専用の充電ICで充電し、電池の電圧は分圧してBMPで監視することにします。

また、良い打鍵感や音も欲しかったのでよくあるサンドイッチマウントではなく、 ガスケットマウントを採用することにしました。ケースはコスト的にアクリル積層で作成することにします。

ここまでの仕様(リチウムイオン電池内蔵、ガスケットマウント)を盛り込むとキーボードが分厚くなり、使いにくくなるような気がしたので薄型のスイッチを使って高さを抑えることにします。

薄型(ロープロファイル)のスイッチでよく使われるのはKailh Chocと呼ばれるスイッチで、専用軸のV1とCherry MX軸のV2があります。Choc V1はV2よりも人気がある印象があり、軸の種類や採用例も多いのですが、キーキャップの種類が少ないという欠点があり、気に入ったキーキャプがなかったのでChoc V2を使うことにしました。 Choc V2は専用のスタビライザーがない、一部のキープロファイルは干渉するので使えない、PCBマウントにしないとキーがプレートにぶつかる等の欠点があります。

キーレイアウトを決める

次にキーのレイアウトを決めます。オーソリニアを使ってみたかったのでオーソリニアをベースに、移行コストを下げるためにキー数は60前後になるようにします。

Choc V2をつかうため、スタビライザーを使わない1.75u以下のキーのみを使うことに注意して以下のようなレイアウトにしました。

レイアウト

このサイズでキーを完全に碁盤の目状に並べると見た目が単調になると感じたので、数字行をずらすなどしてアクセントを付けています。また、GH間に1uの隙間を開けて若干肩が開くようにしています。

PCBを設計する

KiCadを使ってPCBを設計します。

回路図を書く

まず回路図を書きます。

キーマトリクス

BMPでキーマトリクスに使えるピンはRESETピンを除いて18ピンあります。 ここでBMPのインジケータと電池の電圧監視用に1ピンづつ使うのでキーマトリクスに使えるのは16ピンになります。 Denpaは57キー、5行x13列なのですが、「6」のキーを移動し、行を二倍、列を半分にして10行x6列のマトリクスに収めます。

キーマトリクス

リチウムイオン電池周り

リチウムイオン電池の充電にはMCP73831を使います。また、リチウムイオン電池の電圧はBMPの電源電圧(1.7~3.6V)よりも高いのでレギュレーターで降圧します。 バッテリーの電圧をだいたい3V以下になるように分圧し、BMPのアナログピンに入れてバッテリーの電圧を計測できるようにしておきます。

バッテリー周りの回路

BMP周り

BMPのピンに以下のようにつなぎます。

BMP周りの回路

部品を配置する

次に基板上に部品を配置します。パーツをいい感じに配置するのですが、 Choc V2スイッチではキーを押したときにキーキャップとPCBの間に数mmしか隙間がないのでPCBの表面にはできるだけパーツを配置せず、スルーホール部品も足が干渉する可能性を考えてできるだけ使わないようにしました。

また、PCBの下にバッテリーを配置するのでその範囲にはダイオードなどの部品を配置せず、バッテリーとPCBの間にできるだけ隙間ができるようにします(結局これはあまり意味がありませんでした。理由は後述)。

PCBの設計

ケースを設計する

アクリル積層ケースを設計します。断面が以下のようになる感じにします。

ケースの断面図 3mm厚のアクリル(灰色)を積層し、ネジとスペーサーで固定。PCB(緑)は3mm厚のPORON(ピンク)でケースに固定する。

PCBの外形データをもとに各層のアクリルの外形を決めます。リセットボタンや電源スイッチ、USBコネクタの部分に穴を開けておきます。

ケースのアクリル 各層のアクリルの外形。左上が一番上の層、右下が一番下の層

PCBとアクリルを発注する

PCBはJLCPCBに、アクリルは遊舎工房に発注します。

届いたPCB 届いたPCB。JLCPCBの黒は実質マットブラックな模様

ファームウェアをいじる

config.jsonkeymap.jsonを用意し、 Web Configuratorを使ってファームウェアを書き込みます。

BMPのインジケータのバッテリー残量はVCCの電圧を使って計算されていますが、DenpaはレギュレーターでVCCがだいたい一定になっているのでA3ピンの電圧を使ってバッテリーの電圧を計算するように変更します。 また、バッテリーの電圧が下がりすぎると危険なのである程度電圧が下がったらインジケータを点滅させて警告し、スリープするようにします。

// tmk_core/protocol/nrf/bmp.c
// 省略

uint16_t get_lipo_mv()
{
  int16_t vdiv_d = -1;
  int16_t lipo_mv = 0;
  BMPAPI->adc.sample_and_convert(1, &vdiv_d);
  lipo_mv = 5049 * vdiv_d / 4095; // 5049 ~ 3600*(330+820)/820
  return lipo_mv;
}

void bmp_init()
{
  // 省略

  // チャンネル1にA3ピンを紐付ける
  BMPAPI->adc.config_channel(1, 3);

  int32_t battery_level = 1;

  if (get_lipo_mv() > 3850) {
    battery_level = 3;
  }
  else if (get_lipo_mv() > 3675) {
    battery_level = 2;
  }

  bmp_indicator_set(INDICATOR_BATTERY, battery_level);

  if (get_lipo_mv() < 3050) {
    bmp_indicator_set(INDICATOR_USER, 0);
    sleep_enter_counter = 1000;
  }

  // 省略
}
// tmk_core/protocol/nrf/bmp_indicator_led.c
// 省略

__attribute__((weak)) int bmp_indicator_user_pattern(uint32_t time_ms, int32_t option) {
    const uint32_t period = 1000;
    uint32_t time_in_period = time_ms % period;

    if (time_in_period > 0 && time_in_period <100) {
        bmp_indicator_led_on();
    }
    else {
        bmp_indicator_led_off();
    }

    if (time_ms > 15000) {
        bmp_indicator_led_off();
        return 1;
    }

    return 0;
}

// 省略

ちなみにこの部分を書いているときの電圧は4072mVです。

組み立て

部品リスト

部品が揃ったら組み立てます。表面のチップLED(充電インジケータとBMPのインジケータ)は1608サイズではんだ付けが難しい上、キーボードの中心にあるのできれいに仕上げたいところです。

LED用の抵抗は実際に明るさを見て適当な抵抗を選びます。

また、スイッチの音や打鍵感を少しでもよくするため、すべてのスイッチを一旦分解し、潤滑剤(Krytox GPL 205g0)を塗って組み立て直します。(ルブ)

実装した様子(表)

実装した様子(裏) 部品を実装した様子

ケースの組み立て

アクリルケースを組み立てます。今回使ったバッテリーの厚みは約6.2mmなのでPCBの裏面とバッテリーの間のクリアランスが約2mmになるように設計されており、 バッテリーの上に来るスイッチの足を短く切ればPCBのしなりやガスケットの沈み込みなどを考慮しても十分な隙間が確保されるはずでした。

しかし、Choc V2スイッチのプラスチック足を切れないことが判明し、バッテリーの上下に隙間がなくなると思ったのでケースの4,5層、5,6層間にPEフォームを挟み込んで隙間を確保します。

また、打鍵音をいい感じにするため、PCBの裏面にマスキングテープを貼っておきます。(Tape mod)

キーキャップをつけ、ゴム足をつけたら完成です。Cherryプロファイルなどのキーキャップは干渉して使えないので注意します。

完成

Denpa 斧乃木余接みたいな色(DSA Simple Green)

やったー

反省点

BMPのスリープ機能を主に使い、物理電源スイッチは持ち運び時などにのみ使う予定だったのですが、 スライドスイッチの位置が奥まっている上アクリルの穴の幅が小さすぎたため、電源スイッチを指で操作できなくなっています。

Choc V2スイッチ関連

Choc V2スイッチの足を切る前提で設計した部分があるが、実際はプラスチック足が切れない(切りすぎると壊れる)ため、

  • 右上キーのプラ足とBMPがぶつかる
  • バッテリー上下の隙間がほとんど無くなる

といった問題点があります。

また、Choc V2スイッチの安定性が思ったよりも悪く、最下段中央の1.5uキーの端を押したときのぐらつきが気になります。そのため、レイヤーキーをEnter, Space兼用になるようにしています。

また、赤軸の押下圧が約50gと重めになっており、今まで35gのキーボードを使っていたのでこれも気になります。

終わりに

今回始めてキーボードを基板から設計したのですが、ちゃんと使えるものができ、機能・見た目・音などに概ね満足しています。みなさんもキーボードを作ってみてはいかがでしょうか。