オリジナルDIYキーボードキットでUSBキーボードを作るためのヒント - USBキーボードの超基本構成
これは何?
ボクが作ったDIYキーボードキット DIY kit 01 - Keyboardを使用してArduinoでUSBキーボードを作るためのヒントをまとめているよ。DIYキーボードキットを持っていなくても、RP2040を使用したUSBキーボードの作り方について知ることができるよ。
DIYキーボードキットはBOOTHで発売中なので、よかったら、お手元に用意して自分だけのキーボードを作ってみてね。
BOOTHの商品ページ
DIY kit 01 - Keyboard XIAO RP2040
対象読者
- DIYキーボードキットをお買い上げ頂いたみんな
- DIYキーボードのプログラムをどうやって作るのか知りたいみんな
環境
- RP2040を搭載したワンボードマイコン
- DIY kit 01 - Keyboard
- Arduino IDE
- Arduino IDEが動作するPC
RP2040を搭載したワンボードマイコン
このページではSeeed StudioさんのXIAO RP2040を使用していると想定して説明しているよ。
DIY kit 01 - Keyboard
ボクが作ったDIYキーボードキットを使用していると想定して説明しているよ。DIYキーボードキットを持っていなくても、RP2040のGPIOに適当なスイッチやメカニカルスイッチを接続することで、このページで説明している内容に対応できるよ。
作りたいもの
このページで作るものを説明するよ。DIYキーボードキットの基板上にあるKey1のキースイッチを押したときに、Hello world!という文字列をPCに入力するコードを作成するよ。
DIYキーボードキットのKey1はXIAO RP2040のD0ピンに接続されているよ。DIYキットを持っていない場合は、RP2040のD0ピンにキースイッチを接続するか、別のGPIOに接続した場合はこの後のプログラムのピンを適宜読み替えてね。
Key1接続箇所 DIY kit 01 - Keyboard 回路図
作ってみよう
実はArduinoのライブラリには最初からUSBキーボードを作るためのライブラリが用意されていて、これはRP2040にも対応しているよ(正確に言うと、RP2040のライブラリにKeyboardライブラリと同じように振る舞うライブラリが入っているみたい。これをArduinoライブラリと言って良いのか分からないので、補足しておくね←認識が間違ってたら教えて欲しいよ)。このライブラリを使うことで、すごく簡単にUSBキーボードを作れるようになっているよ。
USBキーボード用のライブラリ
ArduinoのUSBキーボードのサンプルコードを少し見てみるよ。Arduino IDEのExamplesから09.USB>Keyboard>KeyboardSerialを選択してみてね。以下のようなサンプルコードが表示されるはずだよ。
#include "Keyboard.h"
void setup() {
// open the serial port:
Serial.begin(9600);
// initialize control over the keyboard:
Keyboard.begin();
}
void loop() {
// check for incoming serial data:
if (Serial.available() > 0) {
// read incoming serial data:
char inChar = Serial.read();
// Type the next ASCII value from what you received:
Keyboard.write(inChar + 1);
}
}
このコードでは、シリアルコンソールで入力された文字を受信して、受信した文字のASCIIコード上の次の文字(例えばシリアルでaと入力するとキーボードからbと入力されるよ)をPC側に入力するサンプルになっているよ。スケッチをコンパイルしてRP2040に書き込んでみてね。
Arduinoのサンプルコードのポイントを説明しておくよ。
#include "Keyboard.h"
キーボードのライブラリをインクルードしているよ。ライブラリを使用するために必要だよ。
Keyboard.begin();
キーボードのライブラリを初期化しているよ。setup()関数内で1回だけ実行してね。
Keyboard.write(inChar + 1);
キーボードから指定された文字をPC側へ入力するよ。この関数で入力できる文字は1文字だけだよ。文字列をPCへ入力したい場合は、print関数を使用するよ。print関数は1文字でも文字列でもOKだよ。
Keyboard.print("Hello");
Arduinoさんの公式ドキュメントは以下を参照してね。
必要な機能を実装してみよう
Arduinoのキーボードライブラリについて分かったと思うから、実際にDIYキーボードキット上のKey1を押したときにHello World!と入力するコードを作成するよ。最後にサンプルコードを示しているけど、まずは自分で作成してみてね。
キーボードを制御するために必要な機能は以下の通りだよ。それぞれの機能の実装方法についてポイントを説明していくよ。
- Key1が押されたことを検出する
- Key1が押されたときにHello World!とPCへ入力する
Key1が押されたことを検出する
ArduinoでGPIOの状態を知るためには、setup関数内でピンのモードを設定する必要があるよ。下記の例のように、setup関数内でpinMode関数を呼び出して、指定したピンのモードを設定するよ。Key1はRP2040のD0ピンに繋がっているから、defineを使用してPIN_KEY_1を定義しているよ。
pinMode関数の2番目の引数でピンのモードを指定するよ。INPUT_PULLUPはピンのモードを入力にして、RP2040内部でD0を電源電圧にプルアップするよ。
プルアップ?
上の方にある回路図を見て欲しいんだけど、Key1には2つのピンがあって、1つはRP2040のD0、もう1つはGNDに接続されているよね。この場合、Key1の状態変化を知るためには、Key1を押していない(スイッチが閉じていない)ときはD0がHIGHになっていて欲しいよね。そのためには、大体10kΩぐらいのプルアップ抵抗というものを電源とD0の間に入れる必要があるんだけど、最近のマイコンは内部にこのプルアップ抵抗を持っていて、プログラムからOn/Offできるようになっているよ。pinMode関数の2番目の引数でINPUT_PULLUPを指定することで、マイコン内部でD0がプルアップされた(D0がHIGHの電圧まで引っ張り上げられた)状態になるよ。Key1を押し下げる(スイッチが閉じる)とD0はGNDと繋がるので、D0はLOWになるよ。D0がGNDと同じ電圧=0Vになっても、プルアップ抵抗のおかげで電源とGNDはショートせずに済むよ。
ピンの設定ができたら、後はピンの状態を確認するだけだね。ピンの状態はdigitalRead関数を呼び出すことで知ることができるよ。digitalRead関数の引数に状態を知りたいピンの番号を指定するよ。ピンの状態がLOWならLOW, HIGHならHIGHが返ってくるよ。
DIYキーボードキットのキースイッチはキーを押し下げたときにスイッチが閉じてD0はLOWになるから、digitalReadがLOWになっているときがスイッチが押されている状態だよ。これを active low というよ。逆にスイッチが押されたときにHIGHになるパターンは active high というよ。
#define PIN_KEY_1 D0
void setup() {
// ・・省略・・
pinMode(PIN_KEY_1, INPUT_PULLUP);
}
void loop() {
int key1 = digitalRead(PIN_KEY_1);
// ・・省略・・
}
Key1が押されたときにHello World!とPCへ入力する
これは、先ほどのKeyboardライブラリで説明した通りだね。文字列をPCへ入力するための関数はprint関数だよ。Key1が押されたときにprint関数を呼び出すことで、文字列をPCへ入力できそうだね。
サンプルコード
うまく実装できたかな?ボクが作成したサンプルコードを書いておくよ。このサンプルコードは、Key1を押したときにHello World!という文字列をPCに入力するよ。ArduinoにUSBキーボードのライブラリが用意されていることで、すごく簡単にUSBキーボードが作れるってこと、分かってもらえたかな?
#include "Keyboard.h"
#define PIN_KEY_1 D0
void setup() {
Serial.begin(9600);
Serial.println("XIAO Keyboard");
pinMode(PIN_KEY_1, INPUT_PULLUP);
Keyboard.begin();
}
void loop() {
int key1 = digitalRead(PIN_KEY_1);
if(key1 == LOW){
Keyboard.print("Hello World!");
}
delay(50);
}
応用 - 複数のキーを同時に送る
キーボードを作るなら色々なショートカットキーを入力できるようにしたいよね。そのために、複数のキーの組み合わせを同時にPCへ送信する必要があるけど、そのための方法について説明するよ。
複数のキーを同時に送る手順は以下の通りだよ。
- 1つめのキーを押し下げた状態にする
- 2つめのキーを押し下げた状態にする
- 全てのキーを離した状態にする
キーを押し下げた状態にするには、Keyboardライブラリのpress関数を使用するよ。以下のようにすると、Nキーがずっと押しぱなしになるよ。
Keyboard.press('n');
押しっぱなしになったキーを離すにはreleaseAll関数を使用するよ。以下のようにすると、押されたキーが全て離された状態になるよ。
Keyboard.releaseAll();
複数のキーを同時に入力する方法は見えてきたかな?例えば、Ctrlキーを押しながらNキーを押すサンプルは以下の通りだよ。キーとキーの間にdelayを入れているのは、delayが無いとうまく動作しなかったから、キーとキーの間は10ms待つようにしているよ。これは環境に依存するかもしれないので、色々と調整してみてね。
char ctrlKey = KEY_LEFT_CTRL;
//・・省略・・
void sendKey(){
//・・省略・・
Keyboard.press(cmdKey);
delay(10);
Keyboard.press('n');
delay(10);
Keyboard.releaseAll();
}
Ctrlキーのような特殊なキーの割り当てはArduinoの公式ドキュメントを参照してね。
まとめ
このページでは、RP2040を使用してUSBキーボードを作る方法について説明したよ。USBキーボードのライブラリがArduinoに用意されているから、とっても簡単に作成できたよね。このページでは1つのキースイッチが押されたときの処理だけだったから、もっとキーを増やしたときの処理とか、ロータリーエンコーダからの入力をどうやって処理するのかなど、色々考えてみてね。
分からないことがあったらXで気軽に質問してね!
じゃあ、またね!
Discussion