T-vK / ESP32-BLE-Keyboard

Bluetooth LE Keyboard library for the ESP32 (Arduino IDE compatible)
2.4k stars 399 forks source link

Is there an issue using this library and example with ESP32-S3 boards? #239

Open en-x opened 1 year ago

en-x commented 1 year ago

Hello,

I am relatively new to Arduino and ESP32, but I do have a programming background. I have built serval projects and am now interested in building something using this BLE Keyboard Library. Thinking this was going to be easy...

I downloaded this library and uploaded the SendKeyStrokes code to my an ESP32-S3 board (I have actually tried several different models, Seeed Xiao, LilyGO, TinyS3, M5StampS3) and none of the S3 board seem to work. I can see the the board in my Bluetooth list on IOS 16.5, I can pair the device, and then immediately get the following in the Serial Monitor...

E (33843) BT_GATT: GATT_INSUF_AUTHENTICATION

E (35434) BT_SMP: smp_calculate_link_key_from_long_term_key failed to update link_key. Sec Mode = 2, sm4 = 0x00 E (35435) BT_SMP: smp_derive_link_key_from_long_term_key failed

E (35440) BT_BTM: btm_proc_smp_cback received for unknown device E (35445) BT_BTM: BTM_GetSecurityFlags false

E (35449) BT_GATT: GATT_INSUF_AUTHENTICATION

E (35493) BT_BTM: BTM_GetSecurityFlags false

E (35493) BT_GATT: GATT_INSUF_AUTHENTICATION

E (35553) BT_BTM: BTM_GetSecurityFlags false

E (35553) BT_GATT: GATT_INSUF_AUTHENTICATION

E (36783) BT_BTM: BTM_GetSecurityFlags false

E (37803) BT_BTM: BTM_GetSecurityFlags false

If I do they exact same steps using an ESP32-32D board it works perfectly and the keystrokes are sent to the phone. I am I doing something wrong with the S3 or is there a compatibly issue. I searched these messages above and cannot seem to find any solutions. I also tried a Seeed Xiao EPS32-C3 and that did not work either. I think I am just missing a step or something related to the S3 boards.

Any help would be greatly appreciated. Thank you. Eric.

TenViki commented 1 year ago

I had the same issue. You just need to enable NimBLE mode, you can do that just by adding

#define USE_NIMBLE

on top of your main.cpp file.

Let me know if that helped!

en-x commented 1 year ago

I was able to resolve my issue… Edit file “BleKeyboard.cpp"

Find line: pSecurity->setAuthenticationMode(ESP_LE_AUTH_REQ_SC_MITM_BOND);

Replace the above line to the following: pSecurity->setAuthenticationMode(ESP_LE_AUTH_BOND);

en-x commented 1 year ago

I had the same issue. You just need to enable NimBLE mode, you can do that just by adding

#define USE_NIMBLE

on top of your main.cpp file.

Let me know if that helped!

Thanks! I fixed it… see below

lubaldi commented 1 year ago

i have a similar issue, both with USE_NIMBLE and not:

in 1st connection all works well, but if i shut down bluetooth, or switch-off Esp32, once I turn it back on, Smartphone deletes the Esp32 from the list of Pairede device and i've to reseach it and reconnect manually. Has this ever happened to anyone?

lightninlex commented 10 months ago

I am trying to use this library to turn my esp32-s3-n8r8 devkit C-1 into a controller for Retro Pie. I've set up a breakout board with the pin definitions from below, for buttons arranged like an SNES controller. I'm not quite sure this issue, but my esp32 keeps connecting and disconnecting at a rapid rate, and I can't get anything out of it besides the error code at the bottom of my comment. PLEASE HELP :(

include

define USE_NIMBLE

BleKeyboard bleKeyboard("GameBoxControl");

// Define debounce delay in milliseconds const long debounceDelay = 50; // 50 ms debounce delay

// Variables to store the last time the button was toggled unsigned long lastDebounceTime_A = 0; unsigned long lastDebounceTime_B = 0; unsigned long lastDebounceTime_X = 0; unsigned long lastDebounceTime_Y = 0; unsigned long lastDebounceTime_START = 0; unsigned long lastDebounceTime_SELECT = 0; unsigned long lastDebounceTime_L = 0; unsigned long lastDebounceTime_R = 0; unsigned long lastDebounceTime_SW = 0; // Variables to store the last button states int lastButtonState_A = HIGH; int lastButtonState_B = HIGH; int lastButtonState_X = HIGH; int lastButtonState_Y = HIGH; int lastButtonState_START = HIGH; int lastButtonState_SELECT = HIGH; int lastButtonState_L = HIGH; int lastButtonState_R = HIGH; int lastButtonState_SW = HIGH; // Define button pins const uint8_t PIN_BUTTON_A = 8; const uint8_t PIN_BUTTON_B = 46; const uint8_t PIN_BUTTON_X = 10; const uint8_t PIN_BUTTON_Y = 12; const uint8_t PIN_BUTTON_L = 13; const uint8_t PIN_BUTTON_R = 14; const uint8_t PIN_BUTTON_START = 1; const uint8_t PIN_BUTTON_SELECT = 2;

// Define joystick pins const uint8_t PIN_JOYSTICK_VRX = 4; const uint8_t PIN_JOYSTICK_VRY = 6; const uint8_t PIN_BUTTON_SW = 15;

// Define the deadzone range const int deadzone = 30; // Adjust the deadzone value to suit your needs

// Function to apply deadzone to a joystick value int applyDeadzone(int value, int centerValue, int deadzone) { if (abs(value - centerValue) < deadzone) { return centerValue; } else { return value; } }

// Function to read inputs and send key strokes void readInputsAndSendKeystrokes() { unsigned long currentTime = millis();

// Read and debounce each button // Example for Button A: int reading_A = digitalRead(PIN_BUTTON_A); if (reading_A != lastButtonState_A) { lastDebounceTime_A = currentTime; } if ((currentTime - lastDebounceTime_A) > debounceDelay) { if (reading_A == LOW) { bleKeyboard.press('a'); // Replace 'a' with your desired key for Button A } else { bleKeyboard.release('a'); } lastButtonState_A = reading_A; } // Button B read and debounce int reading_B = digitalRead(PIN_BUTTON_B); if (reading_B!= lastButtonState_B) { lastDebounceTime_B = currentTime; } if ((currentTime - lastDebounceTime_B) > debounceDelay) { if (reading_B == LOW) { bleKeyboard.press('b'); // Replace 'a' with your desired key for Button A } else { bleKeyboard.release('b'); } lastButtonState_B = reading_B; } // Button X read and debounce int reading_X = digitalRead(PIN_BUTTON_X); if (reading_X!= lastButtonState_X) { lastDebounceTime_X = currentTime; } if ((currentTime - lastDebounceTime_X) > debounceDelay) { if (reading_X == LOW) { bleKeyboard.press('x'); // Replace 'a' with your desired key for Button A } else { bleKeyboard.release('x'); } lastButtonState_X = reading_X; } // Button Y read and debounce int reading_Y = digitalRead(PIN_BUTTON_Y); if (reading_Y!= lastButtonState_Y) { lastDebounceTime_Y = currentTime; } if ((currentTime - lastDebounceTime_Y) > debounceDelay) { if (reading_Y == LOW) { bleKeyboard.press('y'); // Replace 'a' with your desired key for Button A } else { bleKeyboard.release('y'); } lastButtonState_Y = reading_Y; } // Button START read and debounce int reading_START = digitalRead(PIN_BUTTON_START); if (reading_START!= lastButtonState_START) { lastDebounceTime_START = currentTime; } if ((currentTime - lastDebounceTime_START) > debounceDelay) { if (reading_START == LOW) { bleKeyboard.press('z'); // Replace 'a' with your desired key for Button A } else { bleKeyboard.release('z'); } lastButtonState_START = reading_START; } // Button SELECT read and debounce int reading_SELECT = digitalRead(PIN_BUTTON_SELECT); if (reading_SELECT!= lastButtonState_SELECT) { lastDebounceTime_SELECT = currentTime; } if ((currentTime - lastDebounceTime_SELECT) > debounceDelay) { if (reading_SELECT == LOW) { bleKeyboard.press('c'); // Replace 'a' with your desired key for Button A } else { bleKeyboard.release('c'); } lastButtonState_SELECT = reading_SELECT; } // Button L read and debounce int reading_L = digitalRead(PIN_BUTTON_L); if (reading_L!= lastButtonState_L) { lastDebounceTime_L = currentTime; } if ((currentTime - lastDebounceTime_L) > debounceDelay) { if (reading_L == LOW) { bleKeyboard.press('l'); // Replace 'a' with your desired key for Button A } else { bleKeyboard.release('l'); } lastButtonState_L = reading_L; } // Button R read and debounce int reading_R = digitalRead(PIN_BUTTON_R); if (reading_R!= lastButtonState_R) { lastDebounceTime_R = currentTime; } if ((currentTime - lastDebounceTime_R) > debounceDelay) { if (reading_R == LOW) { bleKeyboard.press('r'); // Replace 'a' with your desired key for Button A } else { bleKeyboard.release('r'); } lastButtonState_R = reading_R; } // Button SW read and debounce int reading_SW = digitalRead(PIN_BUTTON_SW); if (reading_SW!= lastButtonState_SW) { lastDebounceTime_SW = currentTime; } if ((currentTime - lastDebounceTime_SW) > debounceDelay) { if (reading_SW == LOW) { bleKeyboard.press('v'); // Replace 'a' with your desired key for Button A } else { bleKeyboard.release('v'); } lastButtonState_SW = reading_SW; }

// Read joystick values int xValue = analogRead(PIN_JOYSTICK_VRX); int yValue = analogRead(PIN_JOYSTICK_VRY);

// Apply deadzone xValue = applyDeadzone(xValue, 2047, deadzone); yValue = applyDeadzone(yValue, 2047, deadzone);

// Joystick X-axis mapping if (xValue > 2047 + deadzone) { bleKeyboard.press(KEY_RIGHT_ARROW); // Right } else if (xValue < 2047 - deadzone) { bleKeyboard.press(KEY_LEFT_ARROW); // Left } else { bleKeyboard.release(KEY_RIGHT_ARROW); bleKeyboard.release(KEY_LEFT_ARROW); }

// Joystick Y-axis mapping if (yValue > 2047 + (deadzone + 35)) { bleKeyboard.press(KEY_UP_ARROW); // Up } else if (yValue < 2047 - (deadzone - 35)) { bleKeyboard.press(KEY_DOWN_ARROW); // Down } else { bleKeyboard.release(KEY_UP_ARROW); bleKeyboard.release(KEY_DOWN_ARROW); } }

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

// Initialize button pins as inputs pinMode(PIN_BUTTON_A, INPUT_PULLUP); pinMode(PIN_BUTTON_B, INPUT_PULLUP); pinMode(PIN_BUTTON_X, INPUT_PULLUP); pinMode(PIN_BUTTON_Y, INPUT_PULLUP); pinMode(PIN_BUTTON_L, INPUT_PULLUP); pinMode(PIN_BUTTON_R, INPUT_PULLUP); pinMode(PIN_BUTTON_START, INPUT_PULLUP); pinMode(PIN_BUTTON_SELECT, INPUT_PULLUP);

// Initialize joystick pins as inputs pinMode(PIN_JOYSTICK_VRX, INPUT); pinMode(PIN_JOYSTICK_VRY, INPUT); pinMode(PIN_BUTTON_SW, INPUT_PULLUP); }

void loop() { if (bleKeyboard.isConnected()) { readInputsAndSendKeystrokes(); } delay(100); // Delay to manage the loop execution speed }

[SERIAL LOG] Starting BLE work! E (51807) BT_APPL: Unknown connection ID: 3 fail sending notification E (51808) BT_APPL: Unknown connection ID: 3 fail sending notification E (51814) BT_APPL: Unknown connection ID: 3 fail sending notification E (51821) BT_APPL: Unknown connection ID: 3 fail sending notification E (51827) BT_APPL: Unknown connection ID: 3 fail sending notification E (51833) BT_APPL: Unknown connection ID: 3 fail sending notification E (51839) BT_APPL: Unknown connection ID: 3 fail sending notification E (51845) BT_APPL: Unknown connection ID: 3 fail sending notification E (52227) BT_APPL: Unknown connection ID: 3 fail sending notification