Keyboard Dongle
This implementation is experimental and subject to change.
The information below is for keyboards consisting of a board and a shield. The setup for keyboards consisting exclusively of a board is not yet documented.
A bluetooth dongle can be added to any keyboard running ZMK. The result is a split keyboard with the dongle as "central". There are a number of advantages to adding a dongle, but also some disadvantages:
Benefits:
- The "central" dongle results in increased battery life for the keyboard/former "central", as it is now a peripheral.
- It is easier to connect to the host device.
Disadvantages:
- An extra microcontroller is needed.
- The keyboard becomes unusable without the dongle.
Depending on how the dongle is used, there are some additional latency considerations to keep in mind. On average, the latency increase is around 3.75ms, in worst case scenario, the latency increase can be up to 7.5ms compared to a unibody keyboard.
Editing a Keyboard Definition to Support a Dongle
You will modify the files defining your keyboard to support a dongle. The recommended approach to doing so (found below) allows you to easily enable a dongle, but it is disabled by default. This is done to ensure that backwards compatibility is maintained for users who do not wish to use a dongle.
Shield Configuration Files
Start by adding the dongle body to the shield configuration.
config SHIELD_MY_KEYBOARD_DONGLE
def_bool $(shields_list_contains,my_keyboard_dongle)
Next, add the dongle configuration to your keyboard's Kconfig.defconfig
.
- Unibody Keyboard
- Split Keyboard
if SHIELD_MY_KEYBOARD_DONGLE
config ZMK_KEYBOARD_NAME
default "My Board"
config ZMK_SPLIT_ROLE_CENTRAL
default y
config ZMK_SPLIT
default y
# Increase the transmit power of the dongle
choice BT_CTLR_TX_PWR
default BT_CTLR_TX_PWR_PLUS_8
endchoice
endif
if SHIELD_MY_KEYBOARD && !ZMK_SPLIT
config ZMK_KEYBOARD_NAME
default "My Board"
endif
Modify the following Kconfig.defconfig
file to include the dongle in the split keyboard configuration.
if SHIELD_MY_KEYBOARD_DONGLE || SHIELD_MY_KEYBOARD_LEFT || SHIELD_MY_KEYBOARD_RIGHT
config ZMK_SPLIT
default y
endif
if SHIELD_MY_KEYBOARD_DONGLE
config ZMK_KEYBOARD_NAME
default "My Keyboard"
config ZMK_SPLIT_ROLE_CENTRAL
default y
config ZMK_SPLIT_BLE_CENTRAL_PERIPHERALS
default 2
# Increase the transmit power of the dongle
choice BT_CTLR_TX_PWR
default BT_CTLR_TX_PWR_PLUS_8
endchoice
endif
Modify the Kconfig.defconfig
file to include the following:
if SHIELD_MY_KEYBOARD_LEFT
# Setting this to y will make the left half the central
# We want it to be the central when dongle is not used
config ZMK_SPLIT_ROLE_CENTRAL
default y
# Check if the left half is the central
if ZMK_SPLIT_ROLE_CENTRAL
config ZMK_KEYBOARD_NAME
default "My Keyboard"
endif # ZMK_SPLIT_ROLE_CENTRAL
endif # SHIELD_MY_KEYBOARD_LEFT
Dongle Overlay File
Replace the kscan
with kscan-mock
in the dongle overlay.
Your keyboard's matrix transform must be both defined and selected under the chosen
node either here or in a my_keyboard.dtsi
file.
// import the default shield configuration
#include "my_keyboard.dtsi"
/ {
chosen {
zmk,kscan = &mock_kscan;
};
mock_kscan: kscan_1 {
compatible = "zmk,kscan-mock";
columns = <0>;
rows = <0>;
events = <0>;
};
};
Enabling the Dongle
When the above has been implemented in the keyboard definition.
The dongle can be enabled by implementing the following changes in the user config file.
For a split keyboard, change this
# Disable central role to use dongle
CONFIG_ZMK_SPLIT_ROLE_CENTRAL=n
For a unibody keyboard, change this
# Enable split functionality, this will put the unibody keyboard in peripheral mode
CONFIG_ZMK_SPLIT=y
Building the firmware
Add the appropriate lines to your build.yml
file to build the firmware for your dongle, in addition to the other parts of your keyboard.
include:
# -----------------------------------------
# Your other keyboard parts here
# -----------------------------------------
- board: nice_nano_v2
shield: my_keyboard_dongle
- board: nice_nano_v2
shield: settings_reset
Before flashing your new firmware, flash the settings_reset
UF2 firmware on all devices.
Any microcontroller with BLE support can be used as a dongle.