This library allows you to make the ESP32C3 act as a Bluetooth Keyboard and control what it does.
You might also be interested in:
- Send key strokes
- Send text
- Press/release individual keys
- Media keys are supported
- Read Numlock/Capslock/Scrolllock state
- Set battery level (basically works, but doesn't show up in Android's status bar)
- Compatible with Android
- Compatible with Windows
- Compatible with Linux
- Compatible with MacOS X (not stable, some people have issues, doesn't work with old devices)
- Compatible with iOS (not stable, some people have issues, doesn't work with old devices)
- For Seeed Studio XIAO ESP32C3
- セキュリティの関係でNimBLE-ArduinoがヘッダーでOnになっています
- (Make sure you can use the ESP32 with the Arduino IDE. Instructions can be found here.)
- Download the latest release of this library from this page.
- In the Arduino IDE go to "Sketch" -> "Include Library" -> "Add .ZIP Library..." and select the file you just downloaded.
- You can now go to "File" -> "Examples" -> "ESP32C3 BLE Keyboard" and select any of the examples to get started.
/**
* This example turns the ESP32 into a Bluetooth LE keyboard that presses a media key
* https://github.com/T-vK/ESP32-BLE-Keyboardを改変しESP32C3でのメディアコントロールに特化したやつ
* NimBLE-Arduinoをライブラリマネージャからダウンロードしてください
*/
#include <BleKeyboard.h>
BleKeyboard bleKeyboard("ESP32 Media Keybord","Mendako Lab",50);
void setup() {
Serial.begin(115200);
Serial.println("Starting BLE work!");
bleKeyboard.begin();
// 使えるメディア制御コマンド
// keyIDの実装参考
// https://www.usb.org/document-library/hid-usage-tables-14
/*
KEY_MEDIA_NEXT_TRACK
KEY_MEDIA_PREVIOUS_TRACK
KEY_MEDIA_STOP
KEY_MEDIA_PLAY
KEY_MEDIA_PAUSE
KEY_MEDIA_MUTE
KEY_MEDIA_VOLUME_UP
KEY_MEDIA_VOLUME_DOWN
*/
// 入力ピンの設定
// D6,8,9はめんどくさいので使わない
// 詳細は → https://lab.seeed.co.jp/entry/2023/04/03/120000
pinMode(D0,INPUT_PULLUP); //GPIO0(BOOT)をプルアップ付き入力設定
pinMode(D1,INPUT_PULLUP); //GPIO0(BOOT)をプルアップ付き入力設定
pinMode(D2,INPUT_PULLUP); //GPIO0(BOOT)をプルアップ付き入力設定
pinMode(D3,INPUT_PULLUP); //GPIO0(BOOT)をプルアップ付き入力設定
pinMode(D4,INPUT_PULLUP); //GPIO0(BOOT)をプルアップ付き入力設定
pinMode(D5,INPUT_PULLUP); //GPIO0(BOOT)をプルアップ付き入力設定
pinMode(D7,INPUT_PULLUP); //GPIO0(BOOT)をプルアップ付き入力設定
pinMode(D10,INPUT_PULLUP); //GPIO0(BOOT)をプルアップ付き入力設定
}
void loop() {
// 長押し判定用のフラグ
static bool flag_KEY_MEDIA_NEXT_TRACK = false;
static bool flag_KEY_MEDIA_PREVIOUS_TRACK = false;
if(bleKeyboard.isConnected()) {
if(digitalRead(D0) == LOW && flag_KEY_MEDIA_NEXT_TRACK == false){
Serial.println("Sending Scan Next Track media key...");
flag_KEY_MEDIA_NEXT_TRACK = true;
bleKeyboard.press(KEY_MEDIA_NEXT_TRACK);
}
else if(digitalRead(D0) == HIGH && flag_KEY_MEDIA_NEXT_TRACK == true){
flag_KEY_MEDIA_NEXT_TRACK = false;
bleKeyboard.release(KEY_MEDIA_NEXT_TRACK);
}
if(digitalRead(D1) == LOW && flag_KEY_MEDIA_PREVIOUS_TRACK == false){
Serial.println("Sending Scan Previous Track media key...");
flag_KEY_MEDIA_PREVIOUS_TRACK = true;
bleKeyboard.press(KEY_MEDIA_PREVIOUS_TRACK);
}
else if(digitalRead(D1) == HIGH && flag_KEY_MEDIA_PREVIOUS_TRACK == true){
flag_KEY_MEDIA_PREVIOUS_TRACK = false;
bleKeyboard.release(KEY_MEDIA_PREVIOUS_TRACK);
}
if(digitalRead(D2) == LOW){
Serial.println("Sending Stop media key...");
bleKeyboard.write(KEY_MEDIA_STOP);
delay(200);
}
if(digitalRead(D3) == LOW){
Serial.println("Sending Play media key...");
bleKeyboard.write(KEY_MEDIA_PLAY);
delay(200);
}
if(digitalRead(D4) == LOW){
Serial.println("Sending Pause media key...");
bleKeyboard.write(KEY_MEDIA_PAUSE);
delay(200);
}
if(digitalRead(D5) == LOW){
Serial.println("Sending Mute media key...");
bleKeyboard.write(KEY_MEDIA_MUTE);
delay(200);
}
if(digitalRead(D7) == LOW){
Serial.println("Sending Volume Increment media key...");
bleKeyboard.write(KEY_MEDIA_VOLUME_UP);
delay(50);
}
if(digitalRead(D10) == LOW){
Serial.println("Sending Volume Decrement media key...");
bleKeyboard.write(KEY_MEDIA_VOLUME_DOWN);
delay(50);
}
}
}
The BleKeyboard interface is almost identical to the Keyboard Interface, so you can use documentation right here: https://www.arduino.cc/reference/en/language/functions/usb/keyboard/
Just remember that you have to use bleKeyboard
instead of just Keyboard
and you need these two lines at the top of your script:
#include <BleKeyboard.h>
BleKeyboard bleKeyboard;
In addition to that you can send media keys (which is not possible with the USB keyboard library). Supported are the following:
- KEY_MEDIA_NEXT_TRACK
- KEY_MEDIA_PREVIOUS_TRACK
- KEY_MEDIA_STOP
- KEY_MEDIA_PLAY_PAUSE
- KEY_MEDIA_MUTE
- KEY_MEDIA_VOLUME_UP
- KEY_MEDIA_VOLUME_DOWN
- KEY_MEDIA_WWW_HOME
- KEY_MEDIA_LOCAL_MACHINE_BROWSER // Opens "My Computer" on Windows
- KEY_MEDIA_CALCULATOR
- KEY_MEDIA_WWW_BOOKMARKS
- KEY_MEDIA_WWW_SEARCH
- KEY_MEDIA_WWW_STOP
- KEY_MEDIA_WWW_BACK
- KEY_MEDIA_CONSUMER_CONTROL_CONFIGURATION // Media Selection
- KEY_MEDIA_EMAIL_READER
There is also Bluetooth specific information that you can set (optional):
Instead of BleKeyboard bleKeyboard;
you can do BleKeyboard bleKeyboard("Bluetooth Device Name", "Bluetooth Device Manufacturer", 100);
. (Max lenght is 15 characters, anything beyond that will be truncated.)
The third parameter is the initial battery level of your device. To adjust the battery level later on you can simply call e.g. bleKeyboard.setBatteryLevel(50)
(set battery level to 50%).
By default the battery level will be set to 100%, the device name will be ESP32 Bluetooth Keyboard
and the manufacturer will be Espressif
.
There is also a setDelay
method to set a delay between each key event. E.g. bleKeyboard.setDelay(10)
(10 milliseconds). The default is 8
.
This feature is meant to compensate for some applications and devices that can't handle fast input and will skip letters if too many keys are sent in a small time frame.
The NimBLE mode enables a significant saving of RAM and FLASH memory.
Standard
RAM: [= ] 9.3% (used 30548 bytes from 327680 bytes)
Flash: [======== ] 75.8% (used 994120 bytes from 1310720 bytes)
NimBLE mode
RAM: [= ] 8.3% (used 27180 bytes from 327680 bytes)
Flash: [==== ] 44.2% (used 579158 bytes from 1310720 bytes)
Standard | NimBLE mode | difference | |
---|---|---|---|
ESP.getHeapSize() |
296.804 | 321.252 | + 24.448 |
ESP.getFreeHeap() |
143.572 | 260.764 | + 117.192 |
ESP.getSketchSize() |
994.224 | 579.264 | - 414.960 |
Uncomment the first line in BleKeyboard.h
#define USE_NIMBLE
Change your platformio.ini
to the following settings
lib_deps =
NimBLE-Arduino
build_flags =
-D USE_NIMBLE
Credits to chegewara and the authors of the USB keyboard library as this project is heavily based on their work!
Also, credits to duke2421 who helped a lot with testing, debugging and fixing the device descriptor!
And credits to sivar2311 for adding NimBLE support, greatly reducing the memory footprint, fixing advertising issues and for adding the setDelay
method.