Giter VIP home page Giter VIP logo

esp32-ble-keyboard's Introduction

ESP32 BLE Keyboard library

This library allows you to make the ESP32 act as a Bluetooth Keyboard and control what it does.
You might also be interested in:

Features

  • 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)

Installation

Example

/**
 * This example turns the ESP32 into a Bluetooth LE keyboard that writes the words, presses Enter, presses a media key and then Ctrl+Alt+Delete
 */
#include <BleKeyboard.h>

BleKeyboard bleKeyboard;

void setup() {
  Serial.begin(115200);
  Serial.println("Starting BLE work!");
  bleKeyboard.begin();
}

void loop() {
  if(bleKeyboard.isConnected()) {
    Serial.println("Sending 'Hello world'...");
    bleKeyboard.print("Hello world");

    delay(1000);

    Serial.println("Sending Enter key...");
    bleKeyboard.write(KEY_RETURN);

    delay(1000);

    Serial.println("Sending Play/Pause media key...");
    bleKeyboard.write(KEY_MEDIA_PLAY_PAUSE);

    delay(1000);
    
   //
   // Below is an example of pressing multiple keyboard modifiers 
   // which by default is commented out. 
   // 
   /* Serial.println("Sending Ctrl+Alt+Delete...");
    bleKeyboard.press(KEY_LEFT_CTRL);
    bleKeyboard.press(KEY_LEFT_ALT);
    bleKeyboard.press(KEY_DELETE);
    delay(100);
    bleKeyboard.releaseAll();
    */

  }
  Serial.println("Waiting 5 seconds...");
  delay(5000);
}

API docs

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.

NimBLE-Mode

The NimBLE mode enables a significant saving of RAM and FLASH memory.

Comparison (SendKeyStrokes.ino at compile-time)

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)

Comparison (SendKeyStrokes.ino at run-time)

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

How to activate NimBLE mode?

ArduinoIDE:

Uncomment the first line in BleKeyboard.h

#define USE_NIMBLE

PlatformIO:

Change your platformio.ini to the following settings

lib_deps = 
  NimBLE-Arduino

build_flags = 
  -D USE_NIMBLE

Credits

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.

esp32-ble-keyboard's People

Contributors

aovestdipaperino avatar dustinwatts avatar dvv avatar grafmar avatar millst avatar muddyfeet avatar mwinters-stuff avatar scaredycat avatar sivar2311 avatar t-vk avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

esp32-ble-keyboard's Issues

MacOS (10.15.1 (19B88)) "Disconnect" doesn't work from Bluetooth in menu bar

Hi,
Thank you so much for the library and all the value provided,
I'm testing on Mac, and observed the interesting issue,
Please help to resolve:

Bluetooth in menu bar -> Devices -> "ESP32 device name" -> Disconnect (only this option is available)
Clicking on Disconnect here - my device reconnects automatically immediately

2buttons_led | Arduino 1 8 13 2020-08-08 18-02-28
Additional info:
When you go to Apple menu/System Preferences/Bluetooth
only Remove option (not Disconnect) available for the connected device
Bluetooth 2020-08-08 18-01-21

F1/F2 Brightness for iOS

I am trying to use an ESP32 to control a wall mounted iPad screen brightness (plan on pairing this library with MQTT).

On a normal Apple Bluetooth keyboard you can used F1 and F2 to adjust the brightness.
I have looked over Keyboard Modifier

I tried several combination without success
bleKeyboard.press(KEY_F1)
bleKeyboard.write(KEY_F1)
bleKeyboard.press(194)
bleKeyboard.write(194)
bleKeyboard.write(0xC2)

When testing with the "SendKeyStrokes" sketch I am able to get all other tests to work.
KEY_MEDIA_VOLUME_UP and KEY_MEDIA_VOLUME_DOWN work fine as well.

I'm curious if I need to create a custom "KEY_MEDIA" for brightness since iOS does not seem to be responding to F1/F2 keys

Thank you for the assistance
Also - Thank you for the great library

First test and a little report

Hi @T-vK

Thanks, that was fast.
In general it is working. In your Hid device descriptor was a (2) instead of (1) at the report id 2.
REPORT_ID(1), 0x02, // REPORT_ID (2)
With that I get a driver error in Win10.

In the array keyReport.keys you wrote all in array 0 and for "a" the code is 0x04 not 0x61 ;)

        keyReport.keys[0] = 0x61; // "a" 
        keyReport.keys[0] = 0x00;
        keyReport.keys[0] = 0x00;
        keyReport.keys[0] = 0x00;
        keyReport.keys[0] = 0x00;
        keyReport.keys[0] = 0x00;

I changed that to

        keyReport.keys[0] = 0x04; // "a"
        keyReport.keys[1] = 0x00;
        keyReport.keys[2] = 0x00;
        keyReport.keys[3] = 0x00;
        keyReport.keys[4] = 0x00;
        keyReport.keys[5] = 0x00;

Now I am able to sent 4 keys through my rotary encoder knob ("a" with short press, "b" with long press, "c" with rotate CW and "d" with rotate CCW). but I am not able to control "play/pause" and so on. I tried it with "0xcd" but I think, these keys are not handled in the same way as normal key strokes.

KEY_MEDIA_VOLUME_UP (and other media keys) don't seem to work on my Android Device

First of all, thank you very much for your work on this project.
Also, I have to apologize, that my issue might not be too insightful - I am just starting with Bluetooth...

I was able to connect my ESP32 with my Android device. However, I tried several media keys (e.g. KEY_MEDIA_VOLUME_UP and KEY_MEDIA_PLAY_PAUSE however, they have not been recognized (or at least, the Android device showed no reaction).

What could be the reason for that?

media controls issue when disconnected-reconnected

Hi, I have used this library a lot in a macro bluetooth keyboard project, but I have an issue with using media controls. When I first connect my esp32 with a device (for example my smartphone) I pair it and it works (all bluetooth keyboard keys are being sent, including media keys). but when I disconnect my esp32 from the device, and I reconnect it, all the keyboard keys will work as expected, however media keys will no longer work. The only way I found to make media keys work again is to unpair my esp32 from my device by deleting it from the device list, then pair it, and it will work again.
I have had this issue with my full program but also with the example program of the library. I have spoke with other people using this library for similar projects, some had the same issue, others don't.
I wonder if it is an issue based on the disconnection between the esp32 and the device that is not proprely made, or if it's an issue with a buffer.
Anyway this library has still be very usefull for any other keyboard keys and it has helped me a lot for this project, Thanks.

Problem with connected statement

hi
so, first of all, I really enjoyed working with the library, it makes everything very clear end easy. but I have a problem with the connected statement. i thinks it sometimes returns true when it really is false.
im working with low power consumption (light sleep mode) and after i wake up the ESP32 with an external button i write an if condition so that if it is connected, it has to return the word "Conectado" . The problem is that sometimes it enters to the if conditional but does not print the word "conectado", so i assume it wrongfully enters into the if command even if its not connected. Could it be that working with low power consumption is interfering with the code?
while(!bleKeyboard.isConnected()){
Serial.print(".");
delay(100);
}
if (bleKeyboard.isConnected()) {
bleKeyboard.println("conectado"); // entre 200 y 300 m
delay(200);
Serial.println("entre al conectado");
}
and also i wanted to ask, which function can i use if i want to unable the bluetooth. Because i tried to use bleKeyboard.end() and it doesnt work. thank you very much.

here is the complete code

#include <BleKeyboard.h>
#include <WiFi.h>
#include <esp_wifi.h>
#include <esp_bt.h>
//Nombre del dispositivo que me va a aparecer en las configuraciones de bluetooth
BleKeyboard bleKeyboard("ESP-32 Keyboard");

struct Button {
const uint8_t PIN;
uint32_t numberKeyPresses; //unsigned int 32 bits
bool pressed; //two values, true or false.
};
const int ledpin=2;
boolean oldPinState = LOW;
Button button1 = {33, 0, false};

RTC_DATA_ATTR int bootCount = 0;

// define ISR function for PushButtton's Interrupt
void IRAM_ATTR isr() {
// if(bootCount>1){
if (oldPinState == LOW) {
button1.numberKeyPresses += 1;
button1.pressed = true;
digitalWrite(ledpin,HIGH);

  }
  oldPinState = HIGH;

// }
}

void print_wakeup_reason(){ // funcion para ver de que modo "despierto la placa"
esp_sleep_wakeup_cause_t wakeup_reason;

wakeup_reason = esp_sleep_get_wakeup_cause();

switch(wakeup_reason)
{
case ESP_SLEEP_WAKEUP_EXT0 : Serial.println("Wakeup caused by external signal using RTC_IO"); break;
case ESP_SLEEP_WAKEUP_EXT1 : Serial.println("Wakeup caused by external signal using RTC_CNTL"); break;
case ESP_SLEEP_WAKEUP_TIMER : Serial.println("Wakeup caused by timer"); break;
case ESP_SLEEP_WAKEUP_TOUCHPAD : Serial.println("Wakeup caused by touchpad"); break;
case ESP_SLEEP_WAKEUP_ULP : Serial.println("Wakeup caused by ULP program"); break;
default : Serial.printf("Wakeup was not caused by deep sleep: %d\n",wakeup_reason); break;
}
}

void setup(){
Serial.begin(115200);
Serial.println("Starting BLE work!");
// comienza a aparecer el teclado en los dispositivos
bleKeyboard.begin();

pinMode(ledpin,OUTPUT);
pinMode(button1.PIN, INPUT_PULLUP);
attachInterrupt(button1.PIN, isr, FALLING);
++bootCount;
//incremento la variable para saber cuantas veces "desperte" la placa
// ++bootCount;
// Serial.println("Boot number: " + String(bootCount));
// pinMode(33,INPUT_PULLDOWN);
// atiendo la interrupcion cuando presiono el boton
// attachInterrupt(digitalPinToInterrupt(33), isr, 1);

//Print the wakeup reason for ESP32
print_wakeup_reason();

// rtc_gpio_pulldown_en((gpio_num_t)GPIO_NUM_33);

// despierto la placa cuando el boton pasa de 0v a 3.3v
esp_sleep_enable_ext0_wakeup(GPIO_NUM_33,0);
// esp_sleep_enable_ext0_wakeup(button1.PIN,FALLING);

// esp_sleep_enable_ext0_wakeup((gpio_num_t)GPIO_NUM_33,RISING);

//Go to Light sleep now
Serial.println("Going to light sleep now");
delay(1000);
// WiFi.forceSleepBegin();
// WiFi.disconnect();
WiFi.mode(WIFI_OFF);
// btStop();
// esp_wifi_stop();
// esp_bt_controller_disable();
esp_light_sleep_start();
Serial.println("me desperte");
// chequeo que este en sleep mode
if (bleKeyboard.isConnected()) {
bleKeyboard.print("This will never be printed");
}
}

void loop(){

if (button1.pressed) {
Serial.printf("Button 1 has been pressed %u times\n", button1.numberKeyPresses);
digitalWrite(ledpin,LOW);
while(!bleKeyboard.isConnected()){
Serial.print(".");
delay(100);
}
if (bleKeyboard.isConnected()) {
bleKeyboard.println("conectado"); // entre 200 y 300 m
delay(200);
Serial.println("entre al conectado");
}
Serial.println("Going to Light sleep now after printing de leter");// ver bien el tema del delay y del serial
button1.pressed = false;
delay(500);
oldPinState = LOW;
esp_light_sleep_start();
Serial.println("me desperte");
delay(1000);
}
}

Media Keys on Android do not work after reconnect BLE

I send media key commands and it works fine on my Android device.
But if connection is lost (to far away) or ESP32 is restarted the BLE connection is reestablished but my Android device will not get the media key information anymore/or does not react to it. I can send text with print or characters with write and this works fine.
With mit IOS device everything works fine even after lot connection and reconnect.
If I do a new pairing between Android device and ESP it works again fine.
Tested now on two different Android devices.
Do you have any clue why media key commands do not work after reconnect?

Volume up doesn't seem to trigger camera shutter in Android 10 (pixel 3)

Hello,

Thank you for creating this lib. I'm trying to use esp32 as a Bluetooth camera shutter with my Pixel 3 running Android 10. I tried bleKeyboard.write(KEY_MEDIA_VOLUME_UP), it doesn't seem to work. Pressing physical volume up or down button on my phone while the stock camera app is active triggers the shutter. The same code worked perfectly with my old phone running Android 6. I'm able to pair ESP BLE Keybaord as a physical keyboard with the pixel 3 and the connection is stable.

What am I doing wrong? I'd appreciate any help.

Thanks

感谢大佬的无私

非常喜欢您做的这个库,非常好用,希望大佬继续开发,希望有指示灯!

Is it incompatible to use CSR Dongle in Win7 or Win10?

Thank you very much for this wonderful library.

A BLE KB test on ESP32 DEVKIT found iphones and Android phones working fine, but I tested three dongle chips using CSR dongle in Windows 7 or 10, and Windows couldn't find bluetooth for ESP32.

I tried installed the CSR driver(CSR Harmony) test and it also failed.

What should I do, thank you

[FR] More secure binding as an option

Hello, and first of all thanks for giving me the opportunity to build a C64 based Bluetooth keyboard: https://github.com/SvOlli/VICEboard
But for pairing, I would like it behave like another Bluetooth keyboard I have: upon pairing you need to enter a number on the keyboard to prevent someone else from also pairing it.
As far as I've read through the API and code, this is only a parameter that needs to be changed, and made available somehow.

Send Windows key

Does anyone have an idea why we can't send the Windows key? Key codes should be 0x5B and/or 0x5C (according to https://stackoverflow.com/a/36458787)
This line does not have any effect on my connected Windows machine - other buttons work fine.

bleKeyboard.write(0x5B);

Connect to Apple TV

The ESP doesn't show up in the Apple TV when it is searching for new bluetooth keyboards.

Control+keys a-z not working

Hello! Thank you for sharing the project... I'm using it to add bluetooth support to an IBM Model M, but using it with Windows, combinations of keys CTRL+[a-z], are not sending bluetooth reports.
The following code:

VirtualKey virtualKey = keyboard->getNextVirtualKey(&keyDown);

uint8_t keyCode = convertToKeyCode( virtualKey);
    if (keyDown)
    {
            bleKeyboard.press(keyCode);
    }

For Ctrl-a , gets a VirtualKey of 22 (0x16), which is converted to keyCode 1, which is used as an index for the _asciimap array in BleKeyboard.cpp, and the value for that index is 0, so it's discarded by the press() method:

       if (!k) {
			setWriteError();
			return 0;
		}

Changing the asciimap array so the offsets 0x01,0x02...have values of 0x04,0x05... doesnt really work, as it then confuses the key combination Ctrl-H with the backspace character, So, finally, i changed the virtualKeyToASCII so VK_a ...VK_z and VK_A ... VK_Z returns a keycode independent of CTRL being pressed or not.
So,pressing H makes convertToKeyCode return a 0x1D, independently of CTRL being pressed or not. This is correctly interpreted by Windows (maybe would cause problems in other scenarios?), as CTRL-H (as the OS knows CTRL is still pressed), different from the ASCII code 0x08 (backspace).

IOS13 Microphone mute button

Hello to all,

First I would like to thank the author of this great project.
I would like to send a command to my IOS13 device to mute the microphone during conversation, is the command is available?

Works with iPad Air2, iPad Pro 2, iPhone SE. Does NOT work with iPad 2

I can confirm the example code works with iOS 12.3.1 on:
iPad Air 2: Bluetooth 4.2
iPad Pro 2: Bluetooth 5.0
iPhone SE: Bluetooth 4.2

It does not work with iOS 9.3.5 on an iPad 2 (Bluetooth 2.1). Sadly that’s the device I want to use it for. I want to use it as domotica dashboard and wake it up remotely by using Bluetooth commands. It does not show up in the Bluetooth devices when I try to pair it. Other Bluetooth keyboards work fine. Is this a Bluetooth 2.1 limitation for this to work, and is this solvable?

bluetooth connecting trouble with Mac

so, first of all, I really enjoyed working with the library, it makes everything very clear end easy. but I have a problem when I try to connect to my MacBook Pro (Retina 13 inch, early 2015).
it just keeps on loading and then after a few seconds just stops.
Somehow it got it to connect once ore twice but only those times.
But when I try to connect it to my iPhone (iPhone 7 ) it works like a charm.
I am using this board:
https://www.joy-it.net/de/products/SBC-NodeMCU-ESP32

her is the code I wrote:
`#include <BleKeyboard.h>

BleKeyboard bleKeyboard("esp 32 Macro", "lolo", 100);
const int buttonPin0 = 2;
const int buttonPin1 = 4;
const int buttonPin2 = 18;
const int buttonPin3 = 19;
const int buttonPin4 = 21;

int buttonState0 = 0;
int buttonState1 = 0;
int buttonState2 = 0;
int buttonState3 = 0;
int buttonState4 = 0;

int lastButtonState0 = LOW;
int lastButtonState1 = LOW;
int lastButtonState2 = LOW;
int lastButtonState3 = LOW;
int lastButtonState4 = LOW;

unsigned long lastDebounceTime0 = 0;
unsigned long debounceDelay0 = 50;

unsigned long lastDebounceTime1 = 0;
unsigned long debounceDelay1 = 50;

unsigned long lastDebounceTime2 = 0;
unsigned long debounceDelay2 = 50;

unsigned long lastDebounceTime3 = 0;
unsigned long debounceDelay3 = 50;

unsigned long lastDebounceTime4 = 0;
unsigned long debounceDelay4 = 50;

void setup() {

Serial.begin(115200);
Serial.println("Starting BLE work!");
bleKeyboard.begin();

pinMode(buttonPin0, INPUT);
pinMode(buttonPin1, INPUT);
pinMode(buttonPin2, INPUT);
pinMode(buttonPin3, INPUT);
pinMode(buttonPin4, INPUT);

}

void loop() {

int reading0 = digitalRead(buttonPin0);
int reading1 = digitalRead(buttonPin1);
int reading2 = digitalRead(buttonPin2);
int reading3 = digitalRead(buttonPin3);
int reading4 = digitalRead(buttonPin4);

if(bleKeyboard.isConnected()) {

if (reading0 != lastButtonState0) {

lastDebounceTime0 = millis();

}

if (reading1 != lastButtonState1) {

lastDebounceTime1 = millis();

}

if (reading2 != lastButtonState2) {

lastDebounceTime2 = millis();

}

if (reading3 != lastButtonState3) {

lastDebounceTime3 = millis();

}

if (reading4 != lastButtonState4) {

lastDebounceTime4 = millis();

}

if ((millis() - lastDebounceTime0) > debounceDelay0) {

if (reading0 != buttonState0) {
  buttonState0 = reading0;

 
  if (buttonState0 == HIGH) {
    bleKeyboard.print("2 ");
    
    Serial.println("0");
  }
}

}

if ((millis() - lastDebounceTime1) > debounceDelay1) {

if (reading1 != buttonState1) {
  buttonState1 = reading1;

 
  if (buttonState1 == HIGH) {
    bleKeyboard.print("4 ");
    Serial.println("1");
  }
}

}

if ((millis() - lastDebounceTime2) > debounceDelay2) {

if (reading2 != buttonState2) {
  buttonState2 = reading2;

 
  if (buttonState2 == HIGH) {
    bleKeyboard.write(KEY_LEFT_GUI);
    bleKeyboard.print("z");
    Serial.println("2");
  }
}

}

if ((millis() - lastDebounceTime3) > debounceDelay3) {

if (reading3 != buttonState3) {
  buttonState3 = reading3;

 
  if (buttonState3 == HIGH) {
    bleKeyboard.print("19 ");
    Serial.println("3");
  }
}

}

if ((millis() - lastDebounceTime4) > debounceDelay4) {

if (reading4 != buttonState4) {
  buttonState4 = reading4;

 
  if (buttonState4 == HIGH) {
    bleKeyboard.print("21 ");
    Serial.println("4");
  }
}

}

lastButtonState0 = reading0;
lastButtonState1 = reading1;
lastButtonState2 = reading2;
lastButtonState3 = reading3;
lastButtonState4 = reading4;
}
}`
maby someone can help me. I would realy appreciate it
best reguards Lorenz

Sending Fkeys over F12

I tried to send the F13 key (KEY_F13 code) but it did not work (not received on the Windows 10 side). But F12 (KEY_F12 code) and lower is working correctly.

[iOS] New Line seems not to be send corectly

If I'm trying to send something like this:

bleKeyboard.print("0000111133335\n");
bleKeyboard.print("0000111133335\n");
bleKeyboard.print("0000111133335\n");
bleKeyboard.print("0000111133335\n");

it mostly gets printed on iOS like this:

0000111133335000011113333500001111333350000111133335

and sometimes like this

0000111133335000011113333500001111333350000111133335








...(never ending new lines)

I would expect it like this:

0000111133335
0000111133335
0000111133335
0000111133335

I know, there's no official OSX or iOS support yet. But it's working really well so far. Just this issue is frustrating.

Question: battery life improvement/ sleep mode

Hi everyone,
Did anyone try to improve battery life using the library? I've connected 2000 mAh rechargeable battery and left the module simply paired with my computer. It took approx 15h to consume all the capacity.
I've seen several deep sleep examples but were not able to combine it with the library?
Appreciate any feedback, thank you!

Possible solution for updating battery.

First of all thanks for making this.

I think I may have found a solution for updating the battery percentage.

Adding a call to this->hid->setBatteryLevel(level); in the setBatteryLevel of the BleKeyboard class makes the updating work for me.

However setting the battery level before "begin" causes an exception, so I am not sure if this is a viable solution. Maybe add a dedicated notify function or something?

Sketch has no space for Wifi Libriary

Firstly, this is a great Library - thanks!

This may be down to a cheap ESP32 but with just the Library and an even smaller program (just sending Vol-Up) it's not leaving much spare storage.

Sketch uses 1005159 bytes (76%) of program storage space. Maximum is 1310720 bytes.

I was hoping to include the Wifi stuff, but there isn't enough space.

My own project is simply to trigger a photo (Vol-up appear to work on Android and iPhone).

Additional media keys Creation

Hi,
tested the library with esp32 and ios 12, 13 ,10 everything works as told, extremely thankful for putting such a wonderful product together.
i wanted to have some information as to how to extend "send media keys" "KEY_MEDIA" like maybe ability to add screenshot, launch voice recorder (primarily on ios) etc.
if you can point me to right direction as to where to begin i maybe able to extend it further, any help would be great

adding additional media keys?

Just found your project after beating my head against the wall trying to learn the ESP-IDF. This is the only project I have found that seems to do security in a way where iOS will accept inputs and I have set up a simple program to send single characters with pushbuttons and it works great. thanks for the hard work. One little annoyance of iOS and bluetooth keyboards is that they hide the on screen keyboard whenever a bluetooth keyboard is connected. I am trying to make an ebook page turner remote for a relative who has limited mobility and would like to read on her phone on a gooseneck mount while in bed. In order to toggle the OSK when a BT keyboard is connected, i need have the BT device send the eject key. I have done this in the past using the HID-project.h library
I can't remeber which one worked but it was either
HID_CONSUMER_EJECT
or
HID_CONSUMER_STOP_SLASH_EJECT
I am very new to C and kind of out of my depth in trying to implement this and was hoping someone could point me in the right direction. Thanks again for the great project. I am already dreaming up a way to augment the lack of a physical play/pause button in my honda when using carplay and other interesting little projects.

German-Umlaute/Layout

Hi,
I tried to send some german "umlaute" something like ö,ä,ü but my iPad does not receive anthing.
Also the "<"-sign is displayed as ";". On my iPad I switched between the German and English keyboard layout, but it does not really help. Is it possible to switch the keyboard layout on the esp32-ble-keyboard or do you know how to solve this?

Thanks!

Adding License to project?

Would you be willing to add a license to your project? I wanted to incorporate your implementation of media keys in the standard Arduino keyboard library, to use with a matrix keypad. This would be fine for a personal project like mine. But, I also would like to submit a pull request to the Arduino Library with these changes.

I don't think I can do that without a license published in your repository. I would really appreciate it.

Thanks.

SNES Control

Sorry for my complete ignorance, I'm new to this world of Arduino and ESP32.
I thought this work was great and I'm trying to adapt it for a SNES control. For each button on the control I am assigning a key, for button "A" on the control for example, assign the key "x" and sending this data via BLE to the computer with ZSNS. My problem seems to be in the timing, because when pressing a button on the control there is no instant response on the emulator, I have to press several times to enter the command. Was there a way to sync the keyboard input?

Below my code.

#include <BleKeyboard.h>

BleKeyboard bleKeyboard;

//define where your pins are
const int dataPin = 21; // RED
const int latchPin = 19; // YELLOW
const int clockPin = 18; // BLUE
const int intervalo = 250; // atraso entre leituras

long buttonData, lastButtonData = 72; //01001000

// On NES Controller there are only 8 buttons, also B, Y swap to A and B
const int n_buttons = 12;
char* buttons[] = {"B", "Y", "SELECT", "START",
"UP", "DOWN", "LEFT", "RIGHT",
"A", "X", "L_BUTTON", "R_BUTTON"};

//Funções que serão chamadas por um array de pinteiros
void Button_B() {/Serial.println("Apertou o B bruxo!!!!");/ bleKeyboard.print("z"); delay(intervalo);}
void Button_Y(){/Serial.println("Apertou o Y bruxo!!!!");/ bleKeyboard.print("a"); delay(intervalo);}
void Button_SELECT(){/Serial.println("Apertou o SELECT bruxo!!!!");/ bleKeyboard.write(KEY_RIGHT_SHIFT); delay(intervalo);}
void Button_START(){/Serial.println("Apertou o START bruxo!!!!");/ bleKeyboard.write(KEY_RETURN); delay(intervalo);}
void Button_UP(){/Serial.println("Apertou o UP bruxo!!!!");/ bleKeyboard.write(KEY_UP_ARROW); delay(intervalo);}
void Button_DOWN(){/Serial.println("Apertou o DOWN bruxo!!!!");/ bleKeyboard.write(KEY_DOWN_ARROW); delay(intervalo);}
void Button_LEFT(){/Serial.println("Apertou o LEFT bruxo!!!!");/ bleKeyboard.write(KEY_LEFT_ARROW); delay(intervalo);}
void Button_RIGHT(){/Serial.println("Apertou o RIGHT bruxo!!!!");/ bleKeyboard.write(KEY_RIGHT_ARROW); delay(intervalo);}
void Button_A(){/Serial.println("Apertou o A bruxo!!!!");/ bleKeyboard.print("x"); delay(intervalo);}
void Button_X(){/Serial.println("Apertou o X bruxo!!!!");/ bleKeyboard.print("s"); delay(intervalo);}
void Button_L_BUTTON(){/Serial.println("Apertou o L_BUTTON bruxo!!!!");/ bleKeyboard.print("d"); delay(intervalo);}
void Button_R_BUTTON(){/Serial.println("Apertou o R_BUTTON bruxo!!!!");/ bleKeyboard.print("c"); delay(intervalo);}

//Array com os ponteiro que chamará as funções
void (*ButtonPointer[])(void) = {Button_B, Button_Y, Button_SELECT, Button_START,
Button_UP, Button_DOWN, Button_LEFT, Button_RIGHT,
Button_A, Button_X, Button_L_BUTTON, Button_R_BUTTON};

void setup() {
Serial.begin(115200);
Serial.println("Starting BLE work!");
bleKeyboard.begin();

//define pin modes
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, INPUT);

//Cria a Task para ler os botões do controle SNES ****************************************************
xTaskCreate(
taskControleSNES, /* Task function. /
"TaskControleSNES", /
String with name of task. /
10000, /
Stack size in bytes. /
NULL, /
Parameter passed as input of the task /
1, /
Priority of the task. /
NULL); /
Task handle. /
//
***************************************************************************************************

}

void loop() {
if(bleKeyboard.isConnected()) {

//if (buttonData != lastButtonData){
lastButtonData = buttonData;
//Print Raw Value of Registers
//Serial.println(buttonData, BIN);

// Print String in Button Name Array
for (int n = 0; n < n_buttons; n++)
{
  if (buttonData & (1 << n) ){
    //Serial.print(buttons[n]);
    ButtonPointer[n]();
    //Serial.print(", ");
  }
}
//Serial.println("\n-------------------");

//}

//delay(10);
  
//bleKeyboard.releaseAll();

}
}

void taskControleSNES( void * parameter )
{

while(1){

// Latch Signal

digitalWrite(latchPin, HIGH);
delayMicroseconds(12);
digitalWrite(latchPin, LOW);

int temp = 0;
buttonData = 0;
for (int i = 0; i < n_buttons; i++)
{
digitalWrite(clockPin, LOW);
delayMicroseconds(0.2);
temp = digitalRead(dataPin);
// 0 Indicates button depressed for SNES controller
if (!temp) {
//temp = size_buttonData - i;
buttonData = buttonData | ((long)1 << i);
}
digitalWrite(clockPin, HIGH);
}

//if (buttonData != lastButtonData){
//lastButtonData = buttonData;
// Print Raw Value of Registers
//Serial.println(buttonData, BIN);

// Print String in Button Name Array

/* for (int n = 0; n < n_buttons; n++)
{
if (buttonData & (1 << n) ){
Serial.print(buttons[n]);
Serial.print(", ");
}
}
Serial.println("\n-------------------"); */
//}
delay(10);
}

vTaskDelete( NULL );

}

Configurable media keys?

Firstly, many thanks for the library - I've been using it to set up an ESP32 to convert infrared keycodes into keyboard input to an Amazon FireStick 4K so my wife can use a firestick with the remote she likes.

The only difficulty I've had is that the firestick needs to receive a specific media key for its menu button, and the only way I've found of achieving that is to physically edit the bleKeyboard.cpp file to change the media key mapping for one of the 16 assigned keys.

That works fine, but it's ugly and won't make it easy to track future changes to the library.

So, my question is: would it be worth adding a new API to be called before begin() which allows the media key assignments to be overridden? It's clearly not a vast amount of work, and I'd be happy to volunteer to do it if there were sufficient interest.

Question: For Media, is there buffering, and if so can we have a command to clear it?

I have this working wonderfully, thanks you for this lib.

I have a user experiance challenge on my project.
When controlling volume on my mac (15" 2017 Catalina 10.15.6) with a rotary encoder connected to an ESP32 (MH ET LIVE ESP32DevKIT) the volume on the mac is increased and decreased as expected.

If I spin the encoder the volume increases as expected, but the mac continues to increase volume for a while after the encoder stops, my guess is it is processing a buffer either in ESP32-BLE-Keyboard or in the MAC.

Any ideas how either clear the buffer in the ESP32-BLE-Keyboard code (if there is one) before each next "volume up" send.

I would like the volume to increase as the encoder is spinning and stop immediately the encoder stops. Volume is relative so missing keys is ok in this context.

#include "sdkconfig.h" file or directory not found

Disclaimer: This may very well be due to the fact I'm still fairly new to using Arduino controllers and the IDE in general.

I have the library is included in my project, but when I attempt to verify and upload I get the following error
...\Arduino\libraries\ESP32-BLE-Keyboard-0.1.0/BleConnectionStatus.h:3:10: fatal error: sdkconfig.h: No such file or directory.

I am trying to upload to a Arduino MKR WiFi 1010 which uses an esp32 chip. I'm using IDE 1.8.8, and I have the esp32 board package version 1.0.4.

Any help is appreciated.

esp32 crashes in begin() call

Hi,

I try to build a ble keyboard which is controlled via a webserver over wifi.

I had your sample script running and controlling the ble keyboard via serial.
Also I had a webserver running and sending commands via web sockets.
Combining both is where I fail.

Whenever I call blekeyboard.begin(), it crashes, when it leaves the setup() method. I decoded the stack trace:

Decoding stack results
0x40091f40: invoke_abort at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp32/panic.c line 155
0x40092171: abort at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp32/panic.c line 170
0x40149137: __cxxabiv1::__terminate(void (*)()) at /builds/idf/crosstool-NG/.build/src/gcc-5.2.0/libstdc++-v3/libsupc++/eh_terminate.cc line 47
0x4014917e: std::terminate() at /builds/idf/crosstool-NG/.build/src/gcc-5.2.0/libstdc++-v3/libsupc++/eh_terminate.cc line 57
0x40148849: __cxxabiv1::__cxa_allocate_exception(std::size_t) at /builds/idf/crosstool-NG/.build/src/gcc-5.2.0/libstdc++-v3/libsupc++/eh_alloc.cc line 268
0x401485cc: operator new(unsigned int) at /builds/idf/crosstool-NG/.build/src/gcc-5.2.0/libstdc++-v3/libsupc++/new_op.cc line 54
0x4014d523: BLEService::createCharacteristic(BLEUUID, unsigned int) at C:\Users\fabse\.platformio\packages\framework-arduinoespressif32\libraries\BLE\src\BLEService.cpp line 259
0x4014bee9: BLEHIDDevice::manufacturer() at C:\Users\fabse\.platformio\packages\framework-arduinoespressif32\libraries\BLE\src\BLEHIDDevice.cpp line 78
0x400d1517: BleKeyboard::taskServer(void*) at .pio\libdeps\d\ESP32 BLE Keyboard\BleKeyboard.cpp line 135
0x4008e689: vPortTaskWrapper at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/port.c line 143

it feels to me like the ram is full, because new fails, but the build process shows only 11.3% used.

RAM:   [=         ]  11.3% (used 60188 bytes from 532480 bytes)
Flash: [=======   ]  74.3% (used 1460628 bytes from 1966080 bytes)

platform.io ini file:

[env:d]
platform = espressif32
board = az-delivery-devkit-v4
board_build.partitions = min_spiffs.csv
framework = arduino
monitor_speed = 115200
lib_deps =
  ESP32 BLE Arduino@>=1.0.1
  https://github.com/T-vK/ESP32-BLE-Keyboard#master
  ESPAsyncTCP-esphome@>=1.2.3
  ESPAsyncWebServer-esphome@>=1.2.7

relevant part of my main.cpp:

#include <FS.h>
#include "SPIFFS.h"
#include <WebServer.h>
#include <DNSServer.h>
#include <WiFi.h>

#include <FS.h>
#include <SPIFFS.h>
#include <ESPmDNS.h>
#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>

#include <BleKeyboard.h>

AsyncWebServer asyncWebServer(80);
AsyncWebSocket ws("/ws");
BleKeyboard bleKeyboard("Generic Keyboard", "Generic", 82);

void setupWebServer();

void setup()
{
  Serial.begin(115200);

  Serial.println("setup");

  SPIFFS.begin();

  if (!MDNS.begin("bleKB"))
  {
    Serial.println("Error setting up MDNS responder!");
    while (1)
    {
      delay(1000);
    }
  }

  Serial.println("starting wifi auto connect");
  WiFi.begin("...", "...");

  if (WiFi.waitForConnectResult() != WL_CONNECTED)
  {
    Serial.printf("WiFi simple Failed!\n");
  }
  else
  {
    Serial.printf("WiFi simple succeeded!\n");
  }

  Serial.println("setting up web server");
  //configureWebServer();//left out, as it does not change anything
  asyncWebServer.begin();
  Serial.println("setting up web server: done");

  Serial.println("Starting BLE work!");
  bleKeyboard.begin();
  Serial.println("setup done!");
}

and a sample serial log:

starting wifi auto connect
WiFi simple succeeded!
setting up web server
setting up web server: done
Starting BLE work!
setup done!
abort() was called at PC 0x401492af on core 1

Backtrace: 0x40091f40:0x3ffecf60 0x4009               2171:0x3ffecf80 0x401492af:0x3ffecfa0 0x401492f6:0x3ffecfc0 0x40148663:0x3ffecfe0 0x40148752:0x3ffed000 0x4014d69b:0x3ffed020 0x4014c061:0x3ffed090 0x400d15ab:0x3ffed0e0 0x
[37m4008e689:0x3ffed120

Rebooting...

notice the spaces in the backtrace? seems wrong to me.

I do not know where I should continue at all with this.

Typo in readme

...By default the battery level will be set to 100%, the device name will be ESP32 Bluetooth Mouse... should be "ESP32 Bluetooth Keyboard"

List of supported / unsupported Apple devices (iPhones, iPads, Macs etc.)

I would like to maintain a list of Apple devices here that work or don't work with this library.
If you have tested a device that is not listed with the same OS version yet, please add a comment and tell me which device and operating system (i.e. iOS version or Mac OS version).
If you tested a device that is already listed, but you had different results (e.g. list says it doesn't work, but for you it does work), please add a comment as well. (And don't forget to mention your device name and OS version.)

Devices that work

  • iPhone SE | iOS 12.3.1 | Reported by satoer
  • iPad Air 2 | iOS 12.3.1 | Reported by satoer
  • iPad Pro 2 | iOS 12.3.1 | Reported by satoer

Devices that don't work

  • 3rd generation iPad (2012) AND ALL DEVICES OLDER THAN THAT (because they don't support Bluetooth LE)
  • iPhone 4s AND ALL DEVICES OLDER THAN THAT (because they don't support Bluetooth LE)
  • MacBook Air 2011 AND ALL DEVICES OLDER THAN THAT (because they don't support Bluetooth LE)
  • MacBook Pro 2012 AND ALL DEVICES OLDER THAN THAT (because they don't support Bluetooth LE)
  • MacMini 2011 AND ALL DEVICES OLDER THAN THAT (because they don't support Bluetooth LE)
  • iMac 2012 AND ALL DEVICES OLDER THAN THAT (because they don't support Bluetooth LE)
  • iPad 2 | iOS 9.3.5 | Reported by satoer
  • iPad Air | iOS 10.3.3 | Reported by iwbrhwfy-source | Note: Can't find device
  • iPhone 7+ | iOS 12.x.x | Reported by iwbrhwfy-source | Note: "very limited by app"

Work with ESP32-BLE-Mouse?

I can't seem to get the ESP32-BLE-Keyboard and ESP32-BLE-Mouse to work together in the same sketch.

I've made some modifications to BleConnectionStatus to have unique BleMouseConnectionStatus and BleKeyboardConnectionStatus files and classes, but it seems that only one of the endpoints is detected on the host. Any tips on how to make them work together? Happy to submit a patch once I've got it working...

Power optimization

Thanks for great library :)

Is there any known method to make power consumption lower?
WROOM devkit, keyboard idle -> around 60-65mA, same when sending keypresses.
As far as I understand how BLE works, it shoud not send data when no data has to be transfered.

I cannot use light sleep because I shoud turn off bluetooth and bluedroid prior to going to sleep afaik.

Some optimization suggestions

hi @T-vK ,This is a great library,I have some problems using this,I made some modifications to make it work better,

xTaskCreate(this->taskServer, "server", 20000, (void *)this, 5, NULL);

Here the task to create a 20000byte, this should not be necessary, it takes up a lot of memory,#40
I modified it to

void BleKeyboard::begin(void)
{
       // xTaskCreate(this->taskServer, "server", 20000, (void *)this, 5, NULL);
	this->taskServer((void *)this);
}

It also works
2.In the course of use, they seem to be difficult to be found and connected successfully, and they will not be disconnected and reconnected.
Reference bledemo, are missing some steps

I modified it to
BleKeyboard.h

class BleKeyboard : public Print
{
private:
  BleConnectionStatus* connectionStatus;
  BLEHIDDevice* hid;
  BLECharacteristic* inputKeyboard;
  BLECharacteristic* outputKeyboard;
  BLECharacteristic* inputMediaKeys;
  KeyReport _keyReport;
  MediaKeyReport _mediaKeyReport;
  //add
  BLEServer *pServer = NULL;

  static void taskServer(void* pvParameter);
public:
  BleKeyboard(std::string deviceName = "RTSCAN Scanner", std::string deviceManufacturer = "RTSCAN", uint8_t batteryLevel = 100);
  void begin(void);
  void end(void);
  void sendReport(KeyReport* keys);
  void sendReport(MediaKeyReport* keys);
  size_t press(uint8_t k);
  size_t press(const MediaKeyReport k);
  size_t release(uint8_t k);
  size_t release(const MediaKeyReport k);
  size_t write(uint8_t c);
  size_t write(const MediaKeyReport c);
  size_t write(const uint8_t *buffer, size_t size);
  void releaseAll(void);
  bool isConnected(void);
  void setBatteryLevel(uint8_t level);
  uint8_t batteryLevel;
  std::string deviceManufacturer;
  std::string deviceName;
   //add
  void startAdvertising();
protected:
  virtual void onStarted(BLEServer *pServer) { };
};

add
BLEServer *pServer = NULL;
void startAdvertising();

BleKeyboard.cpp

void BleKeyboard::taskServer(void* pvParameter) {
  BleKeyboard* bleKeyboardInstance = (BleKeyboard *) pvParameter; //static_cast<BleKeyboard *>(pvParameter);
  BLEDevice::init(bleKeyboardInstance->deviceName);
   //modify
  bleKeyboardInstance->pServer = BLEDevice::createServer();
  bleKeyboardInstance->pServer->setCallbacks(bleKeyboardInstance->connectionStatus);

  bleKeyboardInstance->hid = new BLEHIDDevice(bleKeyboardInstance->pServer);
  bleKeyboardInstance->inputKeyboard = bleKeyboardInstance->hid->inputReport(KEYBOARD_ID); // <-- input REPORTID from report map
  bleKeyboardInstance->outputKeyboard = bleKeyboardInstance->hid->outputReport(KEYBOARD_ID);
  bleKeyboardInstance->inputMediaKeys = bleKeyboardInstance->hid->inputReport(MEDIA_KEYS_ID);
  bleKeyboardInstance->connectionStatus->inputKeyboard = bleKeyboardInstance->inputKeyboard;
  bleKeyboardInstance->connectionStatus->outputKeyboard = bleKeyboardInstance->outputKeyboard;
	bleKeyboardInstance->connectionStatus->inputMediaKeys = bleKeyboardInstance->inputMediaKeys;

  bleKeyboardInstance->outputKeyboard->setCallbacks(new KeyboardOutputCallbacks());

  bleKeyboardInstance->hid->manufacturer()->setValue(bleKeyboardInstance->deviceManufacturer);

  bleKeyboardInstance->hid->pnp(0x02, 0xe502, 0xa111, 0x0210);
  bleKeyboardInstance->hid->hidInfo(0x00,0x01);

  BLESecurity *pSecurity = new BLESecurity();

  pSecurity->setAuthenticationMode(ESP_LE_AUTH_BOND);

  bleKeyboardInstance->hid->reportMap((uint8_t*)_hidReportDescriptor, sizeof(_hidReportDescriptor));
  bleKeyboardInstance->hid->startServices();

  bleKeyboardInstance->onStarted(bleKeyboardInstance->pServer);

  BLEAdvertising *pAdvertising = bleKeyboardInstance->pServer->getAdvertising();
  pAdvertising->setAppearance(HID_KEYBOARD);
  pAdvertising->addServiceUUID(bleKeyboardInstance->hid->hidService()->getUUID());
  pAdvertising->setScanResponse(false);
  pAdvertising->start();
  bleKeyboardInstance->hid->setBatteryLevel(bleKeyboardInstance->batteryLevel);

  ESP_LOGD(LOG_TAG, "Advertising started!");
  // vTaskDelay(portMAX_DELAY); //delay(portMAX_DELAY);
}

//add
void BleKeyboard::startAdvertising()
{
  this->pServer->startAdvertising();
}

ex

#include <BleKeyboard.h>

BleKeyboard bleKeyboard;

bool oldstatus = false;

void setup() {
  Serial.begin(115200);
  Serial.println("Starting BLE work!");
  bleKeyboard.begin();
}

void loop() {
  if(bleKeyboard.isConnected()) {
    if(oldstatus){
      oldstatus = false;
      bleKeyboard.startAdvertising();
    }
    Serial.println("Sending 'Hello world'...");
    bleKeyboard.print("Hello world");
    delay(1000);
    bleKeyboard.releaseAll();
  }else{
      oldstatus = true;
  }

  Serial.println("Waiting 5 seconds...");
  delay(5000);
}

They work very well after modification, and can automatically connect soon after disconnecting,You can refer to these changes

Smooth keyboard injections

Hi, I am trying to inject keystrokes in a continuous manner. The problem is that I either stuff the buffer and when I release the key it keeps on sending, or it I sende too few keystrokes. I basically use trial and error, but is there a technical explanation ot the max times, delays, etc.?

iOS14.1 and iOS12.4.8 cannot find ESP32 BLE keyboard

I use M5StickC have Code include BleKeyboard.h. But they cannot find the device as ESP32 BLE keyboard.
Win10 can find the device with Bluetooth.
How iOS find the device with BleKeyboard?

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

BleKeyboard bleKeyboard;

enum ConfSystem {
  mic = 0,
  video
} conf;
int n_conf = 2;
bool on_air;

void setup() {
  M5.begin();
  bleKeyboard.begin();

  Serial.println("Webconf Mute button");
  Serial.println("Push Button A (M5) to toggle MUTE");
  Serial.println("Push Button B to switch VideoOn or VideoOFF");
  M5.Lcd.setRotation(3); // BtnA is left side to LCD

  // default
  conf = mic;
  on_air = true;
  update_display();
}

void loop() {
  M5.update();
  
  if(M5.BtnA.wasPressed()){
    Serial.println("BtnA was pressed");
    if(bleKeyboard.isConnected()){
      on_air = !on_air;
      if(conf==mic){
        send_mute_mic();
      }
      else if(conf==video){
      send_off_video();
      }
    }
    else {
      Serial.println("BLE is not connected");
    }
    update_display();
  }

  if(M5.BtnB.wasPressed()){
    Serial.println("BtnB was pressed");
    conf = ConfSystem((conf+1) % n_conf);
    Serial.print("New ConfSystem: ");
    Serial.println(conf);
    update_display();
  }
  delay(10);
}

void update_display(){
  Serial.println("update_display");
  Serial.print("On air?: ");
  Serial.println(on_air);
  if(on_air){
    show_onair();
  }
  else {
    show_inmute();
  }
}

void show_onair(){
  M5.Lcd.fillScreen(TFT_RED);
  M5.Lcd.setTextColor(TFT_WHITE, TFT_RED);
  M5.Lcd.setTextSize(3);
  M5.Lcd.setTextDatum(MC_DATUM);
  M5.Lcd.drawString("ON AIR",80,40);

  M5.Lcd.setTextSize(2);
  M5.Lcd.setTextDatum(BR_DATUM);
  if(conf==mic){
    M5.Lcd.drawString("Mic",158,78);
  }
  else if (conf==video){
    M5.Lcd.drawString("Video", 158,78);  
  }
}

void show_inmute(){
  M5.Lcd.fillScreen(TFT_DARKGREY);
  M5.Lcd.setTextColor(TFT_WHITE, TFT_DARKGREY);
  M5.Lcd.setTextSize(3);
  M5.Lcd.setTextDatum(MC_DATUM);
  M5.Lcd.drawString("Muted...",80,40);

  M5.Lcd.setTextSize(2);
  M5.Lcd.setTextDatum(BR_DATUM);
  if(conf==mic){
    M5.Lcd.drawString("Mic",158,78);
  }
  else if (conf==video){
    M5.Lcd.drawString("Video", 158,78);  
  }
}

void send_mute_mic(){
  // https://support.zoom.us/hc/en-us/articles/205683899-Hot-Keys-and-Keyboard-Shortcuts-for-Zoom
  // Command(⌘)+Shift+A: Mute/unmute audio
  Serial.println("Toggle Mic");
  bleKeyboard.press(KEY_LEFT_GUI);
  bleKeyboard.press(KEY_LEFT_SHIFT);
  bleKeyboard.press('a');
  delay(100);
  bleKeyboard.releaseAll();
}

void send_off_video(){
  // https://www.cisco.com/c/en/us/td/docs/collaboration/CWMS/2_5/b_manage_meetings/b_manage_meetings_chapter_0100.html
  Serial.println("Toggle Video");
  bleKeyboard.press(KEY_LEFT_GUI);
  bleKeyboard.press(KEY_LEFT_SHIFT);
  bleKeyboard.press('v');
  delay(100);
  bleKeyboard.releaseAll();
}

Trouble connecting with Android Samsung Galaxy Note 10

Hi !

Thanks a lot for this library, really helpful. I used it to make a dongle that send very strong passwords (32 characters, fully random patterns).

I used your library just adding a pincode security to avoid someone connecting to the dongle and stealing the password

BLESecurity *pSecurity = new BLESecurity();
pSecurity->setStaticPIN(bleKeyboardInstance->hid_pincode);
pSecurity->setAuthenticationMode(ESP_LE_AUTH_REQ_SC_BOND);

it works like a charm on my windows computer, but not on my android phone (Samsung Galaxy Note SM-N950F, Android 9). It was working with android previous version, i think it is probable related to a security update.

When I do the pairing i get the following message : "Pairing impossible." It works sometimes if I delete the pincode setting line.
Any idea regarding what's wrong ? Also, can you tell me where I can find the documentation regarding authentificationmode , setCapability and setInitEncryptionKey ?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.