It is strange that the Dmitry has not yet made this correction. After all, without it, media buttons do not work at all. ![]()
I am a little lost, so this allows me to use an ESP for as virtual Bluetooth keyboard for devices? (Similar to how the Logitech remotes did?)
Also, can I switch between multiple devices, or would I need a separate ESP for each one? I have a Shield, Android TV and PC for example, can I switch between each device?
Iâve run out of ESPs, so working out how many more I need to order
Thanks ![]()
Hi,
I am having the following problem:
After the ipad connects to the esp32 bluetooth, every time I restart the esp32, the ipad cannot automatically reconnect to the esp32 via bluetooth. On Android phones I donât have this problem. Currently I have not found out the cause of the problem
This is cool for sure and much appreciated. Maybe its just me and a lack of imagination but, im struggling to think of any reasons to need a keyboard. Sure, you can find a use for controlling the volume on something or a few keys to toggle this or that but a full size keyboard seems overkill for those things. What am i missing or not thinking of here?
Iâm having this same compile problem with EspHome 2024.3.0
Any ideas?
Compiling .pioenvs/esp-keyboard-wake/lib3d0/ESP32 BLE Arduino/BLEAdvertising.cpp.o
In file included from .piolibdeps/esp-keyboard-wake/ESP32 BLE Arduino/src/BLECharacteristic.h:19,
from .piolibdeps/esp-keyboard-wake/ESP32 BLE Arduino/src/BLEDescriptor.h:14,
from .piolibdeps/esp-keyboard-wake/ESP32 BLE Arduino/src/BLE2902.h:13,
from .piolibdeps/esp-keyboard-wake/ESP32 BLE Arduino/src/BLE2902.cpp:15:
.piolibdeps/esp-keyboard-wake/ESP32 BLE Arduino/src/FreeRTOS.h:61:28: error: 'ringbuf_type_t' has not been declared
Ringbuffer(size_t length, ringbuf_type_t type = RINGBUF_TYPE_NOSPLIT);
^~~~~~~~~~~~~~
@Tomsdad did you ever resolve this? I am trying to use this and am getting the same error unfortunatelyâŚ
I never did. I fell back to the old solution that I had that uses this: https://github.com/clubcotton/esphome/blob/main/playground/esp32_ble_keyboard.h
I had the same issue. Managed to resolve the compilation by setting use_default_libs to false.
In the example provided in the documentation, in the last line, replace true with false.
ble_keyboard:
id: mamontech_keyboard
name: âMamonTechKeyboardâ
manufacturer_id: âMamonTechâ
battery_level: 50
reconnect: true
buttons: true
use_default_libs: false
Your change helped it get further, but now I get a new error:
Linking .pioenvs/esphome-web-c66cb0/firmware.elf
/config/.esphome/platformio/packages/toolchain-xtensa-esp32/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: .pioenvs/esphome-web-c66cb0/src/main.cpp.o:(.literal._Z5setupv+0x670): undefined reference to `vtable for esphome::esp32_ble_server::NimBLEServer'
/config/.esphome/platformio/packages/toolchain-xtensa-esp32/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: .pioenvs/esphome-web-c66cb0/src/main.cpp.o:(.literal._Z5setupv+0x674): undefined reference to `vtable for esphome::esp32_ble_server::NimBLEServer'
/config/.esphome/platformio/packages/toolchain-xtensa-esp32/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: .pioenvs/esphome-web-c66cb0/src/main.cpp.o:(.literal._Z5setupv+0x678): undefined reference to `vtable for esphome::esp32_ble_server::NimBLEServer'
collect2: error: ld returned 1 exit status
*** [.pioenvs/esphome-web-c66cb0/firmware.elf] Error 1
========================= [FAILED] Took 26.31 seconds =========================
Any ideas?
Did you replace or download the external component? For me it works like this (replace the substitutions with your own :)):
# BLE Keyboard project
# https://github.com/dmamontov/esphome-blekeyboard
############# User configuration #############
substitutions:
board: esp32-poe-iso #!! Include your own board
mdns_name: my_ble_kb
# Wifi credentials
wifi_ssid: !secret wifi_ssid
wifi_password: !secret wifi_password
# OTA and API
ota_password: "abcde"
api_password: "FulG0C3MsqsWr01isFywdnO7azeXU67qIVXtJHBz9js="
# Software configuration
input_text_entity_id: "input_text.blekeyboard_new_message" # A string object for entering arbitrary text.
########### End user configuration ###########
############# Base configuration #############
esphome:
name: $mdns_name
comment: "https://github.com/dmamontov/esphome-blekeyboard"
esp32:
board: $board
# Enable logging
logger:
# Enable OTA
ota:
password: $ota_password
platform: esphome
# Enable WiFi
wifi:
#fast_connect: on
ssid: $wifi_ssid
password: $wifi_password
# Enable Home Assistant API
api:
encryption:
key: $api_password
########### End base configuration ###########
# Enable components
external_components:
# - source:
# type: local
# path: ../components
- source: github://dmamontov/esphome-blekeyboard
ble_keyboard:
id: my_ble_keyboard
name: $mdns_name
manufacturer_id: "Apple"
reconnect: true
battery_level: 50
buttons: true
text_sensor:
- platform: homeassistant
id: input_text
entity_id: $input_text_entity_id
internal: true
sensor:
- platform: wifi_signal
name: "WiFi Signal"
update_interval: 60s
button:
- platform: restart
entity_category: "config"
name: "Restart"
- platform: template
name: "Release"
id: key_release
icon: "mdi:send"
on_press:
then:
- ble_keyboard.print:
id: my_ble_keyboard
text: !lambda "return id(input_text).state;"
- ble_keyboard.release: my_ble_keyboard
# - platform: template
# name: "Ctrl + A"
# id: key_ctrl_a
# icon: "mdi:vector-combine"
# on_press:
# then:
# - ble_keyboard.combination:
# id: my_ble_keyboard
# delay: 8
# keys:
# - 0x80
# - "a"
# - platform: template
# name: "Calc"
# id: key_calc
# icon: "mdi:calculator"
# on_press:
# then:
# - ble_keyboard.press:
# id: my_ble_keyboard
# code:
# - 0
# - 2
- platform: template
name: "_Start advertising"
id: start_advertising
icon: "mdi:bluetooth-connect"
on_press:
then:
- ble_keyboard.start: my_ble_keyboard
- platform: template
name: "_Stop advertising"
id: stop_advertising
icon: "mdi:bluetooth-off"
on_press:
then:
- ble_keyboard.stop: my_ble_keyboard
However I am experiencing a different issue. After the ESP restarted, it is not connected anymore. From the looks of this thread no one else experienced that. Is this an isolated issue on my device? Or am I missing some configuration?
For those having trouble with devices (particularly Apple devices) not reconnecting after the ESP32 restarts, Iâve pushed some changes which seems to resolve the issue for me: GitHub - zachdekoning/esphome-blekeyboard: ESPHome BLE Keyboard
From doing some research, it seems that Apple devices donât like the lack of security in the pairing process. The way around this is to set a proper pairing code, which seems to allow my iPad to properly reconnect when the ESP32 restarts.
You can try out these changes with the following:
external_components:
- source: github://zachdekoning/esphome-blekeyboard
ble_keyboard:
id: keyboard_id_here
name: "Keyboard name here"
...
use_default_libs: false # Must set this to false
pairing_code: 123456 # Six digit pairing code
Note that from ESPHome 2025.10+ onwards, you need to manually enable bluetooth in the framework sdkconfig_options or else it will fail to compile:
framework:
type: arduino
sdkconfig_options:
CONFIG_BT_ENABLED: "y"
Friends, I canât upload this config to the new builder. Everything worked fine two years ago, but now it doesnât. Please help me edit this if anyone sees an error.
Summary
- source: github://zachdekoning/esphome-blekeyboard
ble_keyboard:
id: esp32_bleKeyboard
name: "Esp32_BleKeybrd_02"
reconnect: true
buttons: true
use_default_libs: false
#pairing_code: 123456
globals:
- id: keyboard_enabled
type: bool
restore_value: no
initial_value: "false"
switch:
- platform: template
name: Enabled
icon: mdi:power
lambda: |-
if (id(keyboard_enabled)) {
return true;
} else {
return false;
}
turn_on_action:
- ble_keyboard.start: esp32_bleKeyboard
- lambda: |-
id(keyboard_enabled) = true;
turn_off_action:
- ble_keyboard.stop: esp32_bleKeyboard
- lambda: |-
id(keyboard_enabled) = false;
sensor:
- platform: wifi_signal
name: "WiFi Signal"
update_interval: 60s
button:
- platform: restart
entity_category: "config"
name: "Restart"
- platform: template
name: "Start advertising"
id: start_advertising
icon: "mdi:bluetooth"
on_press:
then:
- ble_keyboard.start: esp32_bleKeyboard
- platform: template
name: "Stop advertising"
id: stop_advertising
icon: "mdi:bluetooth-off"
on_press:
then:
- ble_keyboard.stop: esp32_bleKeyboard
- platform: template
name: "Next track"
id: next_track
icon: mdi:skip-next
on_press:
then:
- ble_keyboard.press:
id: esp32_bleKeyboard
code:
- 1
- 0
- delay: 100ms
- ble_keyboard.release: esp32_bleKeyboard
- platform: template
name: "previous track"
id: previous_track
icon: mdi:skip-previous
on_press:
then:
- ble_keyboard.press:
id: esp32_bleKeyboard
code:
- 2
- 0
- delay: 100ms
- ble_keyboard.release: esp32_bleKeyboard
- platform: template
name: "PlayâPause"
id: play_pause
icon: mdi:play-pause
on_press:
then:
- ble_keyboard.press:
id: esp32_bleKeyboard
code:
- 8
- 0
- delay: 100ms
- ble_keyboard.release: esp32_bleKeyboard
- platform: template
name: "Vol up"
id: KEY_MEDIA_VOLUME_UP
icon: mdi:volume-plus
on_press:
then:
- ble_keyboard.press:
id: esp32_bleKeyboard
code:
- 32
- 0
- delay: 100ms
- ble_keyboard.release: esp32_bleKeyboard
- platform: template
name: "Vol down"
id: KEY_MEDIA_VOLUME_DOWN
icon: mdi:volume-minus
on_press:
then:
- ble_keyboard.press:
id: esp32_bleKeyboard
code:
- 64
- 0
- delay: 100ms
- ble_keyboard.release: esp32_bleKeyboard
- platform: template
name: "Stop Play"
id: play_stop
icon: mdi:stop
on_press:
then:
- ble_keyboard.press:
id: esp32_bleKeyboard
code:
- 4
- 0
- delay: 100ms
- ble_keyboard.release: esp32_bleKeyboard ```
Crashes with ESPHome 2026.4.2:
WARNING Found stack trace! Trying to decode it
WARNING Decoded 0x400f22a3: ble_npl_mutex_pend at /home/user/Devops/esphome/config/.esphome/build/living-room-tablet-keyboard/.piolibdeps/living-room-tablet-keyboard/NimBLE-Arduino/src/nimble/porting/npl/freertos/include/nimble/nimble_npl_os.h:249
(inlined by) ble_hs_lock_nested at /home/user/Devops/esphome/config/.esphome/build/living-room-tablet-keyboard/.piolibdeps/living-room-tablet-keyboard/NimBLE-Arduino/src/nimble/nimble/host/src/ble_hs.c:187
WARNING Decoded 0x400f22c7: ble_hs_lock at /home/user/Devops/esphome/config/.esphome/build/living-room-tablet-keyboard/.piolibdeps/living-room-tablet-keyboard/NimBLE-Arduino/src/nimble/nimble/host/src/ble_hs.c:245
WARNING Decoded 0x400f1fe7: ble_gatts_reset at /home/user/Devops/esphome/config/.esphome/build/living-room-tablet-keyboard/.piolibdeps/living-room-tablet-keyboard/NimBLE-Arduino/src/nimble/nimble/host/src/ble_gatts.c:3302
WARNING Decoded 0x400e967d: NimBLEDevice::createServer() at /home/user/Devops/esphome/config/.esphome/build/living-room-tablet-keyboard/.piolibdeps/living-room-tablet-keyboard/NimBLE-Arduino/src/NimBLEDevice.cpp:143
WARNING Decoded 0x400faf4f: BleKeyboard::begin() at /home/user/Devops/esphome/config/.esphome/build/living-room-tablet-keyboard/.piolibdeps/living-room-tablet-keyboard/ESP32 BLE Keyboard/BleKeyboard.cpp:118
WARNING Decoded 0x400d6c83: esphome::ble_keyboard::Esp32BleKeyboard::setup() at /home/user/Devops/esphome/config/.esphome/build/living-room-tablet-keyboard/src/esphome/components/ble_keyboard/ble_keyboard.cpp:25
(inlined by) esphome::ble_keyboard::Esp32BleKeyboard::setup() at /home/user/Devops/esphome/config/.esphome/build/living-room-tablet-keyboard/src/esphome/components/ble_keyboard/ble_keyboard.cpp:17
WARNING Decoded 0x400dcce6: esphome::PollingComponent::call_setup() at /home/user/Devops/esphome/config/.esphome/build/living-room-tablet-keyboard/src/esphome/core/component.cpp:494
WARNING Decoded 0x40197b49: esphome::Component::call() at /home/user/Devops/esphome/config/.esphome/build/living-room-tablet-keyboard/src/esphome/core/component.cpp:260
WARNING Decoded 0x400dc830: esphome::Application::setup() at /home/user/Devops/esphome/config/.esphome/build/living-room-tablet-keyboard/src/esphome/core/application.cpp:82
WARNING Decoded 0x400e0d33: setup() at /home/user/Devops/esphome/config/.esphome/build/living-room-tablet-keyboard/living-room-tablet-keyboard.yaml:97
WARNING Decoded 0x400d713f: esphome::loop_task(void*) at /home/user/Devops/esphome/config/.esphome/build/living-room-tablet-keyboard/src/esphome/components/esp32/core.cpp:66
Trying a few things to see what mitigates the problemâŚ
OK 2026.2.4 works fine! So the problem with the BLE keyboard lies between 2026.2 and 2026.4
Incorrect. Diagnosing moreâŚ
Last ESPHome version that works stable is 2025.12.4. Sorry but no dice with any later versions.
Yeah in ESPHome 2026.1 there was a change made where it doesnât include all arduino libraries by default (to reduce the compile time and binary size).
I have tried a bit of mucking around to get it working but havenât figured it out yet.
For now I just compile it via ESPHome 2025.12.
If youâre running ESPHome as an addon in HA, Iâd recommend adding the following repo and installing the old version (will run separately to the main version): GitHub - khenderick/esphome-legacy-addons: ESPHome addons from previous versions. Just in case something isn't working with the new version ¡ GitHub
Update â Fork migrated to ESP-IDF NimBLE
Hi everyone! I wanted to share that Iâve created a fork of this excellent component, migrated from the Arduino framework to ESP-IDF native NimBLE.
Why? The original relies on NimBLE-Arduino, which doesnât build on newer ESP32 variants like the C3, C6, and H2. The ESP-IDF version uses the native esp_hid component, so it works across the full ESP32 family.
What changed:
- Framework: arduino â esp-idf
- BLE stack: NimBLE-Arduino â ESP-IDF esp_hid + NimBLE
- No external libraries needed
- Same YAML API (print, press, combination, start/stop, battery, etc.)
If youâre hitting build errors on ESP32-C3 or newer chips, give it a try:
GitHub - adesanto84/esphome-blekeyboard: ESPHome BLE Keyboard ¡ GitHub
Full credit to @dmamontov (dmamontov (Dmitry Mamontov) ¡ GitHub) for the original implementation â this fork just adapts the runtime layer for ESP-IDF compatibility.
Thank you! I will probably soon move over to your fork because I'm stuck on ESPHome March 2026.




