Skip to content

Instantly share code, notes, and snippets.

@manuelbl
Created August 3, 2019 09:12
Show Gist options
  • Save manuelbl/66f059effc8a7be148adb1f104666467 to your computer and use it in GitHub Desktop.
Save manuelbl/66f059effc8a7be148adb1f104666467 to your computer and use it in GitHub Desktop.
ESP32 as Bluetooth Keyboard

ESP32 as Bluetooth Keyboard

With its built-in Bluetooth capabilities, the ESP32 can act as a Bluetooth keyboard. The below code is a minimal example of how to achieve it. It will generate the key strokes for a message whenever a button attached to the ESP32 is pressed.

For the example setup, a momentary button should be connected to pin 2 and to ground. Pin 2 will be configured as an input with pull-up.

In order to receive the message, add the ESP32 as a Bluetooth keyboard of your computer or mobile phone:

  1. Go to your computers/phones settings
  2. Ensure Bluetooth is turned on
  3. Scan for Bluetooth devices
  4. Connect to the device called "ESP32 Keyboard"
  5. Open an empty document in a text editor
  6. Press the button attached to the ESP32

The code has been written for the Arduino framework. I recommend using PlatformIO for development as it is far superior to the Arduino IDE while still taking full advantage of the Arduino ecosystem (libraries, support etc.)

/*
* Sample program for ESP32 acting as a Bluetooth keyboard
*
* Copyright (c) 2019 Manuel Bl
*
* Licensed under MIT License
* https://opensource.org/licenses/MIT
*/
//
// This program lets an ESP32 act as a keyboard connected via Bluetooth.
// When a button attached to the ESP32 is pressed, it will generate the key strokes for a message.
//
// For the setup, a momentary button should be connected to pin 2 and to ground.
// Pin 2 will be configured as an input with pull-up.
//
// In order to receive the message, add the ESP32 as a Bluetooth keyboard of your computer
// or mobile phone:
//
// 1. Go to your computers/phones settings
// 2. Ensure Bluetooth is turned on
// 3. Scan for Bluetooth devices
// 4. Connect to the device called "ESP32 Keyboard"
// 5. Open an empty document in a text editor
// 6. Press the button attached to the ESP32
#define US_KEYBOARD 1
#include <Arduino.h>
#include "BLEDevice.h"
#include "BLEHIDDevice.h"
#include "HIDTypes.h"
#include "HIDKeyboardTypes.h"
// Change the below values if desired
#define BUTTON_PIN 2
#define MESSAGE "Hello from ESP32\n"
#define DEVICE_NAME "ESP32 Keyboard"
// Forward declarations
void bluetoothTask(void*);
void typeText(const char* text);
bool isBleConnected = false;
void setup() {
Serial.begin(115200);
// configure pin for button
pinMode(BUTTON_PIN, INPUT_PULLUP);
// start Bluetooth task
xTaskCreate(bluetoothTask, "bluetooth", 20000, NULL, 5, NULL);
}
void loop() {
if (isBleConnected && digitalRead(BUTTON_PIN) == LOW) {
// button has been pressed: type message
Serial.println(MESSAGE);
typeText(MESSAGE);
}
delay(100);
}
// Message (report) sent when a key is pressed or released
struct InputReport {
uint8_t modifiers; // bitmask: CTRL = 1, SHIFT = 2, ALT = 4
uint8_t reserved; // must be 0
uint8_t pressedKeys[6]; // up to six concurrenlty pressed keys
};
// Message (report) received when an LED's state changed
struct OutputReport {
uint8_t leds; // bitmask: num lock = 1, caps lock = 2, scroll lock = 4, compose = 8, kana = 16
};
// The report map describes the HID device (a keyboard in this case) and
// the messages (reports in HID terms) sent and received.
static const uint8_t REPORT_MAP[] = {
USAGE_PAGE(1), 0x01, // Generic Desktop Controls
USAGE(1), 0x06, // Keyboard
COLLECTION(1), 0x01, // Application
REPORT_ID(1), 0x01, // Report ID (1)
USAGE_PAGE(1), 0x07, // Keyboard/Keypad
USAGE_MINIMUM(1), 0xE0, // Keyboard Left Control
USAGE_MAXIMUM(1), 0xE7, // Keyboard Right Control
LOGICAL_MINIMUM(1), 0x00, // Each bit is either 0 or 1
LOGICAL_MAXIMUM(1), 0x01,
REPORT_COUNT(1), 0x08, // 8 bits for the modifier keys
REPORT_SIZE(1), 0x01,
HIDINPUT(1), 0x02, // Data, Var, Abs
REPORT_COUNT(1), 0x01, // 1 byte (unused)
REPORT_SIZE(1), 0x08,
HIDINPUT(1), 0x01, // Const, Array, Abs
REPORT_COUNT(1), 0x06, // 6 bytes (for up to 6 concurrently pressed keys)
REPORT_SIZE(1), 0x08,
LOGICAL_MINIMUM(1), 0x00,
LOGICAL_MAXIMUM(1), 0x65, // 101 keys
USAGE_MINIMUM(1), 0x00,
USAGE_MAXIMUM(1), 0x65,
HIDINPUT(1), 0x00, // Data, Array, Abs
REPORT_COUNT(1), 0x05, // 5 bits (Num lock, Caps lock, Scroll lock, Compose, Kana)
REPORT_SIZE(1), 0x01,
USAGE_PAGE(1), 0x08, // LEDs
USAGE_MINIMUM(1), 0x01, // Num Lock
USAGE_MAXIMUM(1), 0x05, // Kana
LOGICAL_MINIMUM(1), 0x00,
LOGICAL_MAXIMUM(1), 0x01,
HIDOUTPUT(1), 0x02, // Data, Var, Abs
REPORT_COUNT(1), 0x01, // 3 bits (Padding)
REPORT_SIZE(1), 0x03,
HIDOUTPUT(1), 0x01, // Const, Array, Abs
END_COLLECTION(0) // End application collection
};
BLEHIDDevice* hid;
BLECharacteristic* input;
BLECharacteristic* output;
const InputReport NO_KEY_PRESSED = { };
/*
* Callbacks related to BLE connection
*/
class BleKeyboardCallbacks : public BLEServerCallbacks {
void onConnect(BLEServer* server) {
isBleConnected = true;
// Allow notifications for characteristics
BLE2902* cccDesc = (BLE2902*)input->getDescriptorByUUID(BLEUUID((uint16_t)0x2902));
cccDesc->setNotifications(true);
Serial.println("Client has connected");
}
void onDisconnect(BLEServer* server) {
isBleConnected = false;
// Disallow notifications for characteristics
BLE2902* cccDesc = (BLE2902*)input->getDescriptorByUUID(BLEUUID((uint16_t)0x2902));
cccDesc->setNotifications(false);
Serial.println("Client has disconnected");
}
};
/*
* Called when the client (computer, smart phone) wants to turn on or off
* the LEDs in the keyboard.
*
* bit 0 - NUM LOCK
* bit 1 - CAPS LOCK
* bit 2 - SCROLL LOCK
*/
class OutputCallbacks : public BLECharacteristicCallbacks {
void onWrite(BLECharacteristic* characteristic) {
OutputReport* report = (OutputReport*) characteristic->getData();
Serial.print("LED state: ");
Serial.print((int) report->leds);
Serial.println();
}
};
void bluetoothTask(void*) {
// initialize the device
BLEDevice::init(DEVICE_NAME);
BLEServer* server = BLEDevice::createServer();
server->setCallbacks(new BleKeyboardCallbacks());
// create an HID device
hid = new BLEHIDDevice(server);
input = hid->inputReport(1); // report ID
output = hid->outputReport(1); // report ID
output->setCallbacks(new OutputCallbacks());
// set manufacturer name
hid->manufacturer()->setValue("Maker Community");
// set USB vendor and product ID
hid->pnp(0x02, 0xe502, 0xa111, 0x0210);
// information about HID device: device is not localized, device can be connected
hid->hidInfo(0x00, 0x02);
// Security: device requires bonding
BLESecurity* security = new BLESecurity();
security->setAuthenticationMode(ESP_LE_AUTH_BOND);
// set report map
hid->reportMap((uint8_t*)REPORT_MAP, sizeof(REPORT_MAP));
hid->startServices();
// set battery level to 100%
hid->setBatteryLevel(100);
// advertise the services
BLEAdvertising* advertising = server->getAdvertising();
advertising->setAppearance(HID_KEYBOARD);
advertising->addServiceUUID(hid->hidService()->getUUID());
advertising->addServiceUUID(hid->deviceInfo()->getUUID());
advertising->addServiceUUID(hid->batteryService()->getUUID());
advertising->start();
Serial.println("BLE ready");
delay(portMAX_DELAY);
};
void typeText(const char* text) {
int len = strlen(text);
for (int i = 0; i < len; i++) {
// translate character to key combination
uint8_t val = (uint8_t)text[i];
if (val > KEYMAP_SIZE)
continue; // character not available on keyboard - skip
KEYMAP map = keymap[val];
// create input report
InputReport report = {
.modifiers = map.modifier,
.reserved = 0,
.pressedKeys = {
map.usage,
0, 0, 0, 0, 0
}
};
// send the input report
input->setValue((uint8_t*)&report, sizeof(report));
input->notify();
delay(5);
// release all keys between two characters; otherwise two identical
// consecutive characters are treated as just one key press
input->setValue((uint8_t*)&NO_KEY_PRESSED, sizeof(NO_KEY_PRESSED));
input->notify();
delay(5);
}
}
@manuelbl
Copy link
Author

@alex-k8 I'm assuming your keyboard is connected by USB. USB and Bluetooth work very similar when it comes to keyboards. The both exchange input and output reports in exactly the same format. So to control the LEDs, you would need to forward the output report ot the keyboard. But I have no idea what USB/keyboard API you are using. So this might be possible, or you might need to go a different approach.

@alex-k8
Copy link

alex-k8 commented Feb 19, 2023

@manuelbl Thank you for your insight, I think I'll figure it out!

@trethaller
Copy link

Thanks, for some reason the T-vK/ESP32-BLE-Keyboard lib does nor pair with my Fairphone FP3 but your code did it!

@ctc-nick
Copy link

Thanks a lot @manuelbl! It is working. I'm trying to figure out how to map 'Ctrl+A' ae command (modifiers). it looks like the typetext function can do this, but I don't get it. Maybe somebody has a hint for me?

@manuelbl
Copy link
Author

manuelbl commented Jul 2, 2023

@ctc-nick I'm not entirely sure what you mean with "'Ctrl+A' ae command (modifiers)". If you want to send CTRL+A, then you will have to extend the code:

void sendCtrlKey(char key) {
    // create input report
    InputReport report = {
        .modifiers = KEY_CTRL,
        .reserved = 0,
        .pressedKeys = { keymap[(uint8_t)key].usage, 0, 0, 0, 0, 0 }
    };

    // send the input report
    input->setValue((uint8_t*)&report, sizeof(report));
    input->notify();
    delay(5);

    // release all keys
    input->setValue((uint8_t*)&NO_KEY_PRESSED, sizeof(NO_KEY_PRESSED));
    input->notify();
    delay(5);
}

@ctc-nick
Copy link

ctc-nick commented Jul 2, 2023

@manuelbl You got me right. Your short example is very good, because now I really understand that function more. Thank You!
Maybe this is interesting: With some AI help I modified the function so that it accepts this format:

typeText(command, modifierKeys); 

The commands are read in my case as json like this:

const char* command = rectangle["button"]["command"].as<const char*>();
JsonArray modifiers = rectangle["button"]["modifiers"].as<JsonArray>();

    std::vector<uint8_t> modifierKeys;
 
   // Convert modifiers to keys
    for (JsonVariant modifier : modifiers) {
      const char* modifierStr = modifier.as<const char*>();
      if (strcmp(modifierStr, "KEY_CTRL") == 0) {
        modifierKeys.push_back(KEY_CTRL);
      } else if (strcmp(modifierStr, "KEY_SHIFT") == 0) {
        modifierKeys.push_back(KEY_SHIFT);
      } else if (strcmp(modifierStr, "KEY_ALT") == 0) {
        modifierKeys.push_back(KEY_ALT);
      }

And the typetext function with modifiers looks like this:

void typeText(const char* text, const std::vector<uint8_t>& modifierKeys) {
    int len = strlen(text);
    for (int i = 0; i < len; i++) {
        // Translate character to key combination
        uint8_t val = (uint8_t)text[i];
        if (val > KEYMAP_SIZE)
            continue; // Character not available on keyboard - skip
        KEYMAP map = keymap[val];

        // Apply modifier keys
        uint8_t modifier = 0;
        for (uint8_t mod : modifierKeys) {
            modifier |= mod;
        }
        map.modifier |= modifier;

        // Create input report
        InputReport report = {
            .modifiers = map.modifier,
            .reserved = 0,
            .pressedKeys = {
                map.usage,
                0, 0, 0, 0, 0
            }
        };

        // Send the input report
        input->setValue((uint8_t*)&report, sizeof(report));
        input->notify();

        delay(5);

        // Release all keys between two characters; otherwise, two identical
        // consecutive characters are treated as just one key press
        input->setValue((uint8_t*)&NO_KEY_PRESSED, sizeof(NO_KEY_PRESSED));
        input->notify();

        delay(5);
    }
}

This allows to read in commands with variable modifiers.
Thank you for your elegant code! I would also like to publish my project on github and I would add your license. Could I do so?
All the Best!

@manuelbl
Copy link
Author

manuelbl commented Jul 3, 2023

You are welcome to publish the modified code on GitHub. 😄

@ctc-nick
Copy link

ctc-nick commented Jul 4, 2023

Thank you, very nice!! This is indeed a very 'modified' recipe. 🍲 😄

@richstokes
Copy link

Anyone know if there is a way to send arrow key presses with this?

@manuelbl
Copy link
Author

manuelbl commented Oct 4, 2023

Yes, you can do it with something like this:

#define KEY_SYSRQ 0x46 // Keyboard Print Screen
#define KEY_SCROLLLOCK 0x47 // Keyboard Scroll Lock
#define KEY_PAUSE 0x48 // Keyboard Pause
#define KEY_INSERT 0x49 // Keyboard Insert
#define KEY_HOME 0x4a // Keyboard Home
#define KEY_PAGEUP 0x4b // Keyboard Page Up
#define KEY_DELETE 0x4c // Keyboard Delete Forward
#define KEY_END 0x4d // Keyboard End
#define KEY_PAGEDOWN 0x4e // Keyboard Page Down
#define KEY_RIGHT 0x4f // Keyboard Right Arrow
#define KEY_LEFT 0x50 // Keyboard Left Arrow
#define KEY_DOWN 0x51 // Keyboard Down Arrow
#define KEY_UP 0x52 // Keyboard Up Arrow

void sendKeyCode(uint8_t keyCode) {
    // create input report
    InputReport report = {
        .modifiers = 0,
        .reserved = 0,
        .pressedKeys = { keyCode, 0, 0, 0, 0, 0 }
    };

    // send the input report
    input->setValue((uint8_t*)&report, sizeof(report));
    input->notify();
    delay(5);

    // release all keys
    input->setValue((uint8_t*)&NO_KEY_PRESSED, sizeof(NO_KEY_PRESSED));
    input->notify();
    delay(5);
}

sendKeyCode(KEY_DOWN);

@Dreamcazman
Copy link

Dreamcazman commented Oct 14, 2023

Hi, thank you for this. I want to build myself a simple button board (using a Lolin32 lite board) to use with PC emulation, maybe with directional buttons and others which utilise the 'special keys' like escape, space bar, enter and the arrow keys.

I have tried editing your code but I can't seem to get it to compile properly. I am a noob so I'm hoping you can assist. How do I activate the special keys with a button press (GPIO pin to ground), specifically what to enter in this part of the code:

// Change the below values if desired
#define BUTTON_PIN 2
#define MESSAGE "Hello from ESP32\n"
#define DEVICE_NAME "ESP32 Keyboard"

Can I change this to, for example:

#define Up 32
#define KEY_UP 0x52
#define Down 33
#define KEY_DOWN 0x51

and so on...

I am also not sure about this area:

if (isBleConnected && digitalRead(BUTTON_PIN) == LOW) {
// button has been pressed: type message
Serial.println(MESSAGE);
typeText(MESSAGE);

I'm not typing a key like any of the letter keys so I don't know how to change these areas so the up arrow key is triggered (for this example).

Any help would be greatly appreciated.

btw, I have tried the BLEkeyboard and couldn't get it to work at all, no output from any button presses.

@legitlee
Copy link

legitlee commented Oct 14, 2023 via email

@richstokes
Copy link

Thanks @manuelbl - works great :)

@Dreamcazman
Copy link

hello I'm not sure of what problem you are having but if you need help with the coding I would say that you might want to find someone who can help off of the website called fiverr when I have trouble with my coding I would always go to that website to find someone who can help me so you can try there

I think I explained my problem above well enough, who better to ask than the author. @manuelbl, can you assist please?

I want the Arduino to send a 'special key' (eg ESCAPE) when I press a button and not type ESCAPE instead, I hope that makes sense.

@legitlee
Copy link

legitlee commented Oct 15, 2023 via email

@manuelbl
Copy link
Author

@Dreamcazman If you want to send special keys, use the code at the beginning of this thread and combine it with the code for the special keys (see this post).

Then you need to modify loop(). The original code sends an entire string whenever the button is pressed (and Bluetooth is connected). It needs to be replaced with testing for your buttons and sending the correct key code. Assuming that Up and Down are the Arduino GPIO numbers for your buttons, the code will look something like this:

void loop() {  
    if (isBleConnected) {
        if (digitalRead(Up) == LOW) {
            sendKeyCode(KEY_UP);
        } else if (digitalRead(Down) == LOW) {
            sendKeyCode(KEY_DOWN);
        }
    }
    delay(50);
}

@Dreamcazman
Copy link

Dreamcazman commented Oct 15, 2023

@Dreamcazman If you want to send special keys, use the code at the beginning of this thread and combine it with the code for the special keys (see this post).

Then you need to modify loop(). The original code sends an entire string whenever the button is pressed (and Bluetooth is connected). It needs to be replaced with testing for your buttons and sending the correct key code. Assuming that Up and Down are the Arduino GPIO numbers for your buttons, the code will look something like this:

void loop() {  
    if (isBleConnected) {
        if (digitalRead(Up) == LOW) {
            sendKeyCode(KEY_UP);
        } else if (digitalRead(Down) == LOW) {
            sendKeyCode(KEY_DOWN);
        }
    }
    delay(50);
}

Thanks, however after seemingly getting nowhere I scrapped what I was doing, reinstalled and redownloaded the libraries. I found an adaptation of the BLEkeyboard code and actually got it working. It already had some keys set up, but after a lot of trial and error I realised I could use some decimal codes for the special keys.

Also added some debounce code

See my code below, it may help someone else out too.

#define USE_NIMBLE
#include <BleKeyboard.h>

BleKeyboard bleKeyboard;

#define Up 26
#define Down 27
#define Left 14
#define Right 12
#define Coin 13
#define Start 15
#define Spacebar 2
#define Enter 0
#define Escape 4

bool keyStates[9] = {false, false, false, false, false, false, false, false, false};
int keyPins[9] = {Up, Down, Left, Right, Coin, Start, Spacebar, Enter, Escape};
uint8_t keyCodes[9] = {(218), (217), (216), (215), '5', '1', (180), (176), (177)};


void setup() {
  Serial.begin(115200);
  Serial.println("Code running...");
  setInputs();
  bleKeyboard.begin();
}

bool connectNotificationSent = false;

void loop() {
  int counter;
  if(bleKeyboard.isConnected()) {
    if (!connectNotificationSent) {
      Serial.println("Code connected...");
      connectNotificationSent = true;
    }
    for(counter = 0; counter < 9; counter ++){
      handleButton(counter);
    }
  }
}

void setInputs() {
    pinMode(Up, INPUT_PULLUP);
    pinMode(Down, INPUT_PULLUP);
    pinMode(Left, INPUT_PULLUP);
    pinMode(Right, INPUT_PULLUP);
    pinMode(Coin, INPUT_PULLUP);
    pinMode(Start, INPUT_PULLUP);
    pinMode(Spacebar, INPUT_PULLUP);
    pinMode(Enter, INPUT_PULLUP);
    pinMode(Escape, INPUT_PULLUP);
}

unsigned long debounceButtons[9];
int intervalDebounce = 50;

void handleButton(int keyIndex){
  // handle the button press
 if (millis()- debounceButtons[keyIndex]>=intervalDebounce){ 
  if (!digitalRead(keyPins[keyIndex])){
    // button pressed
    if (!keyStates[keyIndex]){
      debounceButtons[keyIndex]= millis();
      // key not currently pressed
      keyStates[keyIndex] = true;
      bleKeyboard.press(keyCodes[keyIndex]);
    }
  }
  else {
    // button not pressed
    if (keyStates[keyIndex]){
      debounceButtons[keyIndex]= millis();
      // key currently pressed
      keyStates[keyIndex] = false;
      bleKeyboard.release(keyCodes[keyIndex]);
    }
  }
}
} 

@legitlee
Copy link

legitlee commented Oct 15, 2023 via email

@simplyrohan
Copy link

Are there any parts I can cut out to make the program size smaller? I don't have a lot of memory, and this uses up a lot of it. I don't need any special characters, numbers, or control keys. Just the basic, English, character set. I have a rough idea of how to do this, but I'm not sure... Thanks for any help, and this is a great example code!

@Dreamcazman
Copy link

Dreamcazman commented Dec 3, 2023

Are there any parts I can cut out to make the program size smaller? I don't have a lot of memory, and this uses up a lot of it. I don't need any special characters, numbers, or control keys. Just the basic, English, character set. I have a rough idea of how to do this, but I'm not sure... Thanks for any help, and this is a great example code!

I'm not sure, it's already fairly compact as it uses Nimble. You may be able to reduce the number of inputs or the debounce code could be removed but without it can cause phantom or unwanted button presses.

Other than that, maybe invest in an Arduino device with more available memory.

@simplyrohan
Copy link

simplyrohan commented Dec 3, 2023

You may be able to reduce the number of inputs

Any idea how I would do this? I see the InputReport struct and REPORT_MAP array, but I'm not sure what I would need to change...

@Dreamcazman
Copy link

Any idea how I would do this? I see the InputReport struct and REPORT_MAP array, but I'm not sure what I would need to change...

For example, if you want to remove the 'Spacebar' input, remove the following:

'#define Spacebar 2' and 'pinMode(Spacebar, INPUT_PULLUP);' lines

This part, remove one of the 'false' entries so there are only eight left, then remove 'Spacebar', it's corresponding key code and change the number from 9 to 8, so it looks like this:

bool keyStates[8] = {false, false, false, false, false, false, false, false};
int keyPins[8] = {Up, Down, Left, Right, Coin, Start, Enter, Escape};
uint8_t keyCodes[8] = {(218), (217), (216), (215), '5', '1', (176), (177)};

Then any other place in the code where it mentions '9' (like above), change it to how many inputs there are, ie. it's now 8.

Hope that makes sense.

@legitlee
Copy link

legitlee commented Dec 3, 2023 via email

@manuelbl
Copy link
Author

manuelbl commented Dec 3, 2023

@simplyrohan The code on this page is quite small. I doubt that any optimizations will make a relevant difference.

The major contributor to the code and RAM size is Bluetooth itself. It's a non-trivial protocol. The moment a single Bluetooth function is used, a large library is pulled in.

So if you need to shrink the code, focus on the Bluetooth library:

  • ESP-NimBLE is supposedly smaller than ESP-Bluedroid
  • Test if certain configuration options reduce flash and memory size, e.g. by turning of unnecessary features (e.g. no central role, reduced logging to get rid of logging messages in the code)

@sundarv74
Copy link

Hello,
Can we connect to two Android phones at the same time and send keys to both from the ESP32? May I request what modifications are needed and any possible code sample for the purpose?
Regards, Sundar.

@TechRelief
Copy link

Trying to make it work with an Espressif ESP32-S3-USB-OTG board it connects to bluetooth (windows 10) and responds when a button is pressed on the board and reaches the typeText() function which does its thing, but there is no ouput at all.
I put a Serial.print() statement to monitor what it is trying to output and for a typeText("abc") it outputs "456", but I am confused about the fact it has references to input->setValue should it not Output? Any thoughts?
Also where is the best way to read up on what it is actually trying to send (i.e. via bluetooth so I can perhaps try to debug this?

@TechRelief
Copy link

Ok so I seem to finally have it working; but I do not know why exactly but I did have to create a new board definition for ESP32-S3-USB-OTG and PlatformIO does not publish what the settings in the board JSON file are for, they tell you to look at existing board definitions for clues. So I copied some settings from other ESP32-S3 boards and somehow it started to work. I do have a question though:
At the end of the bluetoothTask() function it has: delay(portMAX_DELAY);
How does this work exactly? portMAX_DELAY is an unsigned 0xFFFFFFFF value which equates to a delay of 49 days in milliseconds? Is this a kludge to halt code execution here? If anyone knows please enlighten me, thanks...

@wvsbsp
Copy link

wvsbsp commented Dec 17, 2023

Works like a charm! Many thanks! I've been watching this project for a while.
Now i need a bit of hardware to scroll in a PDF file while playing an instrument. I needed only 3 control-keys KEY_PAGE_UP, KEY_PAGE_DOWN and KEY_F11. The longest it took me to find the names for the control keys. It would be a good idea to insert a link in the comment to
~\Arduino15\packages\esp32\hardware\esp32\2.0.14\libraries\BLE\src\HIDKeyboardTypes.h
That's all i had to program: ;-)
`bool bTaster0, bTaster2, bTaster4, oldTaster0, oldTaster2, oldTaster4;
void loop() {
bTaster0 = digitalRead(Taster0);
bTaster2 = digitalRead(Taster2);
bTaster4 = digitalRead(Taster4);

if (isBleConnected && bTaster2 == false && oldTaster2 == true) {
// button has been pressed: type message
//Serial.println(MESSAGE);
//typeText(MESSAGE);
char NewMessage[] = { KEY_PAGE_UP, 0 };
typeText(NewMessage);
}
if (isBleConnected && bTaster4 == false && oldTaster4 == true) {
// button has been pressed: type message
char NewMessage[] = { KEY_PAGE_DOWN, 0 };
typeText(NewMessage);
}
if (isBleConnected && bTaster0 == false && oldTaster0 == true) {
// button has been pressed: type message
char NewMessage[] = { KEY_F11, 0 };
typeText(NewMessage);
}
oldTaster0 = bTaster0;
oldTaster2 = bTaster2;
oldTaster4 = bTaster4;

delay(100);
}`

@HectorFraguas
Copy link

I'm trying to connect it with an Android device and it connects correctly but I can't get the volume up and volume down keys to work, has anyone got something like that?

@arvebjoe
Copy link

arvebjoe commented Mar 5, 2024

I can't get the media play/pause keys to work. Other keys like arrow up or down work fine. I've tried 0x48 (KEY_PAUSE) and 0xB3 (after searching online). Any suggestions?

Example:
sendKeyCode(KEY_PAUSE); // doesn't work
sendKeyCode(0xB3); // doesn't work
sendKeyCode(KEY_DOWN); // works fine

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment