第15回 ミニキーボード製作

今までの習得した知識を使って、ミニキーボードを製作します。

目次

キーボード製作の前の注意

今回からArduino Microを、USBキーボードとして機能するようにプログラミングをしていきます。

ところで、プログラミングは失敗がつきものです。例えば、プログラミングに失敗してしまい、どのスイッチも押していないのに「a」という文字をずっとPCに送り続けるようになってしまう場合もあるかもしれません。

そのようになってしまった場合、新しいスケッチを書き込もうとしても、これから書き込むスケッチのウィンドウにどんどん「a」が入力されてしまい、結果として正しいスケッチが書き込めなくなってしまいます。

プログラム不具合の例

このようになると、新しいスケッチが書き込めなくなり、そのArduino Microは永遠に「a」という文字をひたすら入力する専用のキーボードになってしまいます。

Ardunio Microでは、このようなケースになってしまうことも想定してリセット方法が用意されています。そこで、今回から3回にわたって以下のように説明を進めます。

  1. 今回の記事では何種類かのミニキーボードを製作します。掲載するスケッチは正常に動作することを確認済みですので、スケッチをそのままコピペして動作確認するようにしてください。ご自身でスケッチを変更する場合は十分に確認してからArduino Microに書き込むようにしてください。
  2. 次回の第16回の記事では、プログラミングに失敗してArduino Microが正常に反応しなくなってしまった場合の対処方法を説明します。
  3. 第17回の記事では、今までの知識を活用してチャレンジ課題に取り組んでみます。自分でプログラムを作成しますので、プログラミングに失敗するとArduino Microが正常に反応しなくなる可能性もあります。その場合、第16回で説明した方法でArduino Microをリセットして、正しくスケッチが書き込めるようにしてください。

ミニキーボードを作ってみよう

前回までの記事で、以下のプログララミング方法を習得しました。

  • Aruino MicroをPCに接続したときにキーボードとして認識してもらう処理
  • Arduino MicroからPCに文字データを送る処理
  • スイッチを押したことを検知する処理

これらのプログラミングができれば、キーボードを製作することができるようになります。そこで、言い訳キーボードを作る前に、今回の記事ではミニキーボードを作ってみます。

製作するキーボードは以下の4種類です。これらのスケッチを通して、キーボードライブラリとスイッチライブラリの使い方に慣れましょう!

  1. 「a」と「b」の2文字入力キーボード
  2. 「a」と「b」の2文字と、それぞれ大文字の「A」と「B」にするためのshift機能がついたキーボード
  3. カット、コピー、ペーストの3つの機能のキーボード
  4. 「a」の1文字と、スイッチをダブルクリックすると大文字の「A」になるキーボード

それぞれのキーボードのスケッチは必要な部分のみ説明します。説明がない部分については今までの知識で十分理解できると思いますので、スケッチのコメントを参考にスケッチ全体を理解するようにしてみてください。

1. 「a」と「b」の2文字入力キーボード

左側のスイッチを押すと「a」、中央のスイッチを押すと「b」を入力できるようなキーボードを製作します。

左側のスイッチ検知は、スイッチライブラリを使用します。最初にpoll()メソッドでスイッチ状態の調査をして、次にpushed()メソッドで押されたかどうかを判定します。

押されたことがわかったら、キーボードライブラリを使用してKeyboard.print("a");というようにスイッチに対応する文字をPCに送ります。

スケッチは以下のように作成してみました。

/*
 * ミニキーボードのスケッチ
 *  左スイッチ: 「a」を入力
 *  中央スイッチ:「b」を入力
 */

// ライブラリをインクルード
#include <Keyboard.h>
#include <avdweb_Switch.h>

// スイッチのピン番号
#define SWITCH_HIDARI 23 // 左側スイッチ
#define SWITCH_CHUO   22 // 中央スイッチ

// スイッチクラスのインスタンスを生成
Switch hidariSwitch(SWITCH_HIDARI); // 左側スイッチのインスタンス
Switch chuoSwitch(SWITCH_CHUO);     // 中央スイッチのインスタンス


void setup() {

  // キーボードの接続処理
  Keyboard.begin();

  // スイッチ接続ピンの設定
  pinMode(SWITCH_HIDARI, INPUT_PULLUP);
  pinMode(SWITCH_CHUO,   INPUT_PULLUP);

}

void loop() {

  // スイッチライブラリに左側スイッチ状態の調査を指示
  hidariSwitch.poll();
  
  // 左側スイッチが押されたら「a」をPCに送信
  if( hidariSwitch.pushed() ){
    Keyboard.print("a");
  }


  // スイッチライブラリに中央スイッチ状態の調査を指示
  chuoSwitch.poll();

  // 中央スイッチが押されたら「b」をPCに送信
  if( chuoSwitch.pushed() ){
    Keyboard.print("b");
  }

}

2. 「a」と「b」の2文字と大文字にするためのshift機能がついたキーボード

(1)のスケッチでは「a」と「b」の文字しか入力できません。右側のスイッチが空いていますので、右側スイッチをshiftキーのように使ってみましょう。

shiftキーに見立てた右側スイッチの状態に応じて、左側スイッチが押された時と中央スイッチが押された時、以下のような文字入力ができるようにしてみます。

右側スイッチの状態 左側スイッチが押された時 中央スイッチが押された時
OFF 「a」を送信 「b」を送信
ON 「A」を送信 「B」を送信

アルゴリズムは以下のように考えてみました。

(1)のスケッチでは左側スイッチが押された時は「a」、中央スイッチが押された時は「b」を送信します。(1)のスケッチで、左側スイッチが押された時、さらに右側スイッチの状態を確認して右側スイッチの状態に応じて「a」または「A」をPCに送信することにしました。

スケッチは以下のように作成してみました。

/*
 * ミニキーボードのスケッチ
 *  右側スイッチがOFFのとき
 *    左側スイッチ:「a」を入力
 *    中央スイッチ:「b」を入力
 *  右側スイッチがONのとき
 *    左側スイッチ:「A」を入力
 *    中央スイッチ:「B」を入力
 */

// ライブラリをインクルード
#include <Keyboard.h>
#include <avdweb_Switch.h>

// スイッチのピン番号
#define SWITCH_HIDARI 23 // 左側スイッチ
#define SWITCH_CHUO   22 // 中央スイッチ
#define SWITCH_MIGI   21 // 右側スイッチ

// スイッチクラスのインスタンスを生成
Switch hidariSwitch(SWITCH_HIDARI); // 左側スイッチのインスタンス生成
Switch chuoSwitch(SWITCH_CHUO);     // 中央スイッチのインスタンス生成
Switch migiSwitch(SWITCH_MIGI);     // 右側スイッチのインスタンス生成


void setup() {

  // キーボードの接続処理
  Keyboard.begin();

  // スイッチ接続ピンの設定
  pinMode(SWITCH_HIDARI, INPUT_PULLUP);
  pinMode(SWITCH_CHUO,   INPUT_PULLUP);
  pinMode(SWITCH_MIGI,   INPUT_PULLUP);

}

void loop() {

  // スイッチライブラリに左側スイッチ状態の調査を指示
  hidariSwitch.poll();
  
  // 左側スイッチが押されたかどうか判定する
  if( hidariSwitch.pushed() ){
    // スイッチが押されていたら、右側スイッチの状態を確認する
    if( digitalRead(SWITCH_MIGI) ) {
      // 右側スイッチがOFFのとき
      Keyboard.print("a");
    } else {
      // 右側スイッチがONのとき
      Keyboard.print("A");
    }
  }


  // スイッチライブラリに中央スイッチ状態の調査を指示
  chuoSwitch.poll();
  
  // 中央スイッチが押されたかどうかを判定する
  if( chuoSwitch.pushed() ){
    // スイッチが押されていたら、右側スイッチの状態を確認する
    if( digitalRead(SWITCH_MIGI) ) {
      // 右側スイッチがOFFのとき
      Keyboard.print("b");
    } else {
      // 右側スイッチがONのとき
      Keyboard.print("B");
    }
  }

}

3. カット、コピー、ペーストの3つの機能のキーボード

次に、カット、コピー、ペースト機能のキーボードを製作してみます。

何か文書を作成するとき、コピぺってよく使いますよね。普通のキーボードでは、Windowsの場合はCtrl+C、macOSの場合はcommand+Cというように、キーを組み合わせて使用します。

よく使う機能ですので、使うたびに2つのキーを押すのはちょっと面倒です。そこで、スイッチ1個押すだけで、カット、コピー、ペーストの機能が使えるようにしてみます。

キーボードライブラリはこのようなキー操作にも対応していますので、その機能を使用して以下のように押されたスイッチに応じてカット、コピー、ペーストができるキーボードを製作します。

OS 左側スイッチ
カット
中央スイッチ
コピー
右スイッチ
ペースト
Windows Ctrl + X Ctrl + C Ctrl + V
macOS Command + X Command + C Command + V

また、キーボードライブラリではキーを押したり離したりする操作を行うメソッドが用意されています。以下のメソッドになります。

メソッド 意味 使い方
press(文字またはキー) 引数で指定したキーを押す Keyboard.press(‘x’);
キー「x」を押す
release(文字またはキー) 引数で指定したキーを離す Keyboard.release(‘x’);
キー「x」を離す
releaseAll()
※引数なし
押しているキーをすべて離す Keyboard.releaseAll();

注意点としては、通常のキーは、キーに書かれている文字を「 ‘ 」で囲みます。「x」キーの場合は'x'、「c」キーの場合は'c'などです。

またCtrlキー、Commandキー、Deleteキーなどの特殊キーについては、キーボードライブラリのヘッダファイルの中で、以下のように#defineされています。例えばWindowsキーボードの場合、左側のCtrlキーを押す場合は

Keyboard.press(KEY_LEFT_CTRL);

のように書きます。また、このように押したキーを離すには、

Keyboard.release(KEY_LEFT_CTRL);

のように書きます。

以下の表は、キーボードライブラリで定義されている特殊キーの定義名です。

キー 定義名
左側Ctrlキー(Windows) KEY_LEFT_CTRL
左側Altキー(Windows) KEY_LEFT_ALT
左側Commandキー(macOS) KEY_LEFT_GUI
左側Shiftキー KEY_RIGHT_SHIFT
右側Ctrlキー(Windows) KEY_RIGHT_CTRL
右側Altキー(Windows) KEY_RIGHT_ALT
右側Commandキー(macOS) KEY_RIGHT_GUI
右側Shiftキー KEY_RIGHT_SHIFT
上矢印キー KEY_UP_ARROW
下矢印キー KEY_DOWN_ARROW
左矢印キー KEY_LEFT_ARROW
右矢印キー KEY_RIGHT_ARROW
バックスペースキー KEY_BACKSPACE
TABキー KEY_TAB
リターンキー KEY_RETURN
ESCキー KEY_ESC
Insertキー KEY_INSERT
Deleteキー KEY_DELETE
Page Upキー KEY_PAGE_UP
Page Downキー KEY_PAGE_DOWN
Homeキー KEY_HOME
Endキー KEY_END
Caps Lockキー KEY_CAPS_LOCK
ファンクションキー KEY_F1など
F1〜F24

スケッチは以下のように作成してみました。なお、WindowsとmacOSではショートカットキーが異なりますので、macOSの場合は11行目のコメントアウトを外し、Windowsの場合は14行目のコメントアウトを外してください。

/*
 * ミニキーボードのスケッチ
 *  左側スイッチ: カットキー Command+X(macOS), Ctrl+X(Windows)
 *  中央スイッチ: コピーキー Command+C(macOS), Ctrl+C(Windows)
 *  右側スイッチ: ペーストキー Command+V(macOS), Ctrl+V(Windows)
 */

// commandまたはctrlキーの定義

//   macOSの場合は次の行のコメントをはずしてください (先頭の//を取る)
//#define shortcutKey KEY_LEFT_GUI

//   Windowsの場合は次行のコメントをはずしてください (先頭の//を取る)
//#define shortcutKey KEY_LEFT_CTRL 

// ライブラリをインクルード
#include <Keyboard.h>
#include <avdweb_Switch.h>

// スイッチのピン番号
#define SWITCH_HIDARI 23 // 左側スイッチ
#define SWITCH_CHUO   22 // 中央スイッチ
#define SWITCH_MIGI   21 // 右側スイッチ

// スイッチクラスのインスタンスを生成
Switch hidariSwitch(SWITCH_HIDARI);
Switch chuoSwitch(SWITCH_CHUO);
Switch migiSwitch(SWITCH_MIGI);


void setup() {

  // キーボードの接続処理
  Keyboard.begin();

  // スイッチ接続ピンの設定
  pinMode(SWITCH_HIDARI, INPUT_PULLUP);
  pinMode(SWITCH_CHUO,   INPUT_PULLUP);
  pinMode(SWITCH_MIGI,   INPUT_PULLUP);

}

void loop() {

  // スイッチライブラリに左側スイッチ状態の調査を指示
  hidariSwitch.poll();
  
  // 左側スイッチが押されたか判定して、押されていたらカットキーの組み合わせを送信する
  if( hidariSwitch.pushed() ){
    // Command/Ctrlキーを押す
    Keyboard.press(shortcutKey);
    // 'x'キーを押す
    Keyboard.press('x');
    // ちょっと待つ
    delay(100);
    // 両方のキーを離す
    Keyboard.releaseAll();
  }

  // スイッチライブラリに中央スイッチ状態の調査を指示
  chuoSwitch.poll();
  
  // 中央スイッチが押されたか判定して、押されていたらコピーキーの組み合わせを送信する
  if( chuoSwitch.pushed() ){
    // Command/Ctrlキーを押す
    Keyboard.press(shortcutKey);
    // 'c'キーを押す
    Keyboard.press('c');
    // ちょっと待つ
    delay(100);
    // 両方のキーを離す
    Keyboard.releaseAll();
  }

  // スイッチライブラリに右側スイッチ状態の調査を指示
  migiSwitch.poll();
  
  // 右側スイッチが押されたか判定して、押されていたらペーストキーの組み合わせを送信する
  if( migiSwitch.pushed() ){
    // Command/Ctrlキーを押す
    Keyboard.press(shortcutKey);
    // 'v'キーを押す
    Keyboard.press('v');
    // ちょっと待つ
    delay(100);
    // 両方のキーを離す
    Keyboard.releaseAll();
  }

}

4. 「a」の1文字入力と、ダブルクリックすると大文字になるキーボード

最後に、同じスイッチでもシングルクリックしたとき(カチッと1回押したとき)と、ダブルクリックしたとき(カチッカチッと短い間隔で2回押したとき)で、入力できる文字を変えてみます。

以下のような入力ができるキーボードを製作してみます。

キー操作 左側キー 右側キー
シングルクリック 「a」を送信 「b」を送信
ダブルクリック 「A」を送信 「B」を送信

スイッチライブラリの使い方ですが、poll()メソッドでスイッチの状態を調査した後、以下のメソッドでシングルクリックかダブルクリックか判定することができます。

メソッド 意味 使い方
singleClick() シングルクリックを検知
した場合1を返す
if( hidariSwitch.singleClick() ) {
シングルクリックした場合の処理;
}
doubleClick() ダブルクリックを検知
した場合1を返す
if( hidariSwitch.doubleClick() ) {
ダブルクリックした場合の処理;
}

スケッチは以下のように作成してみました。

/*
 * ミニキーボードのスケッチ
 *  シングルクリックの場合
 *    左スイッチ: 「a」を入力
 *    中央スイッチ:「b」を入力
 *  ダブルクリックの場合
 *    左スイッチ: 「A」を入力
 *    中央スイッチ:「B」を入力
 */

// ライブラリをインクルード
#include <Keyboard.h>
#include <avdweb_Switch.h>

// スイッチのピン番号
#define SWITCH_HIDARI 23 // 左側スイッチ
#define SWITCH_CHUO   22 // 中央スイッチ

// スイッチクラスのインスタンスを生成
Switch hidariSwitch(SWITCH_HIDARI);
Switch chuoSwitch(SWITCH_CHUO);


void setup() {

  // キーボードの接続処理
  Keyboard.begin();

  // スイッチ接続ピンの設定
  pinMode(SWITCH_HIDARI, INPUT_PULLUP);
  pinMode(SWITCH_CHUO,   INPUT_PULLUP);

}

void loop() {

  // スイッチライブラリに左側スイッチ状態の調査を指示
  hidariSwitch.poll();
  
  // 左側スイッチがシングルクリックされたら「a」をPCに送信
  if( hidariSwitch.singleClick() ){
    Keyboard.print("a");
  }
  // 左側スイッチがダブルクリックされたら「A」をPCに送信
  if( hidariSwitch.doubleClick() ){
    Keyboard.print("A");
  }


  // スイッチライブラリに中央スイッチ状態の調査を指示
  chuoSwitch.poll();

  // 中央スイッチがシングルクリックされたら「b」をPCに送信
  if( chuoSwitch.singleClick() ){
    Keyboard.print("b");
  }
  // 中央スイッチがダブルクリックされたら「B」をPCに送信
  if( chuoSwitch.doubleClick() ){
    Keyboard.print("B");
  }

}

わからないところはありませんか?

基礎編パート2では、新しい考え方などをいろいろ習得してきました。特に大きな概念として「オブジェクト」「クラス」「インスタンス」「メソッド」という項目を習得してきました。

これらの概念でつまづく人も多いので、今回のスケッチでわからないところがありましたら、そのままにせずに十分理解してから先に進めるようにしていただければと思います。わからないところはコメント欄からご質問ください。

それでは、次回はArduino Microのリセット方法、その次にチャレンジ課題に挑戦してみましょう。そのあとはいよいよ言い訳キーボードに向けてスケッチを仕上げていきます。

更新履歴

日付 内容
2021.9.25 新規投稿
通知の設定
通知タイミング
guest
0 コメント
本文中にフィードバック
全てのコメントを見る
目次