Commit | Line | Data |
---|---|---|
f6e94cb2 AT |
1 | # KEBA - A Keyboard # |
2 | ||
3 | The goal is a keyboard suitable both as a general purpose UNIX workstation | |
4 | keyboard and as a NED keyboard. The project name is KEBA. | |
5 | ||
6 | ## Size ## | |
7 | ||
8 | Picture a rectangle from the bottom-left `Control` key to the upper right | |
9 | `Backspace` on a traditional 104-key keyboard. That entire block is the *core*. | |
10 | ||
11 | When my hands leave the core, it is as disruptive to my typing as when I reach | |
12 | for the mouse. Thus, the new keyboard will only be the size of the core. In | |
13 | order to utilize the large number of pre-existing keyboard cases and | |
14 | accessories, I will target the "60% keyboard" size, mounting holes and connector | |
15 | location. | |
16 | ||
17 | ## Layout ## | |
18 | ||
19 | The single, universal piece of advice I have received is that, if I want to | |
20 | retain my muscle memory for a traditional keyboard, my alterations must not be | |
21 | minor. Only a significant break from a traditional layout will allow my brain | |
22 | to train a new set of memories without meddling with the old set. | |
23 | ||
24 | I'm going to follow that advice. | |
25 | ||
26 | ### Physical Layout ### | |
27 | ||
28 | Many of the keys accessible on a traditional keyboard via extending my pinky | |
29 | finger (think: `-=[]\'/.`) are difficult to hit accurately. I consistently end | |
30 | up one key off when trying to enter any kind of brace (`(){}[]`). However, my | |
31 | pinky was able to easily navigate the block of function keys adjoined to the | |
32 | left side of the keyboard core on a Sun keyboard. | |
33 | ||
34 | As those Sun keys are laid out in a grid, a pure ortholinear layout seems | |
35 | logical. This also plays into the 'sufficiently different' criteria. By | |
36 | forcing my fingers to move to unaligned (w.r.t. a traditional keyboard) | |
37 | locations, my brain should switch back to traditional layout when presented | |
38 | with a staggered keyboard. | |
39 | ||
40 | Since the block Sun adjoined was a 2x5 grid and the upper-most and lower-most | |
41 | keys were at the edge of comfort, we will go with five rows. This fits cleanly | |
42 | into the 60% keyboard case. | |
43 | ||
44 | Although a 60% case will allow 15 columns of keys, it was difficult to | |
45 | accurately place my hand on top of the outermost function keys, instead | |
46 | frequently sliding over the key while pressing it down. To avoid this, remove | |
47 | one column of keys and make the two outermost columns 1.5u wide. | |
48 | ||
49 | After analyzing my keystrokes by lightly marking the top of my keys, I | |
50 | discovered that my spacebar is only struck over a surface corresponding to 2.5 | |
51 | key widths. Given the ortholinear layout, we will reduce the spacebar to 2u | |
52 | wide and include multiple 2u buttons. | |
53 | ||
54 | Putting together the current criteria, we arrive at the following layout: | |
55 | ||
56 | ![](/projects/ned/keyboard_images/001_kb_img.png "") | |
57 | ||
58 | ### Logical Layout ### | |
59 | ||
60 | We first consider the alphanumerics. This consists of a 10x4 grid with four | |
61 | empty spots (the `;/.,` keys). When placing it into the 12x4 space available, | |
62 | split it to allow for a wider spread of the hands, creating an easier angle on | |
63 | the wrists. This also avoids a double column of utility keys on the outer ends | |
64 | of the board, instead moving one column from each side into the middle and | |
65 | making it easier to accurately hit the pinky-associated utility keys. | |
66 | ||
67 | The alphabetic keys will reside in a modified Colemak configuration with the | |
68 | `U` key moving down two spots, just to the right of the `M` key, and the `O` | |
69 | key moving to the `U` key's old location. This modified Colemak layout allows | |
70 | placement of `Escape` directly underneath the right pinky. | |
71 | ||
72 | While we're at it, rearrange the numbers into the correct order. | |
73 | ||
74 | That thinking generates this alphanumeric+`Escape` core layout: | |
75 | ||
76 | ![](/projects/ned/keyboard_images/002_kb_img.png "") | |
77 | ||
78 | The remaining special keys are | |
79 | ||
80 | Tab, Shift, Control, Alt, Space, Enter, Backspace. | |
81 | ||
82 | Since `Backspace` is never pressed in the course of regular typing, we locate | |
83 | it at middle-top where each index finger can reach it with a small stretch. | |
84 | Given their frequent use, `Space` and `Enter` are placed under the thumbs. | |
85 | `Shift` moves to the most convenient pinky location. Then `Tab` is placed | |
86 | underneath that location, still easily accessible but the least accessible of | |
87 | the `Ctrl`/`Shift`/`Tab` combo. | |
88 | ||
89 | My computing environment uses `Alt` to send instructions to the operating | |
90 | environment and `Control` to send instructions to individual programs. | |
91 | Consequently, we place `Control` to the left of the `QWFPG` row for convenient | |
92 | use with the left side alphabetic keys and place `Alt` bottom-center so the | |
93 | entire keyboard is easily reached while it is depressed. | |
94 | ||
95 | In practice, I found that I never use the right hand `Alt`, `Shift` or | |
96 | `Control` so there will be only one of each on this keyboard. | |
97 | ||
98 | Arrow keys are assigned under the assumption that up/down arrow keys should not | |
99 | share a hand with `Enter` since one frequently pages through a list with | |
100 | up/down arrows and selects with `Enter`, like when selecting a command from the | |
101 | command line history. By keeping them on separate sides of the board, both | |
102 | hands can be used. | |
103 | ||
104 | The four corner keys will be reserved for user-programmable shortcuts. | |
105 | ||
106 | That leaves us with the following layout: | |
107 | ||
108 | ![](/projects/ned/keyboard_images/003_kb_img.png "") | |
109 | ||
110 | Finally, all the remaining keys will be mapped via four overlays, selectable | |
111 | via two Meta keys on the bottom row. Holding a combination of these keys down | |
112 | will select the overlay. A single tap of the key will enable the overlay for a | |
113 | single additional keypress. A double-tap of the key will lock the overlay on, | |
114 | or turn it off. | |
115 | ||
116 | Via this mechanism, the remaining 12 blank keys can encode 48 values. | |
117 | ||
118 | Importantly, overlays will NOT change any keys other than these 12 blank keys. | |
119 | Every key in the following set will remain unchanged in every overlay: | |
120 | ||
121 | a-z, 0-9, Control, Shift, Alt, Tab, Space, | |
122 | Enter, Backspace, Arrows, Escape, Meta1, Meta2 | |
123 | ||
124 | At a minimum, the overlays need to include the following characters from a | |
125 | standard 104-key: | |
126 | ||
127 | `~!@#$%^&*()_+-=[]{}\|;:'",.?/<> | |
128 | ||
129 | Including other characters, say some logic and set theory symbols, is enticing | |
130 | but would require a custom keyboard definition in each OS I use. Perhaps | |
131 | careful assignment of keycodes so as to stay outside the standard 104-key | |
132 | definitions would allow a 'compatibility' mode. For that reason, I would like | |
133 | to keep the combined (`Meta1`+`Meta2`) overlay blank, if possible. | |
134 | ||
135 | Assignment of the overlay keys is still tentative. | |
136 | ||
137 | I know I want all the brackets down the middle. The remaining assignments are | |
138 | made in consideration of the key's frequency of use in/at normal English | |
139 | writing, the UNIX command line, and the C programming environment. Allowing | |
140 | overlap, I see those sets as follows. | |
141 | ||
142 | English Language: | |
143 | ||
144 | !,.? | |
145 | ||
146 | UNIX Commandline: | |
147 | ||
148 | `~&*_-\/|" | |
149 | ||
150 | C Language: | |
151 | ||
152 | #&*-+=;:'",/ | |
153 | ||
154 | Other: | |
155 | ||
156 | @$%^ | |
157 | ||
158 | When assigning overlays, since the 'extra' overlay buttons are on the right | |
159 | hand side, the left overlay button, or `Meta1`, should take precedence over the | |
160 | right overlay button. In other words, the priority should be: | |
161 | ||
162 | Default > Meta1 > Meta2 > Meta1+Meta2 | |
163 | ||
164 | The following are the three overlays as currently assigned: | |
165 | ||
166 | ![](/projects/ned/keyboard_images/004_kb_img.png "") | |
167 | ||
168 | ![](/projects/ned/keyboard_images/005_kb_img.png "") | |
169 | ||
170 | ![](/projects/ned/keyboard_images/006_kb_img.png "") | |
171 | ||
172 | ## Keyswitches ## | |
173 | ||
174 | In the linear vs clicky vs tactile decision, my *normal* is most people's | |
175 | *extreme*. I consider an IBM Model M to be the baseline for an adequate | |
176 | computer keyboard, not some ultimate endpoint. | |
177 | ||
178 | The switches most frequently recommended for someone that likes the Model M are | |
179 | the Cherry MX Greens. I already use MX Blues from the same family to repair | |
180 | Tektronix terminals and find the tactile style suitable. If the information on | |
181 | the internet is to be believed, MX Greens are still lighter than a Model M but | |
182 | are the heaviest MX-series switches on the market. | |
183 | ||
184 | It might make sense to install Mill-Max sockets in one PCB so I can easily swap | |
185 | keyswitches until I find what I want, despite the cost. Even if the MX Greens | |
186 | are where I settle, I won't know they're *right* until I also try some other | |
187 | switches. | |
188 | ||
189 | ## Keycaps ## | |
190 | ||
191 | Keycaps should be either the full SA profile, or all SA Row 3 profile. | |
192 | Alphanumeric caps should have a SINGLE character on them, not a double printing | |
193 | that includes the 'shifted' character. All overlay and most non-alphanumeric | |
194 | caps like Space and Enter should be blank. Meta keys can be playful, consider | |
195 | PLOT/STOP or BREAK/RESET from my existing keycap inventory. | |
196 | ||
197 | ## Computer Interface ## | |
198 | ||
199 | Since both QMK and the STM32 natively support USB, that is a natural interface | |
200 | to choose. | |
201 | ||
202 | Alternatively, I could expose a logic level UART and design a series of inline | |
203 | dongles to convert to whatever signalling I want. That allows me to easily | |
204 | connect the keyboard in place of a USB, PS/2, Sun Type 3 & 5, Tektronix | |
205 | terminal, etc keyboard. This option would require custom firmware. | |
206 | ||
207 | ## Human Interface ## | |
208 | ||
209 | The keyboard should include LED lights behind the keys for use in communicating | |
210 | with the user. By default, the lights should be off and should only briefly | |
211 | light to communicate. At a minimum, there should be a different blink for each | |
212 | Meta key to indicate when it is triggered/toggled. Perhaps multi-color LEDs to | |
213 | indicate the different overlays? | |
214 | ||
215 | If using USB, expose a virtual UART to the host that allows for configuration. | |
216 | If using a generic UART, configure the keyboard to enter a programming mode on | |
217 | that same UART when some contrived combination of keys is pressed. Either way, | |
218 | the keyboard should be easily configurable via a human-readable UART interface. | |
219 | ||
220 | ## Firmware ## | |
221 | ||
222 | If I use a USB interface, I can copy my STM32 circuit from Liquid Fusion and | |
223 | use it with QMK until I get around to writing my own code. Will QMK support the | |
224 | 'toggle by double-tap' feature I envison for the Meta keys? | |
225 | ||
226 | ## Template ## | |
227 | ||
228 | The following JSON is a template of the static key assignments that can be | |
229 | uploaded to <http://www.keyboard-layout-editor.com/>. | |
230 | ||
231 | [ | |
232 | [ | |
233 | { | |
234 | "c": "#ffffff", | |
235 | "t": "000000", | |
236 | "p": "SA R3", | |
237 | "sm": "cherry", | |
238 | "sb": "cherry", | |
239 | "st": "MX1A-F1xx", | |
240 | "a": 7, | |
241 | "f": 9, | |
242 | "w": 1.5 | |
243 | }, | |
244 | "", | |
245 | "Ø", | |
246 | "1", | |
247 | "2", | |
248 | "3", | |
249 | "4", | |
250 | { | |
251 | "f": 4, | |
252 | "w": 2 | |
253 | }, | |
254 | "ERASE", | |
255 | { | |
256 | "f": 9 | |
257 | }, | |
258 | "5", | |
259 | "6", | |
260 | "7", | |
261 | "8", | |
262 | "9", | |
263 | { | |
264 | "w": 1.5 | |
265 | }, | |
266 | "" | |
267 | ], | |
268 | [ | |
269 | { | |
270 | "f": 4, | |
271 | "w": 1.5 | |
272 | }, | |
273 | "CONTROL", | |
274 | { | |
275 | "f": 9 | |
276 | }, | |
277 | "Q", | |
278 | "W", | |
279 | "F", | |
280 | "P", | |
281 | "G", | |
282 | "", | |
283 | "", | |
284 | "J", | |
285 | "L", | |
286 | "O", | |
287 | "Y", | |
288 | "", | |
289 | { | |
290 | "w": 1.5 | |
291 | }, | |
292 | "" | |
293 | ], | |
294 | [ | |
295 | { | |
296 | "f": 4, | |
297 | "w": 1.5 | |
298 | }, | |
299 | "SHIFT", | |
300 | { | |
301 | "f": 9 | |
302 | }, | |
303 | "A", | |
304 | "R", | |
305 | "S", | |
306 | "T", | |
307 | "D", | |
308 | "", | |
309 | "", | |
310 | "H", | |
311 | "N", | |
312 | "E", | |
313 | "I", | |
314 | { | |
315 | "f": 4 | |
316 | }, | |
317 | "ESC", | |
318 | { | |
319 | "f": 9, | |
320 | "w": 1.5 | |
321 | }, | |
322 | "" | |
323 | ], | |
324 | [ | |
325 | { | |
326 | "f": 4, | |
327 | "w": 1.5 | |
328 | }, | |
329 | "TAB", | |
330 | { | |
331 | "f": 9 | |
332 | }, | |
333 | "Z", | |
334 | "X", | |
335 | "C", | |
336 | "V", | |
337 | "B", | |
338 | "", | |
339 | "", | |
340 | "K", | |
341 | "M", | |
342 | "U", | |
343 | "", | |
344 | "", | |
345 | { | |
346 | "w": 1.5 | |
347 | }, | |
348 | "" | |
349 | ], | |
350 | [ | |
351 | { | |
352 | "w": 1.5 | |
353 | }, | |
354 | "", | |
355 | "<i class='fa fa-long-arrow-up'></i>", | |
356 | "<i class='fa fa-long-arrow-down'></i>", | |
357 | { | |
358 | "f": 4, | |
359 | "w": 2 | |
360 | }, | |
361 | "SPACE", | |
362 | "M1", | |
363 | { | |
364 | "w": 2 | |
365 | }, | |
366 | "ALT", | |
367 | "M2", | |
368 | { | |
369 | "w": 2 | |
370 | }, | |
371 | "ENTER", | |
372 | { | |
373 | "f": 9 | |
374 | }, | |
375 | "<i class='fa fa-long-arrow-left'></i>", | |
376 | "<i class='fa fa-long-arrow-right'></i>", | |
377 | { | |
378 | "w": 1.5 | |
379 | }, | |
380 | "" | |
381 | ] | |
382 | ] | |
383 | ||
384 | The following JSON is a template of the overlay keys that can be uploaded to | |
385 | <http://www.keyboard-layout-editor.com/>. | |
386 | ||
387 | [ | |
388 | [ | |
389 | { | |
390 | "c": "#ffffff", | |
391 | "t": "000000", | |
392 | "p": "SA R3", | |
393 | "sm": "cherry", | |
394 | "sb": "cherry", | |
395 | "st": "MX1A-F1xx", | |
396 | "a": 7, | |
397 | "f": 9, | |
398 | "w": 1.5, | |
399 | "d": true | |
400 | }, | |
401 | "", | |
402 | { | |
403 | "d": true | |
404 | }, | |
405 | "", | |
406 | { | |
407 | "d": true | |
408 | }, | |
409 | "", | |
410 | { | |
411 | "d": true | |
412 | }, | |
413 | "", | |
414 | { | |
415 | "d": true | |
416 | }, | |
417 | "", | |
418 | { | |
419 | "d": true | |
420 | }, | |
421 | "", | |
422 | { | |
423 | "f": 4, | |
424 | "w": 2, | |
425 | "d": true | |
426 | }, | |
427 | "", | |
428 | { | |
429 | "f": 9, | |
430 | "d": true | |
431 | }, | |
432 | "", | |
433 | { | |
434 | "d": true | |
435 | }, | |
436 | "", | |
437 | { | |
438 | "d": true | |
439 | }, | |
440 | "", | |
441 | { | |
442 | "d": true | |
443 | }, | |
444 | "", | |
445 | { | |
446 | "d": true | |
447 | }, | |
448 | "", | |
449 | { | |
450 | "w": 1.5, | |
451 | "d": true | |
452 | }, | |
453 | "" | |
454 | ], | |
455 | [ | |
456 | { | |
457 | "f": 4, | |
458 | "w": 1.5, | |
459 | "d": true | |
460 | }, | |
461 | "", | |
462 | { | |
463 | "f": 9, | |
464 | "d": true | |
465 | }, | |
466 | "", | |
467 | { | |
468 | "d": true | |
469 | }, | |
470 | "", | |
471 | { | |
472 | "d": true | |
473 | }, | |
474 | "", | |
475 | { | |
476 | "d": true | |
477 | }, | |
478 | "", | |
479 | { | |
480 | "d": true | |
481 | }, | |
482 | "", | |
483 | "", | |
484 | "", | |
485 | { | |
486 | "d": true | |
487 | }, | |
488 | "", | |
489 | { | |
490 | "d": true | |
491 | }, | |
492 | "", | |
493 | { | |
494 | "d": true | |
495 | }, | |
496 | "", | |
497 | { | |
498 | "d": true | |
499 | }, | |
500 | "", | |
501 | "", | |
502 | { | |
503 | "w": 1.5 | |
504 | }, | |
505 | "" | |
506 | ], | |
507 | [ | |
508 | { | |
509 | "f": 4, | |
510 | "w": 1.5, | |
511 | "d": true | |
512 | }, | |
513 | "", | |
514 | { | |
515 | "f": 9, | |
516 | "d": true | |
517 | }, | |
518 | "", | |
519 | { | |
520 | "d": true | |
521 | }, | |
522 | "", | |
523 | { | |
524 | "d": true | |
525 | }, | |
526 | "", | |
527 | { | |
528 | "d": true | |
529 | }, | |
530 | "", | |
531 | { | |
532 | "d": true | |
533 | }, | |
534 | "", | |
535 | "", | |
536 | "", | |
537 | { | |
538 | "d": true | |
539 | }, | |
540 | "", | |
541 | { | |
542 | "d": true | |
543 | }, | |
544 | "", | |
545 | { | |
546 | "d": true | |
547 | }, | |
548 | "", | |
549 | { | |
550 | "d": true | |
551 | }, | |
552 | "", | |
553 | { | |
554 | "f": 4, | |
555 | "d": true | |
556 | }, | |
557 | "", | |
558 | { | |
559 | "f": 9, | |
560 | "w": 1.5 | |
561 | }, | |
562 | "" | |
563 | ], | |
564 | [ | |
565 | { | |
566 | "f": 4, | |
567 | "w": 1.5, | |
568 | "d": true | |
569 | }, | |
570 | "", | |
571 | { | |
572 | "f": 9, | |
573 | "d": true | |
574 | }, | |
575 | "", | |
576 | { | |
577 | "d": true | |
578 | }, | |
579 | "", | |
580 | { | |
581 | "d": true | |
582 | }, | |
583 | "", | |
584 | { | |
585 | "d": true | |
586 | }, | |
587 | "", | |
588 | { | |
589 | "d": true | |
590 | }, | |
591 | "", | |
592 | "", | |
593 | "", | |
594 | { | |
595 | "d": true | |
596 | }, | |
597 | "", | |
598 | { | |
599 | "d": true | |
600 | }, | |
601 | "", | |
602 | { | |
603 | "d": true | |
604 | }, | |
605 | "", | |
606 | "", | |
607 | "", | |
608 | { | |
609 | "w": 1.5 | |
610 | }, | |
611 | "" | |
612 | ], | |
613 | [ | |
614 | { | |
615 | "w": 1.5, | |
616 | "d": true | |
617 | }, | |
618 | "", | |
619 | { | |
620 | "d": true | |
621 | }, | |
622 | "", | |
623 | { | |
624 | "d": true | |
625 | }, | |
626 | "", | |
627 | { | |
628 | "f": 4, | |
629 | "w": 2, | |
630 | "d": true | |
631 | }, | |
632 | "", | |
633 | "M1", | |
634 | { | |
635 | "w": 2, | |
636 | "d": true | |
637 | }, | |
638 | "", | |
639 | "M2", | |
640 | { | |
641 | "w": 2, | |
642 | "d": true | |
643 | }, | |
644 | "", | |
645 | { | |
646 | "f": 9, | |
647 | "d": true | |
648 | }, | |
649 | "", | |
650 | { | |
651 | "d": true | |
652 | }, | |
653 | "", | |
654 | { | |
655 | "w": 1.5, | |
656 | "d": true | |
657 | }, | |
658 | "" | |
659 | ] | |
660 | ] | |
661 |