M5StickCでiPhoneのスクリーンキャプチャボタンを作る

概要

M5StickC(ESP32)でBluetooth Keyboardを作ってiPhoneのスクリーンキャプチャがかんたんに作れるボタンを作りました。

きっかけ

おっ、これってESP32だったらかんたんに作れるよねってことで作ってみました!

ベース

過去にBluetooth Keyboardは作ったことがあったのでかんたんですね。。。と思っていました。。。

なんとなく知っていたのですが、最新版ではこのとき使っていたESP32-BLE-KeyboardライブラリがiOSで使えないということを、、、

現状ESP32のライブラリが1.0.6に更新されてちょっとBluetooth周りが不安定になっているようです。ただし、次のバージョンアップで大幅にまた変わる予定なので今回は使うのを断念。もうちょっと経てば安定して動くバージョンが公開されるかもしれません。

今回はもう少し軽いBluetoothスタックであるNimBLEを使ってみたいと思います。

上記のライブラリを使うことで、標準Bluetoothスタックより、軽量なNimBLEスタックを利用することができます。NimBLEスタックは軽量なのですがBluetooth Classicなどの古いバージョンが利用できません。Bluetooth Low Energy(BLE)と呼ばれるものしか使えません。

たとえば上記はBluetooth3.0なのでBluetooth Classicでないと接続できません。最近のデバイスは4以降のはずですのでBLEでもあまり問題はないはずです。

NimBLEスタック自体は軽量なのですが、ESP32の場合標準Bluetoothスタックライブラリの実装が未完成なところがあるので動作が不安定です。Bluetooth ClassicとBLEの両対応なので複雑化しているところもあります。一方NimBLEスタックライブラリは最近作られているものなので比較的シンプルで安定しています。

NimBLE-Arduinoライブラリはライブラリマネージャからインストールできるので、かんたんに利用開始が可能です。

前回はBLEキーボードライブラリに上記を使いました。こちらはESP32の標準Bluetoothスタックライブラリを利用しているので利用することができません。

今回は、ESP32-BLE-KeyboardライブラリをNimBLEスタック対応をしたESP32-NimBLE-Keyboardライブラリを使ってみたいと思います。あらかじめNimBLE-Arduinoを入れていれば、ESP32-BLE-Keyboardライブラリとほぼ同じように利用できます。

コード

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

BleKeyboard bleKeyboard("M5StickC BLE ScreenShot");

// Battery update time
unsigned long nextVbatCheck = 0;

// get Battery Lebel
int getVlevel() {
  float vbat = M5.Axp.GetBatVoltage();
  int vlevel = ( vbat - 3.2 ) / 0.8 * 100;
  if ( vlevel < 0 ) {
    vlevel = 0;
  }
  if ( 100 < vlevel ) {
    vlevel = 100;
  }

  return vlevel;
}

void setup() {
  M5.begin();
  M5.Axp.ScreenBreath(9);
  setCpuFrequencyMhz(80);
  M5.Lcd.setRotation(3);
  M5.Lcd.fillScreen(BLACK);
  M5.Lcd.setTextSize(2);
  M5.Lcd.setCursor(0, 16);
  M5.Lcd.println("NimBLE");
  M5.Lcd.println("ScreenShot");
  M5.Lcd.println();
  M5.Lcd.println(" Press BtnA");

  bleKeyboard.setBatteryLevel(getVlevel());
  bleKeyboard.begin();
}

void loop() {
  // Button Update
  M5.update();

  if (bleKeyboard.isConnected()) {
    if ( M5.BtnA.wasPressed() ) {
      // ScreenShot(COMMAND + SHIFT + 3)
      bleKeyboard.press(KEY_LEFT_GUI);
      bleKeyboard.press(KEY_LEFT_SHIFT);
      bleKeyboard.press('3');
      delay(100);
      bleKeyboard.releaseAll();
    }
  }

  // Battery Lebel Update
  if (nextVbatCheck < millis()) {
    M5.Lcd.setCursor(112, 0);
    M5.Lcd.printf("%3d%%", getVlevel());

    nextVbatCheck = millis() + 60000;
  }

  // Wait
  delay(1);
}

上記でうごきます。コード自体はキーボードライブラリの違いは一切ありません。どちらのライブラリを使っても全く同じコードになります。逆に同じ名前のファイル名なので共存することができないと思います。

      // ScreenShot(COMMAND + SHIFT + 3)
      bleKeyboard.press(KEY_LEFT_GUI);
      bleKeyboard.press(KEY_LEFT_SHIFT);
      bleKeyboard.press('3');
      delay(100);
      bleKeyboard.releaseAll();

キモは上記の部分です。COMMAND + SHIFT + 3でスクリーンキャプチャなので、同時押しをしてあげるだけになります。

これでiPhoneやiPadにBluetoothでペアリングして、M5StickCのボタンを押すと画面キャプチャがどんどん取得できます。

まとめ

誰得なデバイスですが、アプリ開発などでがんがん画面キャプチャをしたい場合には非常に便利だと思います。使うことあるかは微妙なところですがたまには勢いで作ってみるのもいいのかな?

コメント

  1. Funekogi より:

    初めまして。T-vKさんのESP32-BLE-Keyboardライブラリを使って、ESP32をベースにBluetoothキーボードを作ったのですが、Androidからは見えるのにiOSからは見えないので悩んでいました。
    Lang-shipさんの記事のおかげで、解決できました。
    (iPhoneの曲送り、ボリューム変更、再生/ストップを操作できるリモコンを作りました。ドライブ時に使いたいと思います。)どうもありがとうございます!

  2. street22 より:

    windowsにはつながるのですが、なぜか、ipad、iphone(ios14.71)のbluetoothにつながりません。何か理由があるのか..もし情報があればよろしくお願いします。

    • たなかまさゆき より:

      手元で確認したところ、iPhoneのiOS14.7.1で繋がりました
      ライブラリマネージャからNimBLE-Arduinoを追加
      https://github.com/wakwak-koba/ESP32-NimBLE-Keyboard からZip形式でダウンロードして、ライブラリに追加

      で動きました
      ボードマネージャーはESP32の標準の1.0.6でもM5Stackの1.0.9でも動きました
      M5Stackの1.0.8だと内部のESP32バージョンが違うのでそれが原因の可能性もあります

  3. street22 より:

    返信ありがとうございました。M5StickCが壊れていたみたいで、新しいものに変えたらiOSでもちゃんとつながりました。申し訳ありません、お手数をおかけしました。