キューブ型のマクロキーボードを作ったった
はじめに
先日、キットを購入して組み立てて自作キーボード沼に入った(自作キーボード沼にようこそ)。
その後、沼落ちしたからには、自分でも自作キーボードを設計したいなーと思い、キー数少なめのキューブ型のマクロキーボードを作ることにした。最終的にこんなん作ったった。作る経緯と作り方をドキュメントにしとく。
ちなみに、名前をつけようと思って、KeyCube
にしよかなと息子氏に話したら「2」をつけるようにアドバイスをもらったので、KeyCube 2
にした。似たのを2つ印刷してて2つ目だから「2」をつけたほうがいいとのこと。3
もありそうな期待感があっていい感じ。テトラポッドみたいやから、そっちの名前を拝借しようかとも思ったけど、テトラポッドは四面体的な形やからやめた。
経緯
自作キーボードの入門として気になってたのは、少ないキーでRaspberry Pi Picoとかを使ってショートカットキーとかを入力できるようにするマクロキーボード。例えば、こんな感じで作ってる人がいる。
- This Raspberry Pi Pico-Based Macro Keyboard Features a 3D-Printed Circuit Board - Hackster.io
- How to Build a Raspberry Pi Pico-Powered Stream Deck Keypad | Tom's Hardware
比較的、気軽にできて良い感じ。普通のキーボードは、配線がややこしくて、ダイオードも入れなあかんかったり、色々めんどくさい。なので、ここらの手っ取り早いやつから試すことにした。
ただ、普通に真似して作ったら、チャレンジングな部分があんましなくて、どーしよっかなーと思ってた。
そんな中、別の探しものしてるときに、thingiverseでこんなん見つけた。
MX Fidget Cube by judy2k - Thingiverse
テトラポッドみたいで、とってもいい感じ。
印刷してキーをつけたら、こんな感じ。ずっと触ってたい。キーはMint60スターターセットであまったやつを使った。カラフルでいい感じ。
しばらく触ってたら、中のスペースにBLEのマイコンとボタン電池入らないかなーと思い始めた。ただ、小さい場所に入れるのは難易度高いので、キーを1つ犠牲にして、ATOM Matrix (M5Atom) つけるのならできるかなーと思い始めた。
作戦は、こんな感じ。
- 3Dモデルを修正して、穴を大きくし、M5Atomをはめる
- 中で配線する
- M5Atomで使われてるマイコンESP32のライブラリを使ってBLEキーボード化する。
ちょうどよい難易度な気がした。ということで、作ることにした。以降で試行錯誤した結果を示す。
環境+材料
ここらを使った。
コンピュータ
- MacOS
モデリング
- Dashboard | Tinkercad
- Ultimaker Cura: Powerful, easy-to-use 3D printing software
- Creality Ender 3 V2 Official Store, Best DIY 3D Printers for beginners and creators in 2021 – Creality3D Store® Official Store for Creality 3D Printers and Accessories
- PLAのフィラメント
回路
- ATOM Matrix
- Mint60スターターセットの残ったキー
- 普通のピンヘッダ
- 普通の洗剤
- 普通のUSB-Cケーブル
ソフトウェア
モデリング
この方のモデルを拝借して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
ライブラリはこれを使った。ありがたや。
試したら、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したあとに、カーソルキーを割り当てたりして、動作確認した。期待通り動いた。特に長押しで連続してトリガーされるのが、キーボード感があって良い感じ。
おわりに
イメージしたものが、小さめの労力で作れたので満足。自作キーボードを設計したい欲も満たされて、3Dプリンタ活用スキルも磨けた。
今回、3Dプリンタ用のソフト向けにキーを割り当てるけど、ショートカットキーとか、スニペットでも良さげ。ただ、3Dなキー配置なので、3Dなソフトとかゲームに使いやすそうな気はしてる。
使いみちが微妙なので、アイデアゆる募。
Discussion