はじめに
最近、ハマっている Seeed Studio XIAO ESP32C6でBluetooth Low Energy(BLE)のテストを兼ねて、無線1ボタンキーボードを作ってみた。1ボタン動作は色々用途があると思いますが、今回は、Windowsのログインを自動化するボタンにしてみた。

以前の「Seeed Studio XIAO ESP32C6」の記事
ハード
- Windows10
- XIAO ESP32C6
- ブレッドボード
- タクトスイッチx1
- ジャンプワイヤー
- リポバッテリー3.7v 210mAh
XIAO ESP32C6
使用したXIAO ESP32C6。
配線
HIGH検知のボタン。10KΩでプルダウンさせておく。
DeepSleepからの復帰に使うので XIAO ESP32C6 の場合は、GPIO0,1,2のいずれかにする必要がある。
ESP32C6 GPIO1 -+- BUTTON --- 3.3v
|
+-- 10KΩ --- GND
Li-Poバッテリ駆動
リチウムポリマー電池を使ってワイヤレス。
背面のBAT±にLi-Poバッテリを繋ぐだけ。※要はんだ付け
ソフト
- ArduinoIDE 2.3.6(Arduino core3.2.0)
- ESP32-BLE-Keyboard 0.3.2
ESP32-BLE-Keyboard
ESP32には、BLE が使えるので無線キーボード化できる。Arduino用ライブラリは色々あるが今回は下記を使用。
XIAO ESP32C6ではコンパイルエラーが出るのでbegin関数の中を以下のように修正した。
void BleKeyboard::begin(void)
{
#if defined(ARDUINO_XIAO_ESP32C6)
BLEDevice::init(deviceName.c_str());
#else
BLEDevice::init(deviceName);
#endif
:
:
#if defined(ARDUINO_XIAO_ESP32C6)
hid->manufacturer()->setValue(deviceManufacturer.c_str());
#else
hid->manufacturer()->setValue(deviceManufacturer);
#endif
:
:
#if defined(ARDUINO_XIAO_ESP32C6)
pSecurity->setAuthenticationMode(ESP_LE_AUTH_BOND);
#else
pSecurity->setAuthenticationMode(ESP_LE_AUTH_REQ_SC_MITM_BOND);
#endif
仕様
ログインパスワードをソース埋め込みにすればもっと簡単なロジックになる。今回はNVS書き込みにしたので少々手間。プロコンで良ければごっそり外してくださいな。
手順 | 説明(初回のみ) | |
---|---|---|
0 | リポバッテリーは外しておく | |
1 | PC ⇔ ESP32C6 USB接続後 コンパイル&アップロード | |
2 | ペアリングモード(内臓LED点滅) | |
3 | WindowsのBluetoothデバイスの追加で「ESP32BLEButton」を追加 (30秒以内→ボタン押下で2から) |
|
4 | BLE接続完了(内臓LED点灯) | |
5 | シリアルモニタでログインパスワード入力 「Enter new password:」 |
|
6 | パスワードがNVS(不揮発性メモリ)に保存される | |
7 | ESP32C6をPCから取り外す | |
8 | リポバッテリー接続 | |
9 | BLE接続開始(内臓LED点滅) | |
10 | BLE接続完了(内臓LED点灯) | |
11 | 10秒後 BLE切断(内臓LED消灯) | |
12 | DeepSleep |
手順 | 説明(2回目以降ここから) | |
---|---|---|
0 | DeepSleep(内臓LED消灯) | |
1 | 1回ボタン押下(復帰) | |
2 | BLE接続開始(内臓LED点滅) | |
3 | BLE接続完了(内臓LED点灯) | |
4 | 2回ボタン押下(ダブルクリック) | |
5 | Windowsへログインパスワード送信 | |
6 | 10秒後 BLE切断(内臓LED消灯) | |
7 | DeepSleep |
手順 | 説明(パスワード変更) | |
---|---|---|
0 | リポバッテリーは外す | |
1 | PC ⇔ ESP32C6 USB接続 | |
2 | ArduinoIDE起動 シリアルモニタ COM接続確認 | |
3 | ボタン長押し(3秒) | |
4 | NVS(不揮発性メモリ)クリア | |
5 | 初回手順5へ |
ソース
githubに置きました。
https://github.com/nori-dev-akg/BLE-Button-login
以下、ちょっと説明。
BLE接続
以下の bleKeyboard.begin()
がBLE接続開始。そのあと接続確認ループ。タイムアウトCONNECT_TIMEOUT
するまで内臓LEDを点滅させる処理。タイムアウトしたらDeepSleepになる。
bleKeyboard.begin(); // Start BLE keyboard
Serial.print("BLE Keyboard started. Waiting for connection...");
unsigned long startTime = millis();
while (!bleKeyboard.isConnected()) {
if (millis() - startTime > CONNECT_TIMEOUT * 1000) {
Serial.println("Connection timeout. Please try again.");
gotoSleep();
return;
}
digitalWrite(LED_PIN, LOW);
delay(100);
digitalWrite(LED_PIN, HIGH);
delay(100);
Serial.print(".");
}
Serial.println("connected!");
ログインパスワード送信
Windowsロック画面で、最初にコントロールキーKEY_LEFT_CTRL
を送信して、パスワード入力フォームを表示させている。表示されるまでディレイWAIT_LOGIN
して、その後に pass
を送信して、KEY_RETURN
を送信。
Serial.println("Double Pressed");
// On double click, send Ctrl key
bleKeyboard.press(KEY_LEFT_CTRL);
delay(100);
bleKeyboard.releaseAll();
delay(WAIT_LOGIN); // Wait for login screen
bleKeyboard.write((const uint8_t*)pass, strlen(pass)); // Send password
bleKeyboard.write(KEY_RETURN);
DeepSleep
DeepSleepでは、esp_sleep_enable_ext1_wakeup()
関数を使う。指定したピンの状態を検知してWakeUpすることができるDeepleep。esp_sleep_enable_ext0_wakeup()
は ESP32C6には無い模様。さらに以下の BUTTON_PIN
のところで使えるピンは0,1,2だけ。
void gotoSleep() {
Serial.println("Going to sleep...");
bleKeyboard.end(); // End BLE connection
digitalWrite(LED_PIN, HIGH); // Turn off LED
delay(500);
esp_sleep_enable_ext1_wakeup(1ULL << BUTTON_PIN, ESP_EXT1_WAKEUP_ANY_HIGH); // Wakeup on HIGH
esp_deep_sleep_start(); // Start deep sleep
}
消費電流
BLE接続中が40mA越えです。内臓LEDは数mAだとして素XIAO-ESP32C6が20mAぐらいだったから結構BLEも喰うね。1日数回接続で殆どDeepSleep状態なので結構持つと思うけど。
BLE接続中 | DeepSleep |
---|---|
![]() |
![]() |
40.3mA | 23.8μA |
おわりに
ハマりポイントは ESP32-BLE-Keyboard ライブラリの修正が必要なところぐらいでしょう。
Windows起動直後の一発目のBLEの接続に10秒ほど掛かるのが気持ち悪いぐらいですが、ロック状態からのログインの時は直ぐにつながる。
3Dプリンターがあればケースなんか用意できるんだけど、そんなもん置く場所ない。広い家に住みたいよ。