第21回 動作確認版言い訳キーボード

言い訳キーボードを製作するための要素技術を一通り確認しました。今回は言い訳キーボードの基本動作確認版のスケッチを作成します。

目次

言い訳キーボードの仕様

第18回の記事で言い訳キーボードの仕様を決めましたが、もう一度簡単に確認します。

言い訳キーボードには3個のスイッチがあります。これらのスイッチを押すと、スイッチに割り当てられている3種類の文章から適当に選んで、そのデータをPCに送ることにします。

左側スイッチ中央スイッチ右側スイッチ
「起きたら」
「トイレが」
「飼い犬が」
「頭痛がひどいので」
「水漏れで修理するため」
「動物病院に行くため」
「休暇を取得いたします」
「急遽お休みします」
「終わり次第出社します」

言い訳キーボードをPCに接続して、順番に「左側スイッチ」→「中央スイッチ」→「右側スイッチ」と押していくと、休む理由が自動的に生成されるわけです。

必要な知識の確認

ここまでの説明で、言い訳キーボードを製作するための要素技術は一通り揃ったはずです。

ちょっとしつこくなり申し訳ございませんが、言い訳キーボードの製作に必要な知識を整理しておきたいと思います。

キーボードの処理

Ardunio Microをキーボードとして振る舞うには「キーボードの接続処理」「文字データをPCに送る」という動作が必要です。

Keyboardライブラリを使えば、簡単に実現できましたよね。

以下の命令を使用すれば実現できます。

#include <Keyboard.h>  // キーボードライブラリのヘッダファイルインクルード

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

Keyboard.print("ABC");  // PCに文字データ「ABC」を送る

スイッチの処理

スイッチの処理は、Switchライブラリを使うと簡単になりました。

言い訳キーボードでは、Switchライブラリを使用して、次のようなスケッチでスイッチが押されたかどうかの検知を行います。

#include <avdweb_Switch.h>  // スイッチライブラリのヘッダファイルインクルード

Switch hidariSwitch(A5);  // A5端子に接続されているスイッチのインスタンス生成

hidariSwitch.poll();  // スイッチ状態の調査を指示

if( hidariSwitch.pushed() ) {  // スイッチが押されているかの判定
  // スイッチが押されていた時の処理
}

乱数

スイッチが押されたら、3種類の文字列の中から1つ適当に選ぶ必要があります。

何か適当に選ぶには乱数が必要です。

3個から選ぶので以下の命令で0〜2の乱数を生成すればOKです。

ただし、Arduino Microが動作を開始するたびに違う乱数を発生させたいので、乱数発生の前に初期化をします。

randomSeed( analogRead(A1) );  // 乱数の初期化

uint8_t number = random(3);  // 0〜2の乱数を変数numberに代入

生成した乱数に応じて処理を変える

乱数を生成したあと、数字に応じて文字データをPCに送る必要があります。

生成した数字に応じて処理を変える場合、switchが適していますので、次のように処理を切り替えることにします。

switch( random(3) ){
  case 0:
    // 処理A
    break;

  case 1:
    // 処理B
    break;

  case 2:
    // 処理C
    break;
}

なお、ifを使用して次のように書くこともできますが、乱数を発生するたびにその数値によらず、毎回ifで3回条件判断をすることになってしまいます。

uint8_t number = random(3);  // 0〜2の乱数を変数numberに代入

// numberが0の時の処理
if( number == 0 ) {
	// 処理A
}

// numberが1の時の処理
if( number == 1 ) {
	// 処理B
}

// numberが2の時の処理
if( number == 2 ) {
	// 処理C
}

場合分け処理の場合はswitchの方が適していますね。


必要な知識は以上ですが、日本語入力に関して補足がありますので次に説明します。

日本語入力

今まで、Keyboardライブラリを使用して「A」などの英数字をPCに送信していました。

今回製作する言い訳キーボードでは日本語を入力になりますので、日本語入力の文字データについて確認しておきましょう。

日本語入力モードが「ローマ字入力」「かな入力」で異なりますので、それぞれ説明します。

ローマ字入力

PCを日本語ローマ字入力モードにしているとき、例えば「起きたら」と入力する場合、次のようにキーを押しますよね。

okitara[スペースキー][リターンキー]

「okitara」と入力すると「おきたら」とひらがなで未確定の状態で入力され、そのあとスペースキーを押すと「起きたら」に変換され、リターンキーを押すことにより確定します。


Keyboardライブラリを利用して「起きたら」と日本語入力するには、上のようなキー入力を再現します

具体的には以下のようにスケッチに書きます。(スペースキーとリターンキーは日本語で書いたままです)

Keyboard.print( "okitara[スペースキー][リターンキー]" );

このスケッチで、[スペースキー]の部分は半角スペースでOKです。

問題は[リターンキー]の部分ですが、リターンキーの文字ってないですよね。

コンピュータの世界ではリターンキーやタブキー、バックスペースキーなどの文字で表せないキーは特殊な書き方をします。

例えばリターンキーであれば、次のように\の後にキーに対応した英文字を書きます。

\n

注意点としては、\は「バックスラッシュ」と呼ばれるもので、よく出てくる/(スラッシュ)と向きが逆になります。

\の後の英文字nはリターンキーを意味します。

他にも、例えば\tであればタブキー、\bであればバックスペースキーを意味します。

ところで\の入力ですが、OSやキーボードの種類によって異なります。

Windowsの場合は、英数字モードにして「¥」キーを押すと入力できます。キーボードによっては「ろ」のキーに割り当てられている場合もあります。

macOSの場合は、optionキー +「¥」キーで入力できます。

ちょっとややこしいので、わからない場合はこの記事からコピペして利用してみてください。


以上をまとめると、「起きたら」と日本語入力する場合、スケッチは次のようになります。

Keyboard.print("okitara \n");

かな入力

日本語をかな入力している場合は、押しているキーの英文字をデータとして送ります。

って、ちょっと分かりづらいですよね。

「起きたら」と入力する場合、日本語キーボードでは「お」「き」「た」「ら」のキーを順番に押します。

例えば、「お」のキーは英数字では「6」ですよね。

「お」「き」「た」「ら」のキーは、英数字の場合「6」「g」「q」「o」と押していることになります。


まとめると、日本語かな入力モードにしている場合、次のようにデータを送ると、「起きたら」と入力できることになります。

Keyboard.print("6gqo \n");

最後に補足ですが、macOSでライブ変換にしている場合、変換するためにスペースバーを押す必要はありませんので、スケッチは次のようになります。(文字データからスペースを削除)

Keyboard.print("okitara\n");  // ローマ字入力モード

Keyboard.print("6gqo\n");  // かな入力モード

言い訳キーボードのスケッチ

以上で必要な知識が一通り確認できましたので、言い訳キーボードのスケッチを作成してみます。

スケッチは次にのように作成してみました。日本語入力モードはローマ字入力にしています。

/*
 * 動作確認版言い訳キーボード
 *  「ローマ字入力モード」のデータにしています
 */

// キーボードライブラリとスイッチライブラリ
#include <Keyboard.h>
#include <avdweb_Switch.h>

// スイッチのピン番号の定義
#define SWITCH_HIDARI A5
#define SWITCH_CHUO   A4
#define SWITCH_MIGI   A3

// スイッチクラスのインスタンスを生成
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);

  // 乱数の初期化
  randomSeed(analogRead(A1));
}


void loop() {

  // 左側スイッチ状態の調査
  hidariSwitch.poll();
  
  // 左側スイッチが押されたら、主部を適当に選んでPCに送信
  if( hidariSwitch.pushed() ){
    // 0〜2の乱数を生成して、数字に応じて文字列をPCに送る
    switch(random(3)){
      case 0:
        Keyboard.print("okitara \n");
        break;
      case 1:
        Keyboard.print("toirega \n");
        break;
      case 2:
        Keyboard.print("kaiinuga \n");
        break;
    }
  }


  // 中央スイッチ状態の調査
  chuoSwitch.poll();
  
  // 左側スイッチが押されたら、理由を適当に選んでPCに送信
  if( chuoSwitch.pushed() ){
    // 0〜2の乱数を生成して、数字に応じて文字列をPCに送る
    switch(random(3)){
      case 0:
        Keyboard.print("zutuugahidoinode \n");
        break;
      case 1:
        Keyboard.print("mizumoredeshuurisurutame \n");
        break;
      case 2:
        Keyboard.print("doubutubyouinnniikutame \n");
        break;
    }
  }

  // スイッチライブラリに右側スイッチ状態の調査を指示
  migiSwitch.poll();
  
  // 左側スイッチが押されたら、文末を適当に選んでPCに送信
  if( migiSwitch.pushed() ){
    // 0〜2の乱数を生成して、数字に応じて文字列をPCに送る
    switch(random(3)){
      case 0:
        Keyboard.print("kyuukawoshutokuitashimasu \n");
        break;
      case 1:
        Keyboard.print("kyuukyooyasumishimasu \n");
        break;
      case 2:
        Keyboard.print("owarishidaishusshashimasu \n");
        break;
    }
  }

}

動作確認版スケッチの問題点

今回のスケッチは、動作はしますが課題があります。

というのは、文字データを変更したい場合、それぞれ文章はスイッチの中に埋もれていますので、スケッチの中から修正するところを探す必要があります。

このように複数の文字データを扱いたい場合、もう少し見通しが良くなる方法がありますので、次回以降の記事ではスケッチを見やすくしていきます。

更新履歴

日付内容
2021.11.9新規投稿
2025.2.18スケッチの端子名変更
説明内容簡略化
通知の設定
通知タイミング
guest
0 コメント
新しい準
古い順 一番投票が多い
本文中にフィードバック
全てのコメントを見る
目次