You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Adding Easier Configuration for Dual-Side Encoders On Split Keyboards (#1133)
* added arg and property for `add_buttons: int` for adding singleton/single-pin buttons to the `coord_mapping`, rather than the user needing to create the coord_mapping manually.
* added documentation for the `add_buttons` argument
* updated description for Multiple Scanners with Custom `coord_mapping`
Copy file name to clipboardExpand all lines: docs/en/encoder.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -3,7 +3,7 @@ Add twist control to your keyboard! Volume, zoom, anything you want.
3
3
4
4
I2C encoder type has been tested with the Adafruit I2C QT Rotary Encoder with NeoPixel.
5
5
6
-
**Note:** If you have a **split** keyboard and encoders on **both sides** should work, it's currently necessary to use the encoder-scanner explained at the bottom of[scanners docs](scanners.md).
6
+
**Note:** If you have a **split** keyboard and encoders on **both sides** should work, it's currently necessary to use the encoder-scanner. See the Advanced Configuration section of the[scanners docs](scanners.md).
7
7
8
8
## Enabling the extension
9
9
The constructor(`EncoderHandler` class) takes a list of encoders, each one defined as either:
Copy file name to clipboardExpand all lines: docs/en/scanners.md
+88-13Lines changed: 88 additions & 13 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -150,24 +150,42 @@ class MyKeyboard(KMKKeyboard):
150
150
151
151
### RotaryioEncoder
152
152
153
-
Matrix events from a quadrature ("rotary") encoder?
153
+
Matrix events from a quadrature ("rotary") encoder.
154
+
155
+
For any rotary encoders that you may include in your keyboard configuration, you can add this scanner to handle the input of the encoder actions (usually: left turn, right turn, and click) and to be able to configure them via the `keyboard.keymap` as if they were regular keys.
156
+
157
+
Often, rotary encoders are attached as accessories, i.e. alongside a key/button matrix. The below example shows how this can be configured.
If your design requires symetrical encoders (e.g. one on each half of a split keyboard), see Multiple Scanners section below for more details.
188
+
171
189
172
190
## `Scanner` base class
173
191
@@ -201,14 +219,66 @@ class MyKeyboard(KMKKeyboard):
201
219
# etc...
202
220
]
203
221
```
204
-
#### Multiple Scanners `coord_mapping` and keymap changes
205
-
To add more scanners you need to add onto your `coord_mapping`.
222
+
223
+
224
+
#### Adding Single-Pin Buttons or Rotary Encoders to Keymap Using Scanners and Split
225
+
226
+
In many cases, split keybaords are symetrical in form and function. Some split keyboards also have additional hardware like one or more rotary encoders, or non-matrix-connected media or macro buttons. In this case, you will want to configure multiple scanners.
227
+
228
+
The `Split` class that you're probably already using creates the `coord_mapping` indexes automatically. However, the `add_buttons` argument will cause it to append any additional "buttons" (or encoder actions) to the `coord_mapping` for _each half_ of the keyboard.
229
+
230
+
By default, `Split` will also configure `MatrixScanner` and assign it to `KMKKeyboard.matrix` as a single/default scanner, but with the additional actions/keys from `RotaryioEncoder`, it will need to be configured in your custom class so that `RotaryioEncoder` can be configured and appended to `KNKKeyboard.matrix`. This enables the rotary actions to map from the `coord_mapping` to the `keybaord.keymap` correctly, making it easy to assign keycodes to the actions or buttons.
206
231
207
232
Example:
233
+
```python
234
+
from kmk.scanners import DiodeOrientation
235
+
from kmk.scanners.keypad import MatrixScanner
236
+
from kmk.scanners.encoder import RotaryioEncoder
237
+
from kmk.modules.split import Split
238
+
239
+
240
+
classMyKeyboard(KMKKeyboard):
241
+
def__init__(self) -> None:
242
+
super().__init__()
243
+
self.diode_orientation = DiodeOrientation.ROW2COL
244
+
split_args = {
245
+
'split_side': None, # EE Hands
246
+
'data_pin': board.GP1,
247
+
'data_pin2': board.GP0,
248
+
'split_flip': True,
249
+
'use_pio': True,
250
+
'uart_flip': True,
251
+
'add_buttons': 2# add left- and right-turn actions for one encoder on each side; see `split_keyboards.md`
#### Multiple Scanners `coord_mapping` and keymap changes
273
+
For a more manually-controlled configuration, you can add any other scanners that you need and create your `coord_mapping` in your own code (leaving off the `add_buttons` argument when initializing `Split`)
274
+
Creating and assigning a custom `coord_mapping` should be done before intitializing `Split` or any scanners.
275
+
276
+
The below examples illustrate how the additional encoder actions are assigned to the `coord_mapping`. Your configuration should follow this pattern.
277
+
208
278
209
279
`coord_mapping` with just one `MatrixScanner` on a 58 key split keyboard:
210
280
```python
211
-
coord_mapping = [
281
+
keyboard.coord_mapping = [
212
282
0, 1, 2, 3, 4, 5, 35, 34, 33, 32, 31, 30,
213
283
6, 7, 8, 9, 10, 11, 41, 40, 39, 38, 37, 36,
214
284
12, 13, 14, 15, 16, 17, 47, 46, 45, 44, 43, 42,
@@ -217,9 +287,9 @@ coord_mapping = [
217
287
]
218
288
```
219
289
220
-
`coord_mapping` using `MatrixScanner` and `RotaryioEncoder` on the same 58 key split keyboard with an encoder on each half:
290
+
`coord_mapping` using `MatrixScanner` and `RotaryioEncoder` on the same 58 key split keyboard, adding an encoder to each half:
221
291
```python
222
-
coord_mapping = [
292
+
keyboard.coord_mapping = [
223
293
0, 1, 2, 3, 4, 5, 37, 36, 35, 34, 33, 32,
224
294
6, 7, 8, 9, 10, 11, 43, 42, 41, 40, 39, 38,
225
295
12, 13, 14, 15, 16, 17, 49, 48, 47, 46, 45, 44,
@@ -229,9 +299,14 @@ coord_mapping = [
229
299
]
230
300
```
231
301
232
-
On the top left side of a standard split keyboard `coord_mapping`, right below that you see a split keyboard where `RotaryioEncoder` and `MatrixScanner` (the default scanner) are used.
233
-
In the single scanner example, we used to count from 0 to 29 while the top right side starts at 30.
234
-
With the addition of the encoder scanner, the left side has 2 additional keys making it count up to 31 and the right side would then start at 32 and count to 63.
235
-
This means that keys 30, 31, 62, and 63 are for encoders.
236
-
Notice that all of the encoders are at the end of the array, because we put the encoder scanner after the matrix scanner in `keyboard.matrix`.
237
-
Therefore, we need to add 4 more key codes in the corresponding places of our `keyboard.keymap`, they will be used for the encoders.
302
+
Note that in both examples, the left-side indexes count from 0 to 29 for the first five rows. But the right side of the first (single scanner) example starts at 30 (in the top right corner) and ends at 59 in the center.
303
+
304
+
With the addition of the `RotaryioEncoder` scanner, the left side has 2 additional keys (30 and 31) causing the right side to start at 32 and count to 61 in the center, with two more keys at the bottom (62 and 63).
305
+
**This means that keys 30, 31, 62, and 63 are for the encoders.**
306
+
307
+
Notice that, despite the visual layout, all of the encoder keys are at the **_end_** of the array. This is because `RotaryioEncoder` was **_after_**`MatrixScanner`**_in the list_** when the `keyboard.matrix` was assigned. (see example in the previous section above)
308
+
309
+
Therefore, 4 more key codes can be added in the corresponding places in the `keyboard.keymap`, and they will be assigned to the encoders' actions.
310
+
311
+
312
+
Also note, it may be necessary to configure `Split().split_offset` when configuring your own `coord_mapping` to make sure that the encoders are assigned properly. The value will usually be the first/lowest index value of the right side. In the case of the second example above, the offset value would be 32, but this also depends on your `coord_mapping` layout.
Copy file name to clipboardExpand all lines: docs/en/split_keyboards.md
+5Lines changed: 5 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -50,6 +50,7 @@ split = Split(
50
50
data_pin2=None, # Second uart pin to allow 2 way communication
51
51
uart_flip=True, # Reverses the RX and TX pins if both are provided
52
52
use_pio=False, # Use RP2040 PIO implementation of UART. Required if you want to use other pins than RX/TX
53
+
add_buttons=0# add single-pin buttons, rotary encoder actions, etc. per-side.
53
54
)
54
55
55
56
```
@@ -111,6 +112,10 @@ In order to enable it, you must:
111
112
- pass `use_pio=True` into the `Split()` constructor.
112
113
113
114
115
+
### `add_buttons`
116
+
if you have additional single-pin buttons, rotary encoders, or other non-matrix actions that will be assigned to keys, you can add this argument with the number of buttons per-side. This will enable you to include them at the end of your keymap without needing to manually configure `keyboard.coord_mapping`.
117
+
118
+
114
119
### `data_pin`/`data_pin2`
115
120
For UART `SplitType`: on the `split_target` side, `data_pin` is the one use for RX, `data_pin2` the one for TX.
0 commit comments