🧊

キューブ型のマクロキーボードを作ったった

2021/06/20に公開

はじめに

先日、キットを購入して組み立てて自作キーボード沼に入った(自作キーボード沼にようこそ)。
その後、沼落ちしたからには、自分でも自作キーボードを設計したいなーと思い、キー数少なめのキューブ型のマクロキーボードを作ることにした。最終的にこんなん作ったった。作る経緯と作り方をドキュメントにしとく。

https://twitter.com/optimisuke/status/1406228483500511239?s=20

ちなみに、名前をつけようと思って、KeyCubeにしよかなと息子氏に話したら「2」をつけるようにアドバイスをもらったので、KeyCube 2にした。似たのを2つ印刷してて2つ目だから「2」をつけたほうがいいとのこと。3もありそうな期待感があっていい感じ。テトラポッドみたいやから、そっちの名前を拝借しようかとも思ったけど、テトラポッドは四面体的な形やからやめた。

経緯

自作キーボードの入門として気になってたのは、少ないキーでRaspberry Pi Picoとかを使ってショートカットキーとかを入力できるようにするマクロキーボード。例えば、こんな感じで作ってる人がいる。

比較的、気軽にできて良い感じ。普通のキーボードは、配線がややこしくて、ダイオードも入れなあかんかったり、色々めんどくさい。なので、ここらの手っ取り早いやつから試すことにした。

ただ、普通に真似して作ったら、チャレンジングな部分があんましなくて、どーしよっかなーと思ってた。

そんな中、別の探しものしてるときに、thingiverseでこんなん見つけた。
MX Fidget Cube by judy2k - Thingiverse

テトラポッドみたいで、とってもいい感じ。

印刷してキーをつけたら、こんな感じ。ずっと触ってたい。キーはMint60スターターセットであまったやつを使った。カラフルでいい感じ。

https://twitter.com/optimisuke/status/1404777633729056773?s=20

しばらく触ってたら、中のスペースにBLEのマイコンとボタン電池入らないかなーと思い始めた。ただ、小さい場所に入れるのは難易度高いので、キーを1つ犠牲にして、ATOM Matrix (M5Atom) つけるのならできるかなーと思い始めた。

https://twitter.com/optimisuke/status/1404824530674012164?s=20

作戦は、こんな感じ。

  1. 3Dモデルを修正して、穴を大きくし、M5Atomをはめる
  2. 中で配線する
  3. M5Atomで使われてるマイコンESP32のライブラリを使ってBLEキーボード化する。

ちょうどよい難易度な気がした。ということで、作ることにした。以降で試行錯誤した結果を示す。

環境+材料

ここらを使った。

コンピュータ

  • MacOS

モデリング

回路

ソフトウェア

モデリング

この方のモデルを拝借してM5Atomをはめれるように修正した。
MX Fidget Cube by judy2k - Thingiverse

Tinkercadつかってモデルを修正した。1箇所穴を大きくして爪をつけた。

印刷時のサポート材は台に接する部分だけにして、傾けて印刷した。45度ぐらいなら、サポート材なしでも失敗せずに印刷できるらしい。

印刷後はこんな感じ。

サポート材をとるとき、案の定、爪が欠けた。めんどくさかったので、このまま使うことにした。本当は、もうちょい太い爪にする等の対策が必要そう。

回路

回路図はこんな感じ。GNDを共通にして5個のキーそれぞれに5個のGPIOを接続する。M5Atom側でプルアップしてる前提。キーの接続方向は気にしなくてよい。1キーに付き1GPIOなのでダイオードもいらない。とってもシンプル。キーが押されてないときはオープンになってプルアップでHIGH、キーが押されているときはクローズドになってLOWとして認識される。

最初に、M5Atomで期待通りプルアップして入力できるか確認した。どのGPIOでもプルアップできた。

配線してく。内部のスペースが小さいので、作業が細かくて辛かった。最終的に、中身がパンパンでM5Atomがはみ出た。再配線はしんどいし、配線は隠れてるから、良しとした。

最初にヘッダピンにはんだ付けした。ショートしそうやったので、真面目に熱収縮チューブ使った。熱収縮チューブはめんどくさいので、はんだをあてて縮めた。

コードの取り回しを考えながら接続してく。

一旦2個つけた。

キーキャップつけるとそれっぽい。

動作確認。いい感じ。

残りもつけてく。中パンパン。

全部つけたところ。いい感じ。

digitalRead()使った簡単な動作確認をして回路と配線はOKとした。

ソフトウェア

全体

Arduino環境でコーディングと書き込みを実施した。
こんな感じ。コピペしまくった。wasPressed()のときとpressedFor()のときにキー入力+LEDの色変更するようにした。
割り当てるショートカットキーは試行錯誤中。
2個以上同時に押されることは考慮してない。どういう動作すべきか考えるのめんどくさくなって、これでよしとした。

#include "M5Atom.h"
#include <BleKeyboard.h>

// M5Atom
uint8_t DisBuff[2 + 5 * 5 * 3];

const int PRESSEDTIME = 500;

void setBuff(uint8_t Rdata, uint8_t Gdata, uint8_t Bdata)
{
    DisBuff[0] = 0x05;
    DisBuff[1] = 0x05;
    for (int i = 0; i < 25; i++)
    {
        DisBuff[2 + i * 3 + 0] = Rdata;
        DisBuff[2 + i * 3 + 1] = Gdata;
        DisBuff[2 + i * 3 + 2] = Bdata;
    }
}

// BLE Keyboard
BleKeyboard bleKeyboard;

// Button
Button BtnDown = Button(39, true, 10);
Button BtnUp = Button(25, true, 10);
Button BtnForward = Button(19, true, 10);
Button BtnBackward = Button(33, true, 10);
Button BtnRight = Button(21, true, 10);
Button BtnLeft = Button(23, true, 10);

// update for buttons
void update(){
	BtnUp.read();
	BtnDown.read();
	BtnForward.read();
	BtnBackward.read();
	BtnRight.read();
	BtnLeft.read();
}

void setup() {
  Serial.begin(115200);
  Serial.println("Starting BLE work!");
  bleKeyboard.begin();

  M5.begin(true, false, true);
  delay(10);
  setBuff(0xff, 0x00, 0x00);
  M5.dis.displaybuff(DisBuff);
}

void loop() {
  if(bleKeyboard.isConnected()) {
    if (BtnForward.wasPressed() | BtnForward.pressedFor(PRESSEDTIME)){
      setBuff(0x40, 0x00, 0x00);
      bleKeyboard.write(KEY_MEDIA_VOLUME_UP);
    } else if (BtnBackward.wasPressed() | BtnBackward.pressedFor(PRESSEDTIME)){
      setBuff(0x00, 0x40, 0x00);
      bleKeyboard.write(KEY_MEDIA_VOLUME_DOWN);
    } else if (BtnRight.wasPressed() | BtnRight.pressedFor(PRESSEDTIME)){
      setBuff(0x00, 0x00, 0x40);
      bleKeyboard.write(KEY_F23);
    } else if (BtnLeft.wasPressed() | BtnLeft.pressedFor(PRESSEDTIME)){
      setBuff(0x20, 0x20, 0x20);
      bleKeyboard.write(KEY_F24);
    } else if (BtnUp.wasPressed() | BtnUp.pressedFor(PRESSEDTIME)){
      setBuff(0x10, 0x10, 0x10);
      bleKeyboard.press(KEY_LEFT_CTRL);
      bleKeyboard.press(KEY_LEFT_GUI);
      bleKeyboard.press('f');
      delay(100);
      bleKeyboard.releaseAll();
    } else if (BtnDown.wasPressed() | BtnDown.pressedFor(PRESSEDTIME)){
      setBuff(0x00, 0x00, 0x00);
    }
    M5.dis.displaybuff(DisBuff);

    delay(200);
    update();
  }
}

キースイッチ入力

digitalRead()使って、まじめに読み取っても良いけども、チャタリングとか、押したタイミングとか気にするの大変。
なので、いろいろ対策済みっぽいM5Atomのライブラリを呼ぶことにした。最初、ライブラリを直接書き換える必要あるかなと思ってたけど、普通にButtonクラスを呼べばいいだけなことに気づいた。

GitHub - m5stack/M5Atom: M5Stack Atom Arduino Library

BLE Keyboard

ライブラリはこれを使った。ありがたや。

GitHub - T-vK/ESP32-BLE-Keyboard: Bluetooth LE Keyboard library for the ESP32 (Arduino IDE compatible)

試したら、Androidでは動いたけど、MacOSで動かなかった。Issuesを確認したら解決方法書いてあった。
List of supported / unsupported Apple devices (iPhones, iPads, Macs etc.) · Issue #51 · T-vK/ESP32-BLE-Keyboard · GitHub

line 152をコメントアウトしたら、Macでいけた。良かった。

  // bleKeyboardInstance->connectionStatus->pAdvertising->setScanResponse(false);

動作確認

Hello Worldしたあとに、カーソルキーを割り当てたりして、動作確認した。期待通り動いた。特に長押しで連続してトリガーされるのが、キーボード感があって良い感じ。

https://twitter.com/optimisuke/status/1406228483500511239?s=20

おわりに

イメージしたものが、小さめの労力で作れたので満足。自作キーボードを設計したい欲も満たされて、3Dプリンタ活用スキルも磨けた。

今回、3Dプリンタ用のソフト向けにキーを割り当てるけど、ショートカットキーとか、スニペットでも良さげ。ただ、3Dなキー配置なので、3Dなソフトとかゲームに使いやすそうな気はしてる。

使いみちが微妙なので、アイデアゆる募。

GitHubで編集を提案

Discussion