この記事は、「Arduino Micro」を使った基本的なキー入力が行えることを前提としています。
「Arduino Micro」でキー入力を行ったことが無いという方は、以下の記事で説明していますので、是非、そちらを先にご覧になってください。
目次
本記事で使用するもの
記事を見て、気に入ったものがあれば、是非チェックをしてみてください。
文字列の入力速度を調整する
前回の記事にて、文字列のキー入力を行う際に、「Keyboard.print()」という関数を用いました。
しかし、「Keyboard.print()」は一つ一つの文字が間髪入れずにキー入力されるため、環境によっては処理が追いつかず上手く入力されないことがありました。
そこで今回は、「Keyboard.write()」と「delay()」を利用して、一つ一つの文字に対して一定の間隔でキー入力を行い、処理が追いつかないという問題を解決しようと思います。
空のスケッチを書き込む
回路を作成する前に、空のスケッチ(「ファイル」タブの「New Sketch」をクリックしたときに出てくる何の処理も書かれていないスケッチ)を書き込みます。
前に作成した回路がある場合は、その回路を崩す前に空のスケッチを書き込みます。
そうすることにより、前に書き込んだスケッチが、新しく作成しようとしている回路に影響を及ぼすことを防げます。
また、前に作成した回路を崩さずに空のスケッチを書き込むのは、ボードへの入力が無いことによって、PCへの操作が行われる場合があるからです。
新しい回路を作成するときは、いつもこの作業をやっておくと、安全に回路を作成することができます。
回路を作成する
以下のような回路を作成します。
スケッチを書き込む
回路の作成が終わりましたら、以下のようなスケッチを書き込みます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
/* ArduinoMicroで操作(2,文字列の入力速度); 2024/06/27 keyboard_print_test スケッチの詳細はこちら↓ https://mecha-norimaki.com/arduino_micro_02/ 2024/06/27 コメントを編集しました。 */ //ライブラリの読みこみ #include <Keyboard.h> //キー入力を行うスイッチに繋がっているピンを指定 const int keySwitches[] = { 2, 3, 4 }; //USBを繋げた瞬間暴走してしまうような状態を止めるためのピンを指定 const int pausePin = 13; void setup() { //pausePinに指定したピンを入力ピンとして設定(デフォルト設定なので省略しても良い) pinMode(pausePin, INPUT); //pausePinに指定したピンがHIGHのとき空の文を無限に行い以降の文を実行しないようにする while (digitalRead(pausePin)) {} //キー入力を行うスイッチに繋がっているピンをプルアップ付きの入力ピンとして設定する for (int i = 0; i < sizeof(keySwitches) / sizeof(keySwitches[0]); i++) { pinMode(keySwitches[i], INPUT_PULLUP); } //キーボードとして利用するための初期設定 Keyboard.begin(); } void loop() { //while文による繰り返しの際に利用 int i; //keySwitches[0]のスイッチが押されたらAppleと高速で入力 if (!digitalRead(keySwitches[0])) { char apple[] = "Apple"; i = 0; while (apple[i]) { Keyboard.write(apple[i]); i++; //入力速度を調節するための待機 delay(10); } delay(200); } //keySwitches[1]のスイッチが押されたらBananaと素早く入力 if (!digitalRead(keySwitches[1])) { char banana[] = "Banana"; i = 0; while (banana[i]) { Keyboard.write(banana[i]); i++; //入力速度を調節するための待機 delay(50); } delay(200); } //keySwitches[2]のスイッチが押されたらCherryとゆっくり入力 if (!digitalRead(keySwitches[2])) { char cherry[] = "Cherry"; i = 0; while (cherry[i]) { Keyboard.write(cherry[i]); i++; //入力速度を調節するための待機 delay(1000); } delay(200); } } |
スケッチを書き込んだ後に、キーボードの入力が勝手に行われる場合は、USBケーブルを抜いてください。
その後、回路とスケッチが間違っていないかの確認を行います。
間違って書き込んだスケッチによる操作により、修正したスケッチの書き込みが困難な場合は、対策を次の節である「スケッチの解説」にて説明していますので、先にそちらをご覧ください。
回路とスケッチが正しい場合、押したスイッチに応じて文字列の入力が行われます。
以下に入力できる欄を作ったので、試しにキー入力を行ってみてください。
入力される文字列は、入力モード(半角英数字やひらがな入力など)の影響を受けます。
「Apple」、「Banana」、「Cherry」と入力したい場合は、入力モードを半角英数字にします。
スイッチを押したのに入力が行われない場合は、回路とスケッチが間違っていないか確認をしてみてください。
スケッチの解説
暴走を止めるための文
私は「Arduino Micro」にスケッチを書き込むとき、以下のような文を書いて暴走したときの対処を行っています。
まず、スケッチの初めにある以下の文で、「pausePin」という定数を用意して暴走を止めるためのピンの番号を格納しています。
18 19 |
//USBを繋げた瞬間暴走してしまうような状態を止めるためのピンを指定 const int pausePin = 13; |
次に、「void setup()」初めに、以下の文を書くことにより、暴走を止めるためのピンがHIGHのとき空のループを行うようにしています。
23 24 25 26 27 |
//pausePinに指定したピンを入力ピンとして設定(デフォルト設定なので省略しても良い) pinMode(pausePin, INPUT); //pausePinに指定したピンがHIGHのとき空の文を無限に行い以降の文を実行しないようにする while (digitalRead(pausePin)) {} |
上記の文が正しく書き込めていれば、PCとの接続前に「pausePin」に指定したピン(上記の場合だと13番ピン)と5Vピンを接続することで、暴走を止めることができます。
上記の文の詳細や上記の文が機能しなかったときの対処法は、以下の記事で説明していますので、良く分からないという方は、是非以下の記事をご覧になってください。
スイッチを扱うための初期設定
スイッチを扱うための初期設定は以下の通りです。
まず、スケッチの初めにある以下の文により、キー入力を行うスイッチに繋がっているピンの番号を配列としてまとめています。
15 16 |
//キー入力を行うスイッチに繋がっているピンを指定 const int keySwitches[] = { 2, 3, 4 }; |
続いて、「void setup()」の中で以下のような文を記述しています。
29 30 31 32 |
//キー入力を行うスイッチに繋がっているピンをプルアップ付きの入力ピンとして設定する for (int i = 0; i < (sizeof(keySwitches) / sizeof(keySwitches[0])); i++) { pinMode(keySwitches[i], INPUT_PULLUP); } |
上記の文では、「sizeof()」を利用して配列の要素数を確認し、さらに「for文」で要素の数だけ処理を繰り返すことにより、配列にまとめた番号のピンをすべてプルアップ付きの入力ピンとして設定しています。
上記の文の詳細は、以下の記事で説明していますので、良く分からないという方は、是非以下の記事をご覧になってください。
文字列を分解する
今回は、「Keyboard.write()」により、一つ一つの文字をキー入力するため、まず、文字列を一つ一つの文字に分解する必要がありますが、その方法は意外と簡単です。
よく、「Serial.print()」などで文字列を出力させるときに、「”Hello”」のように” “で文字列を囲って記述するパターンを見かけると思います。
実はこの「”Hello”」は、char型の配列として扱われるため、以下のように変数宣言をすれば、配列を扱うのと同じように、文字を一つ一つ扱うことができます。
46 |
char apple[] = "Apple"; |
ここで、文字列データの最後の部分には、Null文字(\0)という文字が存在します。
これは、文字列の終わりを確認するために扱われており、今回のスケッチでもこれを利用します。
分解した文字をキー入力する
文字列の分解ができたので、後は「Keyboard.write()」により文字を順番にキー入力していけば文字列が入力されることになります。
ここで、文字を順番にキー入力するために、繰り返しの処理を行うのですが、今回はwhile文と文字列データの最後の部分にある、Null文字(\0)を利用します。
while文は( )内がtrueのときに、{ }内の処理を繰り返し行います。
この( )内にchar型の文字データが入っていた場合、Null文字(\0)はfalse、それ以外の文字はtrueであると判定されます。
よって、以下の文のような文を記述すれば、Null文字(\0)の前までの文字をキー入力することができるということになります。
46 47 48 49 50 51 52 53 54 55 |
char apple[] = "Apple"; i = 0; while (apple[i]) { Keyboard.write(apple[i]); i++; //入力速度を調節するための待機 delay(10); } |
ここで、while文内の最後にある「delay()」が、入力速度を調節しており、以降で記述している「Banana」、「Cherry」と入力する処理では値を変更して、少し速めの入力と人差し指だけで打ち込んでいるようなゆっくりとした入力を行っています。
文字列の入力をする関数を作成する
上記のスケッチで文字列の入力速度を調節してキー入力をすることができましたが、文字列のキー入力をするたびに、配列の宣言と「while文」を書かなければならないので、面倒くさいです。
そこで、上記の文字列のキー入力を行う処理の部分を関数化して、「Keyboard.print()」のように、お手軽にキー入力ができるように変更を加えたいと思います。
スケッチを書き込む
回路はそのままで、以下のようなスケッチを書き込みます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
/* ArduinoMicroで操作(2,文字列の入力速度); 2024/06/27 keyboard_print_test_2 スケッチの詳細はこちら↓ https://mecha-norimaki.com/arduino_micro_02/ 2024/06/27 コメントを編集しました。 */ //ライブラリの読みこみ #include <Keyboard.h> //キー入力を行うスイッチに繋がっているピンを指定 const int keySwitches[] = { 2, 3, 4 }; //USBを繋げた瞬間暴走してしまうような状態を止めるためのピンを指定 const int pausePin = 13; void setup() { //pausePinに指定したピンを入力ピンとして設定(デフォルト設定なので省略しても良い) pinMode(pausePin, INPUT); //pausePinに指定したピンがHIGHのとき空の文を無限に行い以降の文を実行しないようにする while (digitalRead(pausePin)) {} //キー入力を行うスイッチに繋がっているピンをプルアップ付きの入力ピンとして設定する for (int i = 0; i < sizeof(keySwitches) / sizeof(keySwitches[0]); i++) { pinMode(keySwitches[i], INPUT_PULLUP); } //キーボードとして利用するための初期設定 Keyboard.begin(); } void loop() { //keySwitches[0]のスイッチが押されたらAppleと高速で入力 if (!digitalRead(keySwitches[0])) { customPrint("Apple", 10); delay(200); } //keySwitches[1]のスイッチが押されたらBananaと素早く入力 if (!digitalRead(keySwitches[1])) { customPrint("Banana", 50); delay(200); } //keySwitches[2]のスイッチが押されたらCherryとゆっくり入力 if (!digitalRead(keySwitches[2])) { customPrint("Cherry", 1000); delay(200); } } //**********速度の調節をして文字列をキー入力する関数********** void customPrint(char text[], int speed) { int i = 0; while (text[i]) { Keyboard.write(text[i]); i++; delay(speed); } } |
以下に入力できる欄を作ったので、試しにキー入力を行ってみてください。
スケッチが正しければ、先程のスケッチと同様の処理が行われるはずです。
スケッチの解説
今回のスケッチでは、char型の配列(文字列)と速度の調節を行うための整数を引数とする関数を作成し、先程と同じように、一つ一つの文字に対して一定の間隔でキー入力を行っています。
配列を引数とする関数を作成する際は、以下の文のように[ ]を付けて、引数を定義します。
59 60 61 62 63 64 65 66 67 68 |
//**********速度の調節をして文字列をキー入力する関数********** void customPrint(char text[], int speed) { int i = 0; while (text[i]) { Keyboard.write(text[i]); i++; delay(speed); } } |
実は配列を引数にする場合は少し特殊で、関数内で「sizeof()」を使っても、引数の配列の長さを測定できないなどの注意点があるのですが、今回はNull文字(\0)を利用したループのため特に問題はありません。
void loop()内では、以下のような文により、関数を呼び出して、文字列のキー入力を行っています。
42 |
customPrint("Apple", 10); |
今回は関数を呼び出す際に、文字列を直接記述していますが、配列を定義しておいて、それを渡したい場合は、以下のように記述すれば、同じようなことが行えます。
1 2 |
char apple[] = "Apple"; customPrint(apple, 10); |
終わりに
皆さん、キー入力の速度を調整することができたでしょうか。
基本的には、「Keyboard.print()」で十分に文字列のキー入力を行えるのですが、私はより確実に文字列の入力が行えるように、今回のようなやり方をよく使います。
また、今回の知識を利用すれば、入力速度を自由に変更できるため、ランダムで速度を少し変えて人間っぽい入力にしてみたり、ゆっくりと文字が入力されていくような演出をしてみたりすると面白いかもしれません。
次回の記事では、Windowsの「ファイル名を指定して実行」を利用して、ファイルを実行するといったことを行いたいと思います。
本記事はここまでです。ご清覧ありがとうございました。
広告
今回の主役である「Arduino Micro」です。
まだ持っていないという方は、この機会に是非購入を検討してみてください。
「Arduino Micro」とPCと接続するためのケーブルです。
MicroBタイプのUSBケーブルが無い場合は、合わせて購入を検討してみてください。
今回使用したカラフルなスイッチのセットです。
スイッチを色で判別したいときや見た目をカラフルしたいときにおすすめです。
今回使用したコンパクトなブレッドボードとジャンパーワイヤーのセットです。
コンパクトな回路を作成する際に役立ちます。
楽天モーションウィジェットとGoogleアドセンス広告です。
気になる商品がございましたら、チェックをしてみてください。