ESP32-BLE-Keyboard
ESP32-BLE-Keyboard copied to clipboard
How to add a unique serial number to the BLEKeyboard Device Name?
I would like the BLE Keyboard to display a unique name when pairing by adding a serial number.
If I have multiple BLE keyboards paired, I need to be able to tell the difference between each one. Is there a unique MAC address or something in the code I can add to the command line below?
// Define the Display name of the BLE Device BleKeyboard bleKeyboard("Bluetooth Device Name + (4-Digit) Serial Number" , "Company name",100);
Normally, I would simply generate a random number and add it to the name value, however, this command line must be executed above the "setup" section in Arduino and I am unable run that code in that section.
Also, I am unable to run the above command line within any other section in Arduino.
So, I am hoping there is an existing unique ID number somewhere in the code that I can use?
I use this function in my code that reads the MAC address of the ESP32 device.
// populates the deviceName char with the device Prefix plus a "unique" 4 char code
void getDeviceName(char* deviceName, char* devicePrefix) {
uint64_t chipid = ESP.getEfuseMac();
uint16_t shortid = chipid >> 32;
char sprintfString[20] = "";
strcat(sprintfString, devicePrefix);
strcat(sprintfString, " %04X");
sprintf(deviceName, sprintfString, shortid);
}
and call it like this:
// derive a unique name
char deviceName[20];
getDeviceName(deviceName, "Device Name");
bleKeyboard.setName(deviceName);
@T-vK suggest this can be closed now
I tried webmonkey's solution, and the unique name part does work nicely.
However, the part that is supposed to set the device name
bleKeyboard.setName(deviceName);
does not work. I used it in the last line of "void setup()"
The name of the device stays as defined in the
BleKeyboard bleKeyboard("Macro_kbd_SN0CX","ESP32 DEVKIT V1", 98);
You need to set the device name before the bleKeyboard.begin()
call.
Are you able to share the code you're using?
Thanks! That actually did the trick!
Here is the section in the working version in the "void setup()": ` // Apply name based on MAC
char deviceName[20];
getDeviceName(deviceName, "Macro_kbd");
bleKeyboard.setName(deviceName);
bleKeyboard.begin();`
As for the code, it is a bit long, but here: https://github.com/ekoslav/ESP32_Password_keyboard/tree/main/ESP32_4x4MatKBD_SPIFS
Hello ekoslav,
Thank you very much for the help, I have it running on my application and it is working well, except it does not seem to show up anymore on Apple iPad or iPhone as an available Bluetooth device now.
It does show up on Android, Windows 8, and Windows 10 systems for some reason.
Does this work for you on iOS devices? Maybe my device name is too long now? It adds up to 16 characters. Here is the Bluetooth device name on Android and Windows "9xx_BLE_v1.0_B087"
Here is all the code:
//////////////////////////////////////////////////////////////////////////////////// #include <BleKeyboard.h>
// Define the Display name of the BLE Device BleKeyboard bleKeyboard("9xx_BLE_v1.0","Company Name",100);
// populates the deviceName char with the device Prefix plus a "unique" 4 char code void getDeviceName(char* deviceName, char* devicePrefix) { uint64_t chipid = ESP.getEfuseMac(); uint16_t shortid = chipid >> 32; char sprintfString[20] = ""; strcat(sprintfString, devicePrefix); strcat(sprintfString, " %04X");
sprintf(deviceName, sprintfString, shortid);
}
////////////////////////////////////////////////////////////////////////////////////
void setup() { Serial.begin(115200); ////////////////////////////////////////////////////////////////////////////////////
char deviceName[20]; getDeviceName(deviceName, "9xx_BLE_1.0_"); bleKeyboard.setName(deviceName);
bleKeyboard.begin(); // Wait to Initialize delay(2000);
////////////////////////////////////////////////////////////////////////////////////
// END OF SETUP
////////////////////////////////////////////////////////////////////////////////////
Note: I left this statement in the code because of the "Manufacturer Name and delay value
// Define the Display name of the BLE Device BleKeyboard bleKeyboard("9xx_BLE_v1.0","Company Name",100);
Maybe this statement overrides the previous statement and leaving off the Manufacturer name is the problem? bleKeyboard.setName(deviceName);
Is there a way add the manufacturer name and delay value? I am almost 100% sure that this is the issue
CONFIRMED: Ok the following code works on all operating systems. I commented out the new code after SETUP and now the device name shows up on all operating systems
I believe that iOS must require the manufacturer name and Windows does not. I also believe that the bleKeyboard.setName(deviceName); must be over-writing the manufacturers name.
#include <BleKeyboard.h> // Define the Display name of the BLE Device BleKeyboard bleKeyboard("9xx_BLE_v1.0","Company Name",100);
// char deviceName[20]; // getDeviceName(deviceName, "9xx_BLE_1.0_"); // bleKeyboard.setName(deviceName);
bleKeyboard.begin();
Looks like you have answered your own question while I was writing the reply. I tested my code on following: It does work for me on iPhone 6. On Android 11 (Redmi Note 8 Pro), it is visible and connects, however does not produce keystrokes. On Android 10 (Teclast P20HD), it is visible and connects, however does not produce keystrokes. On Android 4.4 it does work. Android 6 (Sony XA1) works. On all windows desktops it does work.
Is there a way to set the manufacturer name ? If I lave my code as is, everything works..
#include <BleKeyboard.h> // Define the Display name of the BLE Device BleKeyboard bleKeyboard("9xx_BLE_v1.0","Company Name",100);
The iPhone 11 I am testing with does not display the BLE keyboard without the manufacturer name.
In my testing, the only statement that works on all Apple iOS devices is the following:
#include <BleKeyboard.h> // Define the Display name of the BLE Device BleKeyboard bleKeyboard("BLE_KB_1.0","Company Name",100);
void setup() { bleKeyboard.begin(); { void loop() { {
This only works in the section above the setup section. I am not sure how to use a variable string instead of fixed text.
String product_name_string = "BLE_KB_1.0"; BleKeyboard bleKeyboard( product_name_string, "Company Name" ,100);
The serial number MAC address code works GREAT, except I have not found a way to replace the FIXED text "BLE_KB_1.0" with a string variable that contains the auto-generated MAC address.
HELP ?!?!?!
-
The device name must not exceed 15 characters in length. The constructor has code in place to trim the given name down to the first 15 characters, even if a longer name was specified. For the setName method unfortunately it was forgotton to do the same, so you have to make sure youself that you don't provide a name that's too long otherwise Apple devices will struggle. A MAC address is pretty long. Since the first 6 digits of a MAC address hold the vendor information and thus are not unique and probably the same for all ESPs anyway, I would advice to only use the last 6 digits.
-
Make sure to call begin() after setName().
Hello T-vk, Thank you for the assistance. The setName() function works GREAT !!!
I am able to implement it with the "setup" section and generate a unique Bluetooth name for each device.
I ran tests and the length of the name is not causing the problem with the Bluetooth device failing to show up on Apple iOS host devices.
I have confirmed that the Apple iOS host devices are requiring a manufacturer name of some kind before they allow the Bluetooth device to show up on the list of available device to connect to.
The function I have been using includes the manufacturer name but it can only be run before the "setup" section for some reason.. (see Below) BleKeyboard bleKeyboard( product_name_string, "Company Name" ,100);
This function assigns a Bluetooth product name, a manufacturer name, and also the battery level).
Question # 1: Is there a way to modify the library function for this function so it can be run within the "setup" section just like the setName() function does ???
Question # 2: If not, is there another function that can assign the "manufacturer" name ?
Question # 3: Is there another function that can assign and update the current battery level?
If this function can be modified to run with the "setup" section, then I can easily use variables to get the MAC address and assign the product name along with the manufacturer name and finally be able to update the battery level on the wireless keyboard.
I am hoping to resolve this issue and help other users in he future who will run into the same problems.
For the battery level there is another function documented in the Readme. There is no other way to set the manufacturer name at the moment. You'd have to implement a new method for that on the class. If you set the manufacturer name in the constructor as you have shown, it should persist, even after calling setName.