├── .gitignore ├── .rvmrc ├── Gemfile ├── Gemfile.lock ├── teensy ├── scroll_wheel │ └── scroll_wheel.ino └── foot_pedal │ └── foot_pedal.ino ├── mapping.txt ├── twiddler_keymap.txt └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | reference/ 2 | -------------------------------------------------------------------------------- /.rvmrc: -------------------------------------------------------------------------------- 1 | rvm use 1.9.3@chording --create 2 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gem 'pry' 4 | gem 'libhid-ruby', path: './libhid-ruby' 5 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | PATH 2 | remote: ./libhid-ruby 3 | specs: 4 | libhid-ruby (0.0.1) 5 | ffi (>= 1.0.0) 6 | 7 | GEM 8 | remote: https://rubygems.org/ 9 | specs: 10 | coderay (1.0.8) 11 | ffi (1.4.0) 12 | method_source (0.8.1) 13 | pry (0.9.12) 14 | coderay (~> 1.0.5) 15 | method_source (~> 0.8) 16 | slop (~> 3.4) 17 | slop (3.4.3) 18 | 19 | PLATFORMS 20 | ruby 21 | 22 | DEPENDENCIES 23 | libhid-ruby! 24 | pry 25 | -------------------------------------------------------------------------------- /teensy/scroll_wheel/scroll_wheel.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * scroll wheel 3 | */ 4 | 5 | int previousVal = 0; 6 | int val = 0; 7 | int ledPin = 11; 8 | int scrollWheelPin = 10; 9 | 10 | int velocity = 10; 11 | 12 | void setup() { 13 | Serial.begin(9600); 14 | pinMode(scrollWheelPin, INPUT_PULLUP); 15 | pinMode(ledPin, OUTPUT); 16 | delay(1000); 17 | Serial.println("All set"); 18 | } 19 | 20 | void loop() { 21 | val = digitalRead(scrollWheelPin); 22 | if (val != previousVal) { 23 | Serial.println(val); 24 | digitalWrite(ledPin, val); 25 | Mouse.scroll(-1 * velocity); 26 | delay(300); 27 | previousVal = val; 28 | } 29 | } 30 | 31 | -------------------------------------------------------------------------------- /teensy/foot_pedal/foot_pedal.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * A vim insert mode foot pedal 3 | */ 4 | 5 | #include 6 | 7 | int ledPin = 11; 8 | int footPedalPin = 9; 9 | 10 | // 10 = debounce time in ms 11 | Bounce button = Bounce(footPedalPin, 10); 12 | 13 | void setup() { 14 | Serial.begin(9600); 15 | pinMode(footPedalPin, INPUT_PULLUP); 16 | pinMode(ledPin, OUTPUT); 17 | Keyboard.begin(); 18 | 19 | delay(1000); 20 | Serial.println("All set"); 21 | } 22 | 23 | void leaveInsert() { 24 | // We have to build Ctrl-[ to leave insert since 25 | // the ESC key does not seem to be detected on OSX. 26 | Keyboard.press(KEY_LEFT_CTRL); 27 | Keyboard.press('['); 28 | Keyboard.releaseAll(); 29 | }; 30 | 31 | void loop() { 32 | button.update(); 33 | 34 | 35 | if (button.fallingEdge()) { 36 | // ensure we're not in insert mode 37 | leaveInsert(); 38 | // enter insert 39 | Keyboard.write("i"); 40 | digitalWrite(ledPin, HIGH); 41 | } else if (button.risingEdge()) { 42 | leaveInsert(); 43 | digitalWrite(ledPin, LOW); 44 | } 45 | } 46 | 47 | -------------------------------------------------------------------------------- /mapping.txt: -------------------------------------------------------------------------------- 1 | This is an attempt at coming up with a chording keyboard layout for the Razor Nostromo keyboard. 2 | 3 | The keys are named as the table below: 4 | 5 | A B C D E 6 | 1 A1 B1 C1 D1 E1 7 | 2 A2 B2 C2 D2 E2 8 | 3 A3 B3 C3 D3 9 | 10 | (note that there is no E3) 11 | 12 | Typing: 13 | A = pinky finger 14 | B = ring finger 15 | C = middle finger 16 | D = index finger 17 | 18 | There are three keys for each finger. Additionally, there is a thumb 8-way pad (currently not used) and a mouse scroll wheel. 19 | 20 | Since the middle row is the easiest to type, the most common letters have been mapped there, and less common characters are on the top and bottom (1 and 3) rows of keys. 21 | 22 | We will use combinations of these keys (chords) to type. The formulas to build a keypress are as follows: 23 | 24 | r: A2 + B1 25 | 26 | Alphabet letters: 27 | abcdefghijklmnopqrstuvwxyz 28 | 29 | 30 | letter frequency via http://mtgap.bilfo.com/theory-of-letter-frequency.html and http://mtgap.bilfo.com/letter_frequency.html 31 | 32 | formal is not typed nearly as much as casual for most people: 33 | Prose = 6, Casual = 8, Programming = 4, Formal = 2, News = 7 (unweighted): e t a o i n s r h l d c u m f p g y w b . , v k _ ( ) ; " = ' - $ x / 0 : { } 1 j * > q 2 [ ] z ! \ ? < + 3 @ | 5 4 # & 6 8 9 7 % ~ ^ ` 34 | Prose = 6, Casual = 8, Programming = 4, Formal = 2, News = 7 (weighted) : e t a i o n s r h l d c u m p f g y w b , . v k " - 0 ' x j 1 z 2 q 9 5 3 8 4 7 : 6 ) ( $ ; | ? / ! & [ ] % _ @ > = * < + # ` ^ { } ~ \ 35 | 36 | Letter frequency for Ruby: 37 | Ruby: e t n s a o r i l d c _ p u m f " . , = h ' ( : ) g b v > y w < [ ] / 1 x @ q k 0 \ 2 | ? { } 3 - j 5 4 z 6 7 % 9 8 + ! * & $ ; # ^ ~ ` 38 | 39 | Twiddler mapping: 40 | 41 | If we wanted to use the twiddler keymap, we would translate this way: 42 | 43 | (assuming a right-handed Twiddler and a left-handed Corder) 44 | 45 | Twiddler : Corder 46 | L: 3 47 | M: 2 48 | R: 1 49 | 50 | Modes: 51 | The twiddler has four buttons for the thumb that map to 52 | Num = numbers mode 53 | Alt = alt key 54 | Ctrl = ctrl key 55 | Shift = shift key 56 | 57 | The Nostromo has an 8-way pad for the thumb. We can map those modes like this: 58 | num 59 | ^ 60 | shift < > ctrl 61 | v 62 | alt 63 | 64 | This way (I think), you can push the thumb pad to the lower right and push both ctrl and alt simultaneously 65 | -------------------------------------------------------------------------------- /twiddler_keymap.txt: -------------------------------------------------------------------------------- 1 | O OOLO = "" 2 | O MMOM = "" 3 | S MMOM = "LeftShift+" 4 | S OOOL = "" 5 | N OOOL = "" 6 | O OOOL = "" 7 | S RRRO = "" 8 | N RRRO = "" 9 | O RRRO = "" 10 | O RRRR = "" 11 | O MMMM = "" 12 | NA LLOL = "" 13 | O ROOO = "a" 14 | O OROO = "b" 15 | O OORO = "c" 16 | O OOOR = "d" 17 | O MOOO = "e" 18 | O OMOO = "f" 19 | O OOMO = "g" 20 | O OOOM = "h" 21 | O LROO = "i" 22 | O LORO = "j" 23 | O LOOR = "k" 24 | O LMOO = "l" 25 | O LOMO = "m" 26 | O LOOM = "n" 27 | O LLOO = "o" 28 | O LOLO = "p" 29 | O LOOL = "q" 30 | O MROO = "r" 31 | O MORO = "s" 32 | O MOOR = "t" 33 | O MMOO = "u" 34 | O MOMO = "v" 35 | O MOOM = "w" 36 | O MLOO = "x" 37 | O MOLO = "y" 38 | O MOOL = "z" 39 | O LOOO = " " 40 | O ROLO = "!" 41 | O ROMO = """ 42 | O OMOL = "#" 43 | O OLRO = "$" 44 | O OORM = "%" 45 | O OLOL = "&" 46 | O RMOO = "'" 47 | O OLLO = "(" 48 | O ORLO = ")" 49 | O OOLM = "*" 50 | O OOML = "+" 51 | O RORO = "," 52 | O ROOL = "-" 53 | O RROO = "." 54 | O MMMO = "/" 55 | N OLOO = "0" 56 | N ROOO = "1" 57 | N OROO = "2" 58 | N OORO = "3" 59 | N OOOR = "4" 60 | N MOOO = "5" 61 | N OMOO = "6" 62 | N OOMO = "7" 63 | N OOOM = "8" 64 | N LOOO = "9" 65 | NA ROOO = "" 66 | NA OROO = "" 67 | NA OORO = "" 68 | NA OOOR = "" 69 | NA MOOO = "" 70 | NA OMOO = "" 71 | NA OOMO = "" 72 | NA OOOM = "" 73 | NA LOOO = "" 74 | NA OLOO = "" 75 | NA OOLO = "" 76 | NA OOOL = "" 77 | NA LROO = "LeftAlt+" 78 | NA LORO = "LeftAlt+" 79 | NA LOOR = "LeftAlt+" 80 | NA LMOO = "LeftAlt+" 81 | NA LOMO = "LeftAlt+" 82 | NA LOOM = "LeftAlt+" 83 | NA LLOO = "LeftAlt+" 84 | NA LOLO = "LeftAlt+" 85 | NA LOOL = "LeftAlt+" 86 | NA OLRO = "LeftAlt+" 87 | NA OLOR = "LeftAlt+" 88 | NA OLMO = "LeftAlt+" 89 | O OORL = ":" 90 | O ROOR = ";" 91 | N MOOL = "<" 92 | O OOMR = "=" 93 | N RORO = ">" 94 | O RLOO = "?" 95 | O OOLR = "@" 96 | N RMOO = "[" 97 | O LLLO = "\" 98 | N ROOM = "]" 99 | N LMOO = "^" 100 | O OROL = "_" 101 | N ROLO = "`" 102 | N ROOL = "{" 103 | N LLRO = "|" 104 | N LLOR = "}" 105 | N LLMO = "~" 106 | O OLOO = "" 107 | S OLOO = "" 108 | C LLMO = "" 109 | O ORRR = "" 110 | O OLLL = "" 111 | O OORR = "" 112 | O OOLL = "" 113 | O OMRO = "" 114 | O OMLO = "" 115 | O OMMO = "" 116 | O OMOM = "" 117 | O ORRO = "the " 118 | S ORRO = "The " 119 | O ORMO = "of " 120 | O OROR = "to " 121 | O OMOR = "ed " 122 | O OROM = "in" 123 | O OLOM = "ion " 124 | O ROOM = "and " 125 | O OOMM = "ing " 126 | O MOMM = "ent " 127 | O RORR = "ant " 128 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Chording 2 | 3 | This is a repo to hold code and research related to building my own chording keyboard. This project is mostly for novelty; I am not all that interested in trying to design and build a chording keyboard that is more efficient than QWERTY. And I'm certainly not interested in producing one as a commercial product. 4 | 5 | In a lot of ways, a chording keyboard is not as good as a traditional QWERTY (typewriter layout) keyboard, but it has some strengths. I hope to gain basic proficiency on the chording keyboard, as well as create useful keyboard combos that I can trigger easily through the chording keyboard. (Perhaps by creating vim and emacs modes.) 6 | 7 | The goal is that this chording keyboard will supplement my regular keyboard rather than replace it. 8 | 9 | For reference, see my blog posts on the subject: 10 | 11 | * [Building a Chording Keyboard: Progress So Far](http://blog.mattgauger.com/blog/2013/08/03/building-a-chording-keyboard-lessons-learned-and-progress-so-far/) 12 | * [A Simple Text Editor Foot Pedal](http://blog.mattgauger.com/blog/2013/08/06/a-simple-text-editor-foot-pedal/) 13 | 14 | ## Hardware 15 | 16 | * Teensy 3.0 17 | * Razer Nostromo, heavily modified 18 | * Cherry MX brown switches 19 | * WASDKeyboards numpad key cap set 20 | * Sparkfun joystick (very similar to the XBox controller joysticks) 21 | * Green LEDs 22 | 23 | The blog posts referenced above describe how I built my keyboard and other details. 24 | 25 | 26 | ## Layout 27 | 28 | I am planning to use the [TabSpace layout](http://rhodesmill.org/brandon/projects/tabspace-guide.pdf) (PDF), which was originally designed for the Twiddler chording keyboard, with modifications for this keyboard's layout and for its additional capability for mode switching. 29 | 30 | The current layout can be found in the [TabSpace Reference Sheet](http://rhodesmill.org/brandon/projects/tabspace-ref.pdf) which is the current key layout plan until I have time to use the keyboard and make changes. 31 | 32 | Research on layouts: 33 | 34 | * Previous research file [mapping.txt](https://github.com/mathias/chording/blob/269163b91a91b963d327a7377ae1e71d323541ad/mapping.txt) which references: 35 | * [mtgap - theory of letter frequency](http://mtgap.bilfo.com/theory-of-letter-frequency.html) 36 | * [mtgap - letter frequency](http://mtgap.bilfo.com/letter_frequency.html) 37 | 38 | ## License 39 | 40 | Copyright (c) 2013 Matt Gauger 41 | 42 | MIT License 43 | 44 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 45 | 46 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 47 | 48 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 49 | 50 | 51 | --------------------------------------------------------------------------------