Inside of LOVOT

GROOVE X 技術ブログ

趣味で仕事用のキーボードを自作してみた

はじめに

この記事は、GROOVE X Advent Calendar 2023の18日目の記事です。

こんにちは。
ファームウェアチームに所属しているf-sakashitaと申します。

LOVOTのファームウェア開発については過去記事をご覧頂ければと思います。

tech.groove-x.com tech.groove-x.com

今日はLOVOTの開発話からは脱線し、私が普段仕事で使用している自作キーボードについてご紹介します。

※本記事の内容は弊社より製造・販売している製品とは一切関係なく、個人が趣味で開発したものです。
※本記事を参考にした製作物等や、本記事に記載されている他社サービスに関し、当社は一切の責任を負いかねます。

毎日使うキーボード

皆さんは普段仕事や家庭ではどのようなキーボードを使っていますか?
エンジニア界隈だと、メカニカル方式や静電容量方式といったキースイッチを採用した打ち心地・打鍵音・耐久性の優れたキーボードを使用されている方も多いと思います。
弊社でもそのようなキーボードを使用しているエンジニアの方達がいらっしゃり、オフィスでは毎日のようにLOVOTの可愛らしい声と爽快な打鍵音が聞こえてきます。

さて、普段キーボードを操作するにあたって、「このキー絶対にいらないなぁ・・・」と思ったことはないでしょうか?
例えば「Insert」です。
押したことに気づかず文章が上書きされてCtrl-Zで元に戻すといった、無駄にイラっとする経験はありませんか?

また、自分好みのキー配列や、楽な体勢で打てるキーボードが欲しいと思われている方もいらっしゃると思います。

勿論、市販のキーボードでこれらの要望をある程度満足することは可能です。
しかし、購入後に「少し自分には合わない…」「やはりこのキーも欲しかった…」と思うこともあるでしょう。

そこでオススメしたいのが自作キーボードです。
自分が望むキーボードは、自分で作っちゃえば良いのです。
そして、この世にはキーボードを自作するための様々な部品やサービスが存在します。

自作したキーボードの紹介

これが私が普段仕事で使用している自作キーボードです。

自作したキーボード

ケース、PCB、ファームウェアと全て自分で設計開発しました。
スペックは下記の通りです。

キーキャップ Akko Silent
(一部家に余っていたものも使用しています)
キースイッチ Gateron G Pro 3.0 Silver (70個)
Durock Silent Linear Dolphin (9個)
配列、キー数 US配列、79個
hotswap 対応
インターフェース USB (Type-Cコネクタ)
サイズ 縦130mm x 横297 mm x 高さ23 mm
(高さはキーキャップ・スイッチは含めない)
質量 650 g
製作費 4万円程度

なぜ作ったのか

私はこのキーボードを製作する前に、下記の2つの自作キーボードを製作しました。

過去に製作したキーボード

これらはKBDfans社が出しているDZ60とKBD75のPCBを使用しました。

しかし、普段仕事でファームウェアをデバッグする際にFnキーをよく使用するため、FnキーのないDZ60で組んだキーボードは使いにくい問題がありました。
また、KBD75で組んだキーボードは右端列のHomeやPage up/downのキーを普段使うことがなく、誤って押してしまうこともあるため、邪魔でした。

そのため、次に自作するキーボードは自分が普段使いする必要最低限のキーで構成したものにしたく、下記の要求仕様としました。

  1. US配列
  2. fnキー、カーソルキー有り
  3. ページアップやダウン、insertといった普段使用しないキーは無し
  4. メカニカルキーボード&Hotswap対応

理想とするキー配列

最初はこの要求仕様を満たす市販の自作キーボードキットやPCBを探したのですが、全く見つかりませんでした。

こうなると残された道は全て自作するしかありませんでした。
(0から作ってみたかったというのもあります)
それではどのように製作したのかをご紹介します。

ケース

私はハードウェアの設計は本職ではなく完全に初心者です。またキーボードのケースを設計開発した経験もありません。
そんな初心者でも手が出しやすく低コストで作れるアクリルサンド構成でケースを製作しました。

製作したキーボードのアクリルサンドの構成は下記の通りです。

アクリルサンド構成

設計はFusion 360を使用し、アクリル版の加工には遊舎工房様のアクリル加工サービスを使用しました。

  • キープレート用: 押出クリア, 450x300, 1.5mm, 1枚
  • ボトムプレート用: 押出クリア, 450x300, 3.0mm, 1枚
  • チルトプレート用: 押出クリア / 300x70 / 5mm, 1枚

そのほかネジやスペーサ、スタビライザーなどの部品を合わせて、製作費は15,000円程度となりました。

Fusion360で設計
製作したアクリル板

PCB

設計したPCBはUSBコネクタ、マイコン、キーマトリクス回路といった必要最低限のものを実装した程度です。
回路設計も本職ではなく、また安く済ませたかったというのもあるので、このような構成としました。

設計にはKicad v6を使用し、基板の製造および部品実装の大半はJLCPCBで発注しました。
JLCPCBでの製造費を抑えるため、基板製造数は最小の5枚、うち2枚を部品実装し、運送はOCSの最安プランを選びました。
家にあった部品を一部実装してるため概算となりますが総額は13000円ほどでした。

JLCPCBから届いたPCB

ファームウェア

一般的に自作キーボードと言えばQMK firmwareを使うことが多いです。
しかし、私はファームウェアエンジニアの端くれですので、自分で作った回路のファームウェアは自分で作ったほうが早くデバッグも楽だと考え、あえてQMK firmwareは使用しませんでした。

今回採用したマイコンはSTM32G0シリーズのため、統合開発環境にはSTM32CubeIDEを使用し、HALを使用してUSB HID部分を実装しました。
ツールやライブラリのおかげで、さほど時間をかけずにファームウェアを実装することができました。
キーマトリクス処理部は自分で書く必要があるとはいえ、CubeMX上でCustom HID設定し、コード生成後はHID report descriptorの記述と送信用関数を呼び出すだけで済みました。
下記はUSB HIDの追加実装したコードを抜粋したものです。

// usbd_custom_hid_if.c
/** Usb HID report descriptor. */
__ALIGN_BEGIN static uint8_t CUSTOM_HID_ReportDesc_FS[USBD_CUSTOM_HID_REPORT_DESC_SIZE] __ALIGN_END =
{
  /* USER CODE BEGIN 0 */
    0x05, 0x01, // USAGE_PAGE (Generic Desktop)
    0x09, 0x06, // USAGE (Keyboard)
    0xa1, 0x01, // COLLECTION (Application)
    0x05, 0x07, // USAGE_PAGE (Keyboard)

    0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)
    0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)
    0x15, 0x00, // LOGICAL_MINIMUM (0)
    0x25, 0x01, // LOGICAL_MAXIMUM (1)
    0x75, 0x01, // REPORT_SIZE (1)
    0x95, 0x08, // REPORT_COUNT (8)
    0x81, 0x02, // INPUT (Data,Var,Abs) //1 byte

    0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))
    0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)
    0x15, 0x00, // LOGICAL_MINIMUM (0)
    0x25, 0x65, // LOGICAL_MAXIMUM (101)
    0x95, 0x07, // REPORT_COUNT (7)
    0x75, 0x08, // REPORT_SIZE (8)
    0x81, 0x00, // INPUT (Data,Ary,Abs) //7 bytes
  /* USER CODE END 0 */
  0xC0    /*     END_COLLECTION                */
};
// main.c
/* ref : https://www.usb.org/sites/default/files/hid1_11.pdf */
#define KEY_BUF_NUM 6
typedef struct{
  union{
    struct{
      uint8_t ctrl_l  : 1;
      uint8_t shift_l : 1;
      uint8_t alt_l   : 1;
      uint8_t gui_l   : 1;
      uint8_t ctrl_r  : 1;
      uint8_t shift_r : 1;
      uint8_t alt_r   : 1;
      uint8_t gui_r   : 1;
    }map;
    uint8_t u8;
  }modifiers;
  uint8_t reserved;
  uint8_t key[KEY_BUF_NUM];
}KeyboardHID_t;

int main(void)
{
  /* HAL, Clock, GPIO等の諸々の初期化は省略 */
  
  MX_USB_Device_Init();
  KeyboardHID_t key_data;
  
  while(1){
      /* key matrix処理は省略 */
      
      /* HIDデータ送信 */
      USBD_CUSTOM_HID_SendReport(&hUsbDeviceFS, (uint8_t *)&key_data, sizeof(KeyboardHID_t));
      
      HAL_Delay(10);    
  }

さて、肝心のキーマトリクス処理に関する課題として、メカニカルスイッチを使用する場合はチャタリングという問題が付き纏ってきます。
チャタリングというのはキーを押下した際にスイッチの接点が短時間にぶつかる・離れるを繰り返す現象です。
この問題を対策しないと、キーを1回しか押してないつもりが複数回押されたと判定されてしまい、操作性が低下します。
今回自作したものでキーを押下したときの信号を測定したところ、波形の通りチャタリングが発生していました。

チャタリングの様子
  そのため、以下のようにチャタリング対策を実装しました。この実装後は快適にタイピングできるようになりました。
実装したチャタリング回避処理のフローチャート

作ってみた感想

自作キーボードといっても、人によってどこまで取り組むのかが変わります。
個人的には下記の段階があると考えています。

  1. 市販のキーボードやキットを購入し、キーキャップやスイッチ、キーの割り当てを自分好みにカスタマイズする
  2. 自分好みの配列になるようにケースやPCBを作る
  3. 2に加えてファームウェアも自分で作る

今回初めて3にトライしましたが、「案外それらしいものができちゃうんだな」と思いました。
0からキーボードを設計・開発することの敷居が下がり、良い経験となりました。

ただ、やはりハードウェアの設計は難しく、今作では組立しづらい、PCBの固定が甘く撓む、などの問題が見つかっています。
また、透明のアクリル版を使ったケースはPCBが見えるのは好きなのですが、サイドの空いている隙間からゴミが入りやすく、汚れが気になる点もあります。

次回作ではこれらの問題解消も踏まえ、ケース製作は3Dプリンタ品や金属切削品にトライしたいと思います。
また、PCB・ファームウェア面でも面白味に欠けるものになってしまったので、色々なデバイスを搭載したいと思います。

おわりに

今回は仕事用に開発したキーボードについてご紹介させていただきました。
キーボードは業務を効率良く進める上で毎日触れる重要な道具ですので、皆さんも理想のキーボードの姿を御検討してみてはいかがでしょうか?

GROOVE Xでは様々な領域のエンジニアを募集していますので、ご興味があれば是非ご検討ください。

recruit.jobcan.jp