forked from zmkfirmware/zmk
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Co-authored-by: rasmuskoit <[email protected]> Co-authored-by: Cem Aksoylar <[email protected]>
- Loading branch information
1 parent
80df319
commit a8b88f6
Showing
2 changed files
with
202 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,201 @@ | ||
--- | ||
title: Keyboard Dongle | ||
sidebar_label: Keyboard Dongle | ||
--- | ||
|
||
A bluetooth dongle can be added to any keyboard running ZMK. The result is a [split keyboard](../../features/split-keyboards.md) with the dongle as ["central"](../../features/split-keyboards.md#central-and-peripheral-roles). There are a number of advantages to adding a dongle, but also some disadvantages: | ||
|
||
Benefits: | ||
|
||
- For split keyboards, having the dongle for the "central" role results in [improved battery life](/power-profiler) for the former central part, as it is now a peripheral. | ||
- It is easier to connect to the host device since dongles are typically connected via USB. | ||
|
||
Disadvantages: | ||
|
||
- An extra [board](../../faq.md#what-is-a-board) is needed (any BLE-capable board will work). | ||
- The keyboard becomes unusable without the dongle. | ||
|
||
Depending on how the dongle is used, there are some additional [latency considerations](../../features/split-keyboards.md#latency-considerations) to keep in mind. | ||
The addition of the dongle adds an extra "hop" for the former central, increasing its latency to that of a peripheral. The other parts are unchanged latency-wise. There is also a commonly occurring case where the peripherals benefit. | ||
Assuming the dongle is connected to USB and the former central would have been connected via bluetooth to the host if the dongle wasn't present: | ||
|
||
- The former central will have its latency increased by about 1ms from the extra USB "hop" | ||
- The other parts will have their average latency _decreased_ by 6.5ms from the replacement of a BLE "hop" with a "USB" hop. | ||
|
||
As a result, for this common use case the average latency of the keyboard decreases. | ||
|
||
## Adding a Dongle | ||
|
||
To add a dongle, you will create a simplified form of a [new shield](./new-shield.mdx). | ||
The approach described below assumes the dongle will not have any keys assigned to itself, so it will not work for that scenario. | ||
|
||
As there are a very large number of possible devices that could be used as a dongle, you will be defining your dongle as a personal shield intended for your exclusive use. | ||
|
||
Prior to adding a dongle to your keyboard, please test its functionality without a dongle. The below guide will assume that your keyboard is named `my_keyboard`, replace accordingly. | ||
|
||
### Dongle Folder | ||
|
||
First, make sure that your `zmk-config` matches the folder structure found in the [unified ZMK config template](https://github.com/zmkfirmware/unified-zmk-config-template) (extra files and folders are fine, but none should be missing). | ||
|
||
Next, navigate to the `zmk-config/boards/shields` directory. Create a subdirectory called `my_keyboard`, if one doesn't already exist. Unless otherwise specified, the below files should all be placed in said folder. | ||
|
||
### Kconfig Files | ||
|
||
#### Kconfig.shield | ||
|
||
Make a file called `Kconfig.shield`, if one does not exist already. Add the following lines to it, replacing `SHIELD_MY_KEYBOARD_DONGLE` and `my_keyboard_dongle` according to your keyboard: | ||
|
||
```kconfig title="Kconfig.shield" | ||
# No whitespace after the comma or in the keyboard name! | ||
config SHIELD_MY_KEYBOARD_DONGLE | ||
def_bool $(shields_list_contains,my_keyboard_dongle) | ||
``` | ||
|
||
#### Kconfig.defconfig | ||
|
||
Make a file called `Kconfig.defconfig`, if one does not exist already. Add the following lines to it where `SHIELD_MY_KEYBOARD_DONGLE` should match the previous section: | ||
|
||
```kconfig title="Kconfig.defconfig" | ||
if SHIELD_MY_KEYBOARD_DONGLE | ||
# Max 16 characters in keyboard name | ||
config ZMK_KEYBOARD_NAME | ||
default "My Board" | ||
config ZMK_SPLIT_ROLE_CENTRAL | ||
default y | ||
config ZMK_SPLIT | ||
default y | ||
endif | ||
``` | ||
|
||
### Dongle Overlay File | ||
|
||
You will now need to find and copy your keyboard's matrix transform and physical layout. Navigate to the directory defining your keyboard (in-tree keyboards found [here](https://github.com/zmkfirmware/zmk/tree/main/app/boards)) and look through the [devicetree files](../../config/index.md) for nodes with `compatible = "zmk,matrix-transform";` or `compatible = "zmk,physical-layout";`. These should look something like this: | ||
|
||
```dts | ||
// Matrix Transform | ||
default_transform: keymap_transform_0 { | ||
compatible = "zmk,matrix-transform"; | ||
columns = <14>; | ||
rows = <5>; | ||
map = < | ||
// Lots of RC(r,c) macros | ||
>; | ||
}; | ||
// Physical Layout | ||
default_layout: default_layout { | ||
compatible = "zmk,physical-layout"; | ||
display-name = "Default Layout"; | ||
transform = <&default_transform>; | ||
kscan = <&kscan0>; | ||
keys = < | ||
// Really long list of keys. Keys property may not be present. | ||
>; | ||
}; | ||
``` | ||
|
||
You may find some keyboards import their physical layouts from [this location](https://github.com/zmkfirmware/zmk/tree/main/app/dts/layouts), in which case note the `#include` lines and any nodes that modify the properties that come from the shared layout. | ||
|
||
Now that you've found these nodes, make a file called `my_keyboard_dongle.overlay` (renamed as appropriate) and add the following lines to it: | ||
|
||
```dts title="my_keyboard_dongle.overlay" | ||
/ { | ||
chosen { | ||
zmk,kscan = &mock_kscan; | ||
zmk,physical-layout = &default_layout; | ||
}; | ||
mock_kscan: mock_kscan_0 { | ||
compatible = "zmk,kscan-mock"; | ||
columns = <0>; | ||
rows = <0>; | ||
events = <0>; | ||
}; | ||
// Copy of matrix transform node here | ||
// Copy of physical layout node here | ||
// If kscan property of physical layout is present, assign &mock_kscan to it | ||
}; | ||
``` | ||
|
||
Make sure that the matrix transform is selected by the physical layout. If the physical layout imported, you may need to override it: | ||
|
||
```dts title="my_keyboard_dongle.overlay" | ||
&default_layout { | ||
transform = <&default_transform>; | ||
}; | ||
``` | ||
|
||
If no physical layout is found, you should skip it and instead select the matrix transform as chosen directly: | ||
|
||
```dts title="my_keyboard_dongle.overlay" | ||
/ { | ||
chosen { | ||
zmk,kscan = &mock_kscan; | ||
zmk,matrix-transform = &default_transform; | ||
}; | ||
}; | ||
``` | ||
|
||
:::note | ||
If multiple physical layouts and matrix transformations are present, you should only need to import the one you wish to use. However, if you are getting errors, then the shield might be defining things in an unusual manner. In this case, copy in all matrix transformations and physical layouts, overriding as appropriate. | ||
::: | ||
|
||
## Enabling the Dongle | ||
|
||
Next, navigate to the `config` folder found in your `zmk-config`'s root. | ||
|
||
If your keyboard is a unibody, add the following to your `my_keyboard.conf` file (create the file if it does not exist): | ||
|
||
```kconfig title="config/my_keyboard.conf" | ||
# Enable split functionality, this will put the unibody keyboard in peripheral mode | ||
CONFIG_ZMK_SPLIT=y | ||
``` | ||
|
||
If your keyboard is a split keyboard, add the following to your `my_keyboard_left.conf` file, assuming `_left` is the current central (create the file if it does not exist by taking any `my_keyboard.conf` file and duplicating it to create a file for each part, deleting the shared file in the process): | ||
|
||
```kconfig title="config/my_keyboard_left.conf" | ||
# Disable central role to use dongle | ||
CONFIG_ZMK_SPLIT_ROLE_CENTRAL=n | ||
``` | ||
|
||
If your keyboard is a split keyboard, you will also need to increase the number of peripherals the dongle can connect to. | ||
Make a file called `my_keyboard_dongle.conf` and add the following lines to it: | ||
|
||
```kconfig title="config/my_keyboard_dongle.conf" | ||
# Change n to the number of peripherals your dongle will have | ||
CONFIG_ZMK_SPLIT_BLE_CENTRAL_PERIPHERALS=n | ||
# Change m to be equal or greater than the number of peripherals + the number of bt hosts the dongle should connect to | ||
CONFIG_BT_MAX_CONN=m | ||
``` | ||
|
||
To go back to not using a dongle, you can undo the changes in this section by removing the corresponding lines. | ||
|
||
:::note | ||
Under certain conditions, you may also need to change `CONFIG_BT_MAX_CONN` when using a unibody: See the [configuration documentation](../../config/system.md#bluetooth). | ||
::: | ||
|
||
## 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 | ||
# ----------------------------------------- | ||
# Change the board appropriately, you can use any board | ||
- board: nice_nano_v2 | ||
shield: my_keyboard_dongle | ||
- board: nice_nano_v2 | ||
shield: settings_reset | ||
``` | ||
:::warning | ||
Before flashing your new firmware, you need to flash `settings_reset` [firmware](../../troubleshooting/connection-issues.mdx#acquiring-a-reset-uf2) on all devices to ensure they can pair to each other. | ||
::: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters