某ゲームでアイテムを交換する作業が面倒になってきたので キーボード操作を自動化したいと思った。

まず思いついたのは、手元にあった サンワサプライ製のプログラマブルテンキー NT-19UH2BK。 久しぶりに引っぱりだして確認したところ、これは Ctrl + C のような同時押しには対応しているが、 ウェイトをはさみながら複数のキーを順次入力する用途には対応していなかった。

次に AZ-Macro というマクロ機能のある自作 Bluetooth キーボードキットがあることを思い出した。 これは ESP32 で作られていて、 ファームウェアのソースコードも公開 されている。 手持ちの M5StickC なら同じ ESP32 が内蔵されており Bluetooth にも対応しているため、目的を実現できるのではないか?

ということで、M5StickC を Bluetooth キーボードとして PC へ接続し操作を自動化する。

Arduino IDE へ ESP32-BLE-Keyboard をインストール

まずは M5StickC を Bluetooth キーボードとして使うためのライブラリを Arduino IDE へインストールする。

  1. Releases · T-vK/ESP32-BLE-Keyboard から ESP32-BLE-Keyboard.zip をダウンロード
  2. Arduino IDE のメニューで [スケッチ] - [ライブラリをインクルード] - [.ZIP形式のライブラリをインストール…] をクリック
  3. さきほどダウンロードした ESP32-BLE-Keyboard.zip を選択

ESP32-BLE-Keyboard の使い方

公式のサンプル を見れば大まかな使い方はわかると思うが、メソッドの説明がないので補足しておく。

BleKeyboard クラスの以下のメソッドでキーを操作できる。

  • print: 文字列を入力
  • write: キーを押してすぐに離す
  • press: キーを押す (release するまで押したままにする)
  • release: キーを離す
  • releaseAll: すべてのキーを離す

キーの指定は、英数記号の場合、文字をそのまま渡す。 大文字を渡すと自動でシフトキーが補完され大文字での入力になる。

bleKeyboard.write('a');

ファンクションキー、修飾キーなどの場合は BleKeyboard.h で定義されている定数を渡す。

スケッチの作成

M5StickC のボタンA (正面の「M5」ボタン) を押すと 500ms 間隔で順番に B, L, E, Enterキーを押すサンプルスケッチを作成した。 今回は同時押しが不要だったため keystroke に書かれたキーを順に write で出力するだけとなっている。

#include <vector>
#include <M5StickC.h>
#include <BleKeyboard.h>

// -----------------------------------------------------------------------------
// 定数
// -----------------------------------------------------------------------------
// 電源ボタンが1秒未満押された
const uint8_t AXP_WAS_PRESSED = 2;
// キーと待ち時間の構造体
struct Key {
  uint8_t key;
  uint32_t delay;
};
// 送信するキーストローク
const std::vector<Key> keystroke = {
    { 'B'       , 500 },
    { 'L'       , 500 },
    { 'E'       , 500 },
    { KEY_RETURN, 0 }
};

// -----------------------------------------------------------------------------
// 変数
// -----------------------------------------------------------------------------
// ESP32-BLE-Keyboard
BleKeyboard bleKeyboard;

// -----------------------------------------------------------------------------
// 関数
// -----------------------------------------------------------------------------
// 画面を消去する
void clearScreen() {
    M5.Lcd.fillScreen(TFT_BLACK);
    M5.Lcd.setCursor(0, 0);
}

// キーストロークを送信する
void sendKeystroke() {
    clearScreen();
    M5.Lcd.println("Sending...");

    for (const auto& n : keystroke) {
        bleKeyboard.write(n.key);
        delay(n.delay);
    }

    M5.Lcd.println("Complete!");
}

void setup() {
    M5.begin();

    // 画面の表示設定
    M5.Lcd.setRotation(1);
    M5.Lcd.setTextFont(2);
    clearScreen();
    M5.Lcd.println("ESP32-BLE-Keyboard");

    // Bluetooth接続
    bleKeyboard.begin();
}

void loop() {
    M5.update();

    // 電源ボタンが押されたらリセット
    if (M5.Axp.GetBtnPress() == AXP_WAS_PRESSED) {
        esp_restart();
    }

    if (bleKeyboard.isConnected()) {
        // Bluetooth接続済みの場合
        // ボタンAが押されたらキーを送信
        if (M5.BtnA.wasPressed()) {
            sendKeystroke();
        }

        delay(10);
    }
    else {
        // Bluetooth未接続の場合は5秒待つ
        M5.Lcd.println("Waiting 5 seconds...");
        delay(5000);
    }
}

動作確認

以下の手順で動作を確認できる。

  1. M5StickC にスケッチを書き込む
  2. M5StickC の画面に “Waiting 5 seconds…” と表示されていることを確認
  3. PC で Bluetooth デバイスを検索し “ESP32 BLE Keyboard” へ接続
  4. メモ帳などのアプリを開く
  5. M5StickC のボタンA (正面の「M5」ボタン) を押す

これで複雑なキーボードマクロでも思い通りに実行できるようになった。 キーボードでできることなら何でもボタン一発で実行できるため、 思っていた以上に利便性が高い。

参考サイト