--- title: Keyboard Dongle sidebar_label: Keyboard Dongle --- import Tabs from "@theme/Tabs"; import TabItem from "@theme/TabItem"; :::warning This implementation is experimental and subject to change. The information below is for keyboards consisting of a [board and a shield](../faq.md#why-boards-and-shields-why-not-just-keyboard). The setup for keyboards consisting exclusively of a [board](../faq.md#what-is-a-board) is not yet documented. ::: A bluetooth dongle can be added to any keyboard running ZMK. The result is a [split keyboard](./split-keyboards.md) 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. :::note Depending on how the dongle is used, there are some additional [latency considerations](./split-keyboards.md#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](../config/index.md#shield-folder) 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. ```kconfig title="Kconfig.shield" config SHIELD_MY_KEYBOARD_DONGLE def_bool $(shields_list_contains,my_keyboard_dongle) ``` Next, add the dongle configuration to your keyboard's `Kconfig.defconfig`. ```kconfig title="Kconfig.defconfig" 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. ```kconfig title="Kconfig.defconfig" 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: ```kconfig title="Kconfig.defconfig" 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. :::warning Your keyboard's matrix transform must be both defined and selected under the `chosen` node either here or in a `my_keyboard.dtsi` file. ::: ```dts title="my_keyboard_dongle.overlay" // 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 ```kconfig title="config/my_keyboard_left.conf" # Disable central role to use dongle CONFIG_ZMK_SPLIT_ROLE_CENTRAL=n ``` For a unibody keyboard, change this ```kconfig title="config/my_keyboard.conf" # 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. ```yaml include: # ----------------------------------------- # Your other keyboard parts here # ----------------------------------------- - board: nice_nano_v2 shield: my_keyboard_dongle - board: nice_nano_v2 shield: settings_reset ``` :::warning Before flashing your new firmware, flash the `settings_reset` [UF2 firmware](../troubleshooting/connection-issues.mdx#acquiring-a-reset-uf2) on all devices. ::: :::note Any microcontroller with BLE support can be used as a dongle. :::