DIY do-it-yourself keyboard


    It all started for me with this topic about mechanical keyboards , the desire to learn how to type faster (to my shame, until recently I used to print with two fingers, despite 25 years of programming experience), and the recent unpleasant sensations in my hands after a working day (and generally, spent at the computer).
    Conducted a short study of what general keyboards are for programmers and those who type a lot, and wrote this review topic. I bought myself Happy Hacking Lite (a minimalist keyboard with membrane switches), but typing on it turned out to be even less convenient than typing on a laptop, mainly due to the even more compact layout of the keys.
    A topic soon appeared in which the authorI talked about Truly Ergonomic, which he had recently acquired, which was perhaps an almost perfect keyboard from my point of view, but in the comments, the author noted that after two months of use he could not completely switch to it, and the position of the hands was not at all as comfortable as advertised.
    A little later, a topic appeared about Kinesis Advantage , which, according to the author’s opinion , is also not easy to get used to, and the price is just scary.


    Researches



    Following the link from the first topic, I went to the sites of fans of keyboard lovers, American and European , on which people finished, remade and made keyboards from scratch. I studied them, learned everything (I will tell you a lot about this topic), what you need to assemble the keyboard from scratch, ordered all the necessary parts and tools, and waited.
    The list of necessities is below, but for now I’ll talk about the two most interesting ergonomic keyboard projects that I found, and which drove the thought “I can too” into my head.

    Bluecube



    Keyboard from a craftsman working for a plastic company.


    Ergodox



    The keyboard , which took place the evolution of Key64 , through DoxKB , and reached to the stage of mass production (although, with the self-assembly of the parts) at a price of $ 200.


    Design



    Both keyboards from the previous section differ from typical keyboards in that they have noticeably fewer keys. This is done due to the rejection of the block of numeric keys, block of arrows and block of function keys. It’s worth considering whether they are often used, and whether it is impossible to press Fn-1 or some other key combination instead of F1.
    The keys on the BlueCube, Ergodox are arranged in even columns, not in even rows. The same key layout is used in Truly Ergonomic, TypeMatrix, and several other keyboards. This is done for two reasons, firstly, the difference in the length of the fingers, the middle one is typically longer than the rest, and the little finger is shorter, and it is not very convenient for all of them to lie on one row. Secondly, when using the fast ten-finger printing method, if you put the index keys on the serif keys, F and J, and the rest on the keys on the sides of them, try to reach the X key with the ring finger of your left hand without moving the other fingers, or the middle left hands up to the C key. Placing the keys in even columns solves both of these problems.
    Another important point used in BlueCube is the combination of modifier keys with keys such as spacebar, Tab, etc. as follows: if the key is pressed alone, then the resulting character is a space, and if the key is pressed and at that moment pressed and then released, another key, for example 'q', then the first key is interpreted as a modifier, for example, Shift, and the resulting the symbol is Q.
    It is also worth noting that the thumb, which is practically not used when typing on a regular keyboard, is more involved here, similar to the keyboards from Maltron and Kinesis. However, the block of keys for the thumbs does not seem so convenient that on ErgoDox (and similar on Maltron and Kinesis Advantage), and on BlueCube, where they have to be bent right down to the base of the little finger.
    Since nothing was holding me back on how the keyboard would look, I decided to just put my hands on the paper and understand where it would be convenient for me to get my fingers out without moving my hands too much. As a result, I got such a sketch:


    which I immediately transferred to the vector editor, but with the keys on which I applied characters, placing them more or less traditionally:


    In total, it turned out that my fingers reach up to 50 keys, and it seems like all the necessary keys are in place (although not always on their own, if you look from the point of view of traditional layouts). Will there be enough 50 keys, given that on traditional keyboards there are 104 keys (in extreme cases, 87 keys, in the variant without a block of number keys)? Using the Fn modifier, this becomes possible, because combinations of letters and Fn are usually not used, and you can hang anything that did not fit on them, but for some reason you need, for example, arrows, Home, End, PgUp and PgDn.
    Brown squares under the wrists indicate soft linings.
    Indicators? I don’t use Caps Lock, there is no separate digital block, so I don’t need NumLock either, but for what many ScrollLock is needed, they probably don’t even know. So I’m sweeping the indicators.
    Slightly confuses the block of keys under the little finger, if someone else decides to use my keyboard, his little finger may be shorter than my seven-octave one, so I decided to make the block under the little finger turning, from, such as in the figure, to parallel to the other column of keys.
    Another aspect is the natural position of the hands, which is closer to the vertical position of the palms rather than to the position with the palms down, which we are all used to. This is one of the reasons why I did not buy the Truly Ergonomic keyboard and did not calm down. This tends to make the keyboard split into two halves, like Kinesis Freestyle and Ergodox with BlueCube, and tilted.

    So, the keyboard according to the plan is bifurcated, with a reduced number of keys, with the thumbs block shifted, vertically aligned columns vertically shifted relative to each other, the left and right blocks are tilted (adjustable, because different sources advise tilting from 15 to 90 degrees relative to a vertical surface, and sliding adjustable blocks under the little fingers, without indicators.

    Details



    A short list of what you need:

    - keyboard switches;
    - caps on the switches;
    - diodes (why are they needed - a little later);
    - a microcontroller that allows the keyboard to be a USB device, and reads the state of the switches;

    Pay



    Since I assess the chance for error-free design of a printed circuit board on my first try as extremely low, I have no experience with LUT and a photoresist, the price of custom production in a single volume is high, I decided to make a mounted wiring. Material - textolite used in conventional printed circuit boards. A friend, fortunately, had several sheets of fiberglass, which I lent. Chic material, in terms of ease of use, comparable only to blue electrical tape.


    Microcontroller



    Despite my youthful enthusiasm for the bright future of ARM-controllers, I nonetheless chose a device based on a more traditional AVR. Of the most suitable for this application, Atmega32u4 was identified, with 32KB of ROM, a sufficient number of input-output ports, operating in USB slave mode, and also able to communicate via I 2 C. The fact that the keyboard would be without a traditional printed circuit board made it necessary take the controller on the remote board, and I chose the most compact - Teensy . There are a lot of options , even from the same manufacturer, and there are even domestic analogues , although for some reason they are more expensive .


    Switches



    The choice of key switches consisted only between mechanical ones from Cherry, a brand known to many for keyboards, and numerous Chinese clones of the now-unavailable Alps switches.
    Cherry produces two main lines of switches, low-profile Cherry ML , and the more frequently used MX , produced in the following main modifications :
    - black (linear pressing force, medium elasticity, not snapping);
    - red (molted, light, not snapping), popular in gaming keyboards;
    - gray (tactile, elastic, not snapping);
    - transparent (tactile, medium elasticity, not snapping);
    - green (tactile, medium elasticity, snapping);
    - blue (tactile, light, snapping);
    - brown (tactile, light, snapping);
    - white (tactile, medium elasticity, moderately snapping).

    Based on my personal preferences, I liked the transparent ones.
    Switches differ in the installation method. There is an option for mounting on a printed circuit board, and for mounting on an additional plate. The former have two additional posts for greater stability, while the latter requires an additional plate for stability. The first option can also be snapped into this additional plate.
    There are many more modifications of the MX, but this is one of those parts that are not so easy to purchase, or not so cheap, especially in small quantities, and in not very popular modifications - and even more so. On Ebay, they sell them for almost $ 4 apiece; electronic component suppliers have very few choices. The great thing is that they organize group purchases on keyboard forums, and I fit into one of them. Unfortunately, I had to either wait or take what was, and I took the blue ones (choosing from red, brown and blue), in the version with installation on a printed circuit board.


    Caps



    Initially, I wanted to buy some old mechanical keyboard, remove the switches from it and remove the caps, but I did not find anything worthwhile.
    Since buying new ones - so choose. WASD Keyboards is a good choice , I decided to try to take different keys, and took a set of 39 keys of the alphabet block, and two sets of color keys for testing, which also come with key dampers to reduce the clicking effect (clicking effect of the caps on the board rather than internal clicking effect of the switch). Larger keys are also needed, and I took a few keys, usually used as Tab (1.5x), Alt (1.25x) and Caps Lock (1.75x), in different colors.
    Nowadays, cylindrical cones are mainly used, in which each row of keys has its own profile.


    I didn’t have a single key from the number row E in my sets:



    Diodes



    Diodes, namely 50 pcs. 1N4148 in DO-35 case, which turned out to be easier and cheaper to buy with delivery from England than in local supermarkets selling electronic components.

    Lego for adults



    Parts and tools.


    Layout



    Iron



    In order not to waste time in vain, I decided to put together a model and touch with my hands what could come of all this and not waste time if I did not like such an intermediate result. Here's what I got:

    A hand (left, I decided to do it by the principle of fitting shoes) lies comfortably, reaches all the keys. Resolved, continue.

    Microcontroller



    Teensy comes with wired firmware called “flashing light”. Surprisingly, when you connect it with a USB cable to the computer, the small diode really starts to blink. There is another firmware on the site for an example, called a “fast blinking light bulb”, I downloaded it and poured it onto the device, and the light bulb really began to flash faster. Filled the original - again slower. Well, that’s pretty good, a strobe can already be done.
    There are small smashes with the source code of an example from a site called “USB Keyboard”, and a space character is printed on the screen every 8 seconds, and when GND is closed with any of the inputs, two characters appear on the screen indicating the port and leg number, for example B1. The current is scanty - 135 μA. Another good luck.

    Theory



    How to connect 50 (and on conventional keyboards more than twice as many) keys to the microcontroller with 25 I / O ports, leaving a few for things like a mouse?
    Everything is quite simple, you need to distribute the keys in rows and columns, forming a matrix. By applying voltage to column A, and removing this voltage from rows 2 and 3, we can understand that now the keys at the intersection of these rows and this column are in the pressed state. The voltage is supplied to the speakers in turn. Thus, roughly speaking, you do not need the number of input / output ports equal to the number of keys, but rather the square root of this number, in my case - 8x7, that is, 8 outputs and 7 inputs (or vice versa).

    However, this method has one serious drawback, which manifests itself in blocking and loss of clicks:

    This figure shows that when the W, E and D keys are pressed, and when the voltage is applied to column B, the S key fails. The diodes are designed to combat this phenomenon and are called on:


    More details can be found here .

    In addition to this, the USB standard introduces a serious limitation for the input devices connected to it, in 6 simultaneously pressed (non-modifying) keys. Some manufacturers circumvent this limitation by emulating the connection of multiple USB devices. Honestly, I came across this restriction only in my youth, when there was no money for a MIDI keyboard, but I wanted to play a bold chord. But so, note.

    A little pause for thought





    At different times it began to seem to me that there were too many keys (yes, no matter how funny it sounds with only 50 keys!). And when I ordered only 50 switches without any reserve, and when I tried to reach the four extreme keys on the layout with my little fingers, and when I began to think that the seventh column of keys would lead to the need to pull an additional wire between the halves of the keyboard in addition to the cable. On top of that, these initially planned keys should have had Escape, Tab, Backspace, and Enter, which are already on the thumb keys. Duplicate does not make much sense. And if you already get used to the new keyboard, then right away, without escape routes.

    Scheme



    The scheme is so simple that there is not even much point in drawing it.


    The columns and rows in the matrix correspond to the keys, the keys of the thumb block are the fourth row.
    We apply voltage from the column to all incoming legs of the switches of this column. From the output leg of the switch - to the anode of the diode. The outputs from the cathodes of all the switches in the string are connected, and connected to the input of the string.
    For the right half of the keyboard, 6 outputs and 4 inputs are required, on the left - 6 more outputs, and the inputs can be used the same. The result is a 12x4 matrix, totaling as many as 18 inputs and outputs, which is somewhat uneconomical. I will use a 6 by 8 matrix, which is easy to imagine as one half of the keyboard, located not on the left, but below the other, resulting in 14 I / O ports.
    It turns out that in the left half of the keyboard will need to lead 10 cores. The pin connectors I bought are only 10 cores, and they are exactly enough.

    The legs on the controller can be in two modes: input or output. The input can be open, in this case, if it is not closed, it can make noise, and it is better to put it into mode with the built-in pull-up resistor turned on, so that if it is not shorted to ground, it will always be in state 1. We set the outputs the default state is 5V, and while reading a specific column we lower it to 0V, so that when it is closed with the input, the latter goes to state 0, which means pressing a button. This connection option leads to some misunderstanding in the form that the current "flows" from the inputs to the outputs.
    There are other connection options where everything is more or less logical, but they provide additional external elements, such as one for all outputs or several external resistors (to save ports with reading through the ADC), but it seems to me that if there is a controller with enough by the number of ports, he himself must cope with how he has locked a leg where, therefore - the easiest option, although at first glance it is not the most understandable.
    The legs of the microcontroller on Teensy are not all displayed, but those that are displayed go differently. Of the "solid" ports, there are only B. Partially derived - F (no legs F2, F3), D (two legs on the bottom end of the board, do not have legs, and two more are combined with I 2 C, C (there are only legs C6 and C7).

    On the microcontroller we use the legs PF0, PF1, PC6, PC7, PF4-PF7 we use for the outputs, PB0-PB5 for the inputs (with a pull-up resistor). Leave the legs PD0 and PD1 under I 2 C, which will come in handy later for connecting a mouse / trackpoint. We don’t touch the PD6 leg, because it is connected to the LED located on the board, which can be powered by the current supplied to this leg and lower the voltage from 5V to ~ 1.7V.

    Iron



    Pay



    Textolite is intended for etching conductive tracks on it. Since this is not necessary in my case, the foil will have to be removed from it. To do this is not so simple, since it is much thicker and stronger than the one that we are all used to removing from chocolates. It is difficult from the very beginning - to hook the corner of this foil, then, if you shoot it with thick strips, you have to apply a lot of force, but if thin - strives to break, and you have to look for the corner again. I was able to identify a fairly simple way: to hook from an angle, and a strip of 1-1.5 cm lead in a spiral to the center of the board.

    Interesting patterns remain on the PCB, allowing us to understand exactly how the foil was removed.


    I highly recommend wearing gloves and removing the foil with pasters, otherwise scratches are inevitable.

    Drilling



    I made a sketch of how the switches should be located on the board (boards, because it turns out at least 4 pieces, and for a better layout on the PCB, as many as 6 pieces). In order for them to be fixed on it, the board needs to be drilled. For each switch, there are 7 holes, two 0.8mm, two 1.2mm, two 1.6mm, and one central 4mm.
    Drilling directly from the printout is not very convenient, so I made a stencil from the old aluminum back cover of the mobile phone:


    Cutting and drilling aluminum is not an easy task, it heats up, flies in all directions, so I recommend using special safety glasses. As during other operations.
    This is what a switch inserted into the stencil looks like.



    Alas, the drill cam chuck is designed to drill with a tail of a maximum diameter of 3.4mm, but the 3.5mm drill bit is quite stable. To drill 4mm holes he had to make several circular motions. I do not recommend repeating this.
    Originally drilled on a wooden substrate, and somewhere on the hundredth hole, the 0.8mm drill bit broke under the root due to the fact that the textolite moved relative to the substrate at the moment the drill was lowered. Later he drilled so that there was nothing under the tektolite.



    It turned out one not too pleasant thing related to the switches. If they are pushed into holes that are not exactly drilled, it lends itself to deformation, and its tactile properties change, to the extent that it does not click, and can even stick. I drill holes wider. Later I decided to drill with an ordinary drill and a 4mm drill, but still half of these large holes have to be scooped up so that the switches enter without much effort.

    Here's what


    happened : It feels like the switches sit very tight on the board, do not stagger, everyone entered the board without much effort. After soldering, they will sit tight. Honestly, quite an unexpected result for such a makeshift work, I am pleased with myself.

    Despite the obvious unevenness of the hole lines with a pitch of 2.54 mm, the microcontroller and IDC connector got up effortlessly and tightly:




    Diodes again



    There are two options, the first is to solder the diodes in a hinged manner, not the easiest option, given how many wires there will be soldered. The second option is to disassemble the switches, and instead of the wire there, designed to facilitate the wiring of a single-layer printed circuit board, insert a diode. Yes, this is a certain work, but it should pay off by simplifying the hinged installation. There is a third, correct option, to buy diode switches right away, but the latter, for some unknown reason, are not at all popular, and there is nowhere to buy them, except to order a large batch directly from Cherry.





    Cutting



    The boards need as many as 6 pieces. Theoretically, it was possible to make two, but 1) the size of the tectolite pieces does not allow 2) even if it did, it would not be very economical 3) it is possible to play with the position of the boards relative to each other during assembly.



    Board to Board Connections



    In order to not have to pull the wires between the halves of the keyboard, I used cables similar to those used to connect hard drives to the motherboard, with only fewer cores, and IDC / BH connectors. Of course, it would be more correct to use a twisted pair, but I need more than 8 wires, and the 8P8C connector is also not too compact (and 10P10C and 10-core twisted pair are not so easy to find). Another option would be to use an I / O port multiplexer on the I 2 C bus , but I decided to postpone this improvement.
    By the way, the IDC connectors for the angular and straight I got completely different. The straight did not solder in any way, and the legs fell out of it at the slightest heating, and the corner soldered well. Outwardly, they were no different.


    Soldering



    I can say one thing about soldering - this is not my hobby. Slowly, but it works.


    Firmware



    Attempt at writing



    So, I got a piece of the keyboard, and it's time to check if all this works as I expected.

    Teensy comes with a number of examples, including the USB HID (Human Interface Device), in keyboard and mouse options. The firmware has grown from the first of these examples.
    In the original example, the calculation is based on the fact that the inputs are closed by switches on the ground, and with a matrix connection everything is a little different, voltage is periodically applied to part of the legs, and during this period the state of the other legs is read. In order for the legs to work as outputs, you need to transfer them to this mode.
    In general, the order is as follows: initialize the ports and USB; in the cycle, alternately apply voltage to the outputs, read the inputs, if the value at the input corresponds to the pressed key, but in the previous reading cycle it was not pressed - send the key code via USB.
    I’m not a big expert in C, and when it comes to digging in macros, I’m a little lost, so the code can be a little awkward, but the general idea should convey:
    May the reader forgive my habit of making comments in English.

    Firmware code
    #include 
    #include 
    #include 
    #include 
    #include "usb_keyboard.h"
    #define CPU_PRESCALE (n) (CLKPR = 0x80, CLKPR = (n))
    uint8_t matrix [8] [8] = {
    / * B0 * / {KEY_TILDE, KEY_Q, 0, 0, KEY_W, KEY_E, KEY_R, KEY_T}, // Top row
    / * B1 * / {KEY_SLASH, KEY_A, 0, 0, KEY_S, KEY_D, KEY_F, KEY_G}, // Home row
    /*B2*/  {KEY_LEFT_BRACE, KEY_Z, 0, 0, KEY_X, KEY_C, KEY_V, KEY_B}, // Bottom row
    /*B3*/  {0 /*Fn*/, KEY_ENTER, 0, 0,  KEY_TAB, KEY_ESC, KEY_SPACE},
    /*B6*/  {KEY_Y, KEY_U, 0, 0, KEY_I, KEY_O, KEY_P, KEY_EQUAL}, // Top row
    /*B5*/  {KEY_H, KEY_J, 0, 0, KEY_K, KEY_L, KEY_SEMICOLON, KEY_QUOTE}, // Home row
    /*B4*/  {KEY_N, KEY_M, 0, 0, KEY_COMMA, KEY_PERIOD, KEY_SLASH, KEY_RIGHT_BRACE}, // Bottom row
    /*D7*/  {KEY_SPACE, KEY_ESC, 0, 0,  KEY_TAB, KEY_ENTER, 0 /*Fn*/}
    };
    int main(void)
    {
      uint8_t state=0, prev_state[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
      setup_pins_and_usb();
      while (1) {
        // B0
        PORTB = 0b11111110;
        _delay_ms(5);
        state = PINF;
        read_row(state, prev_state[0], matrix[0]);
        prev_state[0] = state;
        // B1
        PORTB = 0b11111101;
        _delay_ms(5);
        state = PINF;
        read_row(state, prev_state[1], matrix[1]);
        prev_state[1] = state;
        // B2
        PORTB = 0b11111011;
        _delay_ms(5);
        state = PINF;
        read_row(state, prev_state[2], matrix[2]);
        prev_state[2] = state;
        // B3
        PORTB = 0b11110111;
        _delay_ms(5);
        state = PINF;
        read_row(state, prev_state[3], matrix[3]);
        prev_state[3] = state;
        // B6
        PORTB = 0b10111111;
        _delay_ms(5);
        state = PINF;
        read_row(state, prev_state[4], matrix[4]);
        prev_state[4] = state;
        // B5
        PORTB = 0b11011111;
        _delay_ms(5);
        state = PINF;
        read_row(state, prev_state[5], matrix[5]);
        prev_state[5] = state;
        // B4
        PORTB = 0b11101111;
        _delay_ms(5);
        state = PINF;
        read_row(state, prev_state[6], matrix[6]);
        prev_state[6] = state;
        PORTB = 0b11111111;
        // D7
        PORTD = 0b00000000;
        _delay_ms(5);
        state = PINF;
        read_row(state, prev_state[7], matrix[7]);
        prev_state[7] = state;
        PORTD = 0b10000000;
      }
    }
    void read_row(uint8_t state, uint8_t prev_state, uint8_t keys[]) {
      uint8_t mask, i;
      mask = 1;
      for (i=0; i<8; i++) {
        if(((state & mask) >> i) == 0 && ((prev_state & mask) >> i) == 1 ) {
          usb_keyboard_press(keys[i], 0);
        }
        mask = mask << 1;
      }
    }
    void setup_pins_and_usb() {
      // set for 16 MHz clock
      CPU_PRESCALE(0);
      // Configure PB0-PB6, PD7 as outputs, high state
      DDRB = 0b01111111;
      DDRD = 0b10000000;
      PORTB = 0b01111111;
      PORTD = 0b10000000;
      // Configure PF0, PF1, PF4-PF7 as inputs, pullup enabled
      DDRF = 0x00;
      PORTF = 0xFF;
      // Initialize the USB, and then wait for the host to set configuration.
      // If the Teensy is powered without a PC connected to the USB port,
      // this will wait forever.
      usb_init();
      while (!usb_configured()) /* wait */ ;
      // Wait an extra second for the PC's operating system to load drivers
      // and do whatever it does to actually be ready for input
      _delay_ms (1000);
    }
    



    Checked - it works. Luck.

    Firm firmware



    You can continue to fence the garden here too, but in firmware there are no less subtleties than in iron. And it occurred to me to use ready-made firmware. Of the available on the network, two seemed most noteworthy:
    Clavis . Used in one mod of the old Wyse WY-85 terminal keyboard. In principle, it looks pretty customizable, but out of the box there are not enough features that are in the second firmware.
    Keyboard TMK . Very seasoned firmware used in the top ten (if not tens) keyboard mods and homebrew keyboards. Out of the box has the following features:
    - layering layouts (you can use one layer for additional useful characters, like a typographical hyphen, etc.);
    - emulation of mouse movements using keys;
    - Can send system key codes: Power Down, Sleep, Wake Up, Volume Down / Up, Mute, Next / Prev track, Play, Stop and others;
    - transfer of many simultaneous keystrokes (not limited to a USB limit of 6 keys);
    - customizable to the smallest detail;
    - works with keyboard “tricks”, namely, it knows how to use the same physical keys for different purposes, depending on the type of keystroke;
    - console debugging firmware.

    At first, there was a problem with sticky keys, but by the time I finished everything, the problem had already been solved. My code can be found here..

    Layout
    #define KEYMAP( \
      K00,K01, K02,K03,K04,K05,        K40,K41,K42,K43, K44,K45, \
      K10,K11, K12,K13,K14,K15,        K50,K51,K52,K53, K54,K55, \
      K20,K21, K22,K23,K24,K25,        K60,K61,K62,K63, K64,K65, \
        T30,T31,T32,T33,T34,              T70,T71,T72,T73,T74   \
    ) { \
      {  KC_##K00, KC_##K01, KC_##K02, KC_##K03, KC_##K04, KC_##K05 },\
      {  KC_##K10, KC_##K11, KC_##K12, KC_##K13, KC_##K14, KC_##K15 },\
      {  KC_##K20, KC_##K21, KC_##K22, KC_##K23, KC_##K24, KC_##K25 },\
      {  KC_0,     KC_##T30, KC_##T31, KC_##T32, KC_##T33, KC_##T34 },\
    \
      {  KC_##K40, KC_##K41, KC_##K42, KC_##K43, KC_##K44, KC_##K45 },\
      {  KC_##K50, KC_##K51, KC_##K52, KC_##K53, KC_##K54, KC_##K55 },\
      {  KC_##K60, KC_##K61, KC_##K62, KC_##K63, KC_##K64, KC_##K65 },\
      {  KC_##T70, KC_##T71, KC_##T72, KC_##T73, KC_##T74, KC_0     } \
    }
    static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
    /** Layer 0: (lowercase char)
     *
     *   ` q w e r t    y u i o p =
     *   \ a s d f g    h j k l ; '
     *   [ z x c v b    n m , . / ]
     */
     KEYMAP( \
        GRV,   Q,   W,   E,   R,   T,      Y,   U,   I,   O,   P, EQL, \
       SLSH,   A,   S,   D,   F,   G,      H,   J,   K,   L,SCLN,QUOT, \
       LBRC,   Z,   X,   C,   V,   B,      N,   M,COMM, DOT,BSLS,RBRC, \
          FN0, FN1, FN2, FN3, FN4,           FN9, FN8, FN7, FN6, FN5   ),
    /** Layer 1: (symbols and navigation)
     *
     *     1 2 3 4 5    6 7 8 9 0 -
     *       ↰ ↑ ↳ ⤒    ← ↓ ↑ →  
     *       ← ↓ → ⤓    
     */
      KEYMAP( \
         NO,   1,   2,   3,   4,   5,      6,   7,   8,   9,   0,MINS, \
         NO,  NO,PGUP,  UP,PGDN,HOME,   LEFT,DOWN,  UP,RGHT,SCLN,QUOT, \
         NO,  NO,LEFT,DOWN,RGHT, END,     NO,  NO,  NO,  NO,  NO,  NO, \
          FN0, FN1, FN2, FN3, FN4,         FN9, FN8, FN7, FN6, FN5   )
    };
    /*
     * Fn action definition
     */
    // TODO: use [1] = KEYMAP(...) to prevent from changing index of element?
    static const uint16_t PROGMEM fn_actions[] = {
        ACTION_LAYER_TAP_KEY(1, KC_SPC),                 // FN0 = L1 symbols 
        ACTION_MODS_TAP_KEY(MOD_LSFT, KC_SPC),           // FN1 = Shift with tap Space
        ACTION_MODS_TAP_KEY(MOD_LCTL, KC_ESC),           // FN2 = Ctrl with tap Escape
        ACTION_MODS_TAP_KEY(MOD_LALT, KC_TAB),           // FN3 = Alt with tap Tab
        ACTION_MODS_TAP_KEY(MOD_LGUI, KC_DEL),           // FN4 = Meta with tap Del
        ACTION_LAYER_TAP_KEY(1, KC_ENT),                 // FN5 = L1 symbols 
        ACTION_MODS_TAP_KEY(MOD_RSFT, KC_ENT),           // FN6 = Shift with tap Enter
        ACTION_MODS_TAP_KEY(MOD_RCTL, KC_BSPC),          // FN7 = Ctrl with tap Backspace
        ACTION_MODS_TAP_KEY(MOD_RALT, KC_RALT),          // FN8 = Ctrl with tap Backspace
        ACTION_MODS_TAP_KEY(MOD_RGUI, KC_TAB)            // FN9 = Meta with tap Tab
    };
    



    Матрица
    /* Column pin configuration
     * col: 0   1   2   3   4   5
     * pin: F0  F1  F4  F5  F6  F7
     */
    static void  init_cols(void)
    {
        DDRF = 0b00000000;
        PORTF = 0b11111111;
    }
    static matrix_row_t read_cols(void)
    {
        return (PINF&(1<<0) ? 0 : (1<<0)) |
               (PINF&(1<<1) ? 0 : (1<<1)) |
               (PINF&(1<<4) ? 0 : (1<<2)) |
               (PINF&(1<<5) ? 0 : (1<<3)) |
               (PINF&(1<<6) ? 0 : (1<<4)) |
               (PINF&(1<<7) ? 0 : (1<<5));
    }
    /* Row pin configuration
     * row: 0   1   2   3   4   5   6   7
     * pin: B0  B1  B2  B3  B6  B5  B4  D7
     */
    static void unselect_rows(void)
    {
        // Hi-Z(DDR:0, PORT:0) to unselect
        DDRB = 0b01111111;
        DDRD = 0b10000000;
        PORTB = 0b01111111;
        PORTD = 0b10000000;
    }
    static void select_row(uint8_t row)
    {
        // Output low(DDR:1, PORT:0) to select
        switch (row) {
            case 0: PORTB &= ~(1<<0); break;
            case 1: PORTB &= ~(1<<1); break;
            case 2: PORTB &= ~(1<<2); break;
            case 3: PORTB &= ~(1<<3); break;
            case 4: PORTB &= ~(1<<6); break;
            case 5: PORTB &= ~(1<<5); break;
            case 6: PORTB &= ~(1<<4); break;
            case 7: PORTD &= ~(1<<7); break;
        }
    }
    



    Ещё одна пауза на раздумьё



    Another very interesting instance of a home-made keyboard caught my eye , which differs from the rest in the simplicity of design, namely the plate on which the switches are mounted.
    Not only are the contacts sticking out from the bottom of the board, but now they are all hung with wires. You need something like a bottom cover. The pieces of the board are scattered, and securing them together reliably and firmly on the posts I bought for connecting printed circuit boards and cogs is not an easy task. It would be ideal if it also served as a stand, giving the entire structure the desired slope.

    A network search showed that plexiglass has a number of unique qualities, such as light weight, ductility when heated to 140 degrees, the ability to cut with a laser and a cutting machine, drilling, and also a very low cost.
    It seems that the PCB project was the wrong engineering decision, and I bought a 1.5mm thick plexiglass sheet.


    To everything else, I tried on, and it seemed to me that the distance between the buttons for the thumbs was too big, I decided to slightly reduce it, literally move it by a millimeter, but this will bring the far key closer by almost half a centimeter. I tried to use the keys of the standard 1x size, with them it would be possible to compact a little more, but to press them with the side surface of the thumb was not at all so convenient.


    Housing



    Many have already ceased to notice what the price tags and stands for goods in the store are made of, and they are usually made of this very plexiglass. There are two ways to bend, the first is heating with a blowtorch along the bend line, and bending along a wooden ruler. It is fraught with bubbles in the material, fire, and everything else low accuracy. The second method is bending under its own weight along the heated wire. Quite a suitable way for a fairly thin Plexiglas.

    Bending test



    I needed: a meter of nichrome wire, four screws, a board. Some manuals on the Internet say that nichrome wire stretches when heated, and it is imperative to use a stretch patch. According to my conservative estimates, according to Wikipedia, the increase in the volume of nichrome is a little less than a millimeter when heated at 200'C and a wire length of 30cm.
    Before bending, it is very important not to forget to remove the protective film from the plexiglass.


    Attempts to heat the wire with a ceramic element of the soldering iron failed, as did the universal power supply at 1A, turned on at 1.5V. The resistance of a section of wire 30 cm long is about 1 Ohm, and at a current of 1A, a power of 1 W is obtained, which, according to calculations, can heat the wire to 150'C in 500 seconds, and only if it does not cool down, and it will.
    Something more powerful was needed, and I took the old AT power supply and connected the ground and 5V to the ends of the wire. The effect was not long in coming, the wire very quickly heated to a temperature when a drop of water on it instantly evaporated.


    The wire is still stretched, and so much that it sags a couple of millimeters, which makes the fold line uneven, and on the sides it fits better with the bent sheet, heats it more, even slightly melting it. Of course, it will work for the test, and those “stretchers” in the form of carpentry dowels are enough, but to make it beautiful and even, you need something more reliable.



    The design is strong, it bends very slightly, the laptop sits on it like a glove.


    Palm rest



    I did not find an analogue of the English wrist rest in Russian, so let it be “emphasized”, although it is understood that this is the thing on which the brush rests when the wrists rest on it. I got from my wife bought a keyboard stand-manipulator (worthy of a separate post), there was emphasis for the keyboard, and for the mouse. The latter was not in demand from his wife and therefore I did not fail to use it for my own purposes.

    Since the emphasis is one, and the keyboard has two halves, it will have to be cut in half. Better yet, remove all the scratching smooth surfaces of the staples.



    And it’s convenient to connect to the structure.

    The hand rests on this comfortably, and you can find several positions in which it is completely relaxed.
    Inside there are two layers of gel, the inside is stiffer, and outside, under a layer of faux leather, softer, and even a little sticky.

    So that the design does not slip on the table, I bought special adhesive legs.

    Cutting



    In order for the switches to stand on the plexiglass, it is necessary to make a slot in it for them, and snap it into place. Slots are made on proprietary equipment, but it is done quickly and is not expensive.



    In the first version of the plexiglass case, I made holes a little larger than necessary, about 0.3 mm, and the switches walked a little noticeably horizontally. Version two gave me the opportunity to slightly adjust the location of the keys under my thumbs, not to use engraving (in the place of engraving the material becomes thinner by as much as a third), and actually reduce the size of the holes.
    With version two there was the following problem. On the bottom (second version) the switches do not click (such small things on the top and bottom in the middle of each switch). At first I thought that I had reduced the holes too much, but it turned out (!!!) that the thickness of the acrylic sheet 1.5mm can reach 1.8mm, and that the switches are designed for 1.5-1.68mm. I did not expect such a setup, but I was lucky that I ordered four “halves” at once, and two of them turned out to be of normal thickness, and the switches clicked into them perfectly.



    Softeners



    Many people remember that mechanical keys are very noisy. This is connected not only with the operation of the mechanism, but also with the fact that after the switch is triggered with a strong and fast pressing, the key goes all the way to the stop, and it hits this stop. To level this effect, there are special rubber rings that prevent touching. There are many types of them, including in my set there were 3 different types of them.


    I decided to try everything, although limited in quantity. Black went to the "home" line, red - up, blue - down. The color keys and the extreme column speakers did not get.


    Controller mount



    I had SP3 board racks, and I tried to drill holes in plexiglass, but somehow they didn’t fit too well even 5mm, and my limit for precise drilling was 3.5mm, so I bit off their fasteners, drilled along the axis, and attached the controller in such an unpretentious way, passing the twisted pair wires around.




    It keeps just fine.

    Yes, of course I had to re-solder almost everything anew, but having any experience in this matter is already a little easier and faster. I changed the assignment of inputs and outputs a bit, so that it is easier with loops and IDC connectors (PF0, PF1, PF4-PF7 for outputs, PB0-PB3 for inputs of the left half, PB4-PB6, PD7 for inputs of the right half).



    Flexion



    Test bending was not so bad in principle, but I wanted to make the bend line evenly, and I attached a spring taken out of the door lock with a latch.




    Keyboard Labels



    Despite the fact that with a specific layout I have not yet decided whether to use QWERTY, Colemak , Workman-P or something else, but I have already chosen a font for the keys, this is Neuropol Nova from Typodermic. Selected due to futurism, excellent design and the ability to make a stencil. In addition, the author kindly agreed to use this commercial font for my purposes. The stencil is cut in the same place as plexiglass, and looks something like this:


    Layout



    Current layout: Russian letters are on the same keys as usual. The location is standard, only the letter X has left left down, to the left of I. A number of modifiers (colored) include both modifier keys and regular ones. Modifiers work when pressed in combination, and when pressed once - normal. One-time: Combination: Second layer, works in combination with red keys. The shooter, in my opinion, is even too much. Two options, for Vim fans - on the right (hjkl), and for WASD fans - on the left (dxcv actually).
    ` q w e r t y u i o p =

    \ a s d f g h j k l ; '

    [ z x c v b n m , . / ]







    Рыж Жлт Зел Роз Сир Сир Роз Зел Жлт Рыж

    Spc Spc Esc Tab Del Tab AGr Bsp Ent Ent



    Lr1 Sft Ctl Alt Met Met AGr Ctl Sft Lr1



    1 2 3 4 5 6 7 8 9 0 -

    ↰ ↑ ↳ ⤒ ← ↓ ↑ →

    ← ↓ → ⤓


    Summary



    Labor costs



    Soon the topic is being read, but soon the matter is being done.
    If I had originally designed the design correctly, then in principle it would have taken about 10 hours. And so, two months to wait for some details, and another three months to assemble and refine all this.

    Finance



    DetailPrice
    Teensy 2.0 microcontroller with legs780
    Cherry MX MX1A-E1JW Switches (Blue)1110
    Switch caps900
    Plexiglass150
    Plexiglass cutting350


    Total: 3290 rub.

    I did not include such trifles as solder, wires, cable, connectors and diodes. The latter I got extremely inexpensive, despite the expensive delivery, but if you spread on the total amount ordered, it turns out that something is about 25 cents per piece at a store price of 6 rubles.
    I got a free wrist rest; you can buy it for about $ 20.
    I spent quite a lot on tools, but it will come in handy more than once. Some inexpensive ones (tweezers with heat-resistant plastic levers that immediately melted at 200'C, a magnifying glass through which you can’t see anything, wire cutters that don’t really bite) were cheap, but they didn’t last very long.

    Impressions



    While typing on this keyboard is not so much. Surely I will find what to improve in the layout. In general - it is convenient, even very.
    I foresee comments like “what about the xxxx key?”. In my tmk_keyboard modification, only two layers are involved. You can add at least 30 more, and push all the possible keys there.
    For comments like "how do you press the keyboard shortcuts xxx + yyy + zzz?" I can answer that I specially chose software for myself so as not to torment my fingers (Linux, Awesome, Vim, Chromium + Vimium, Zathura). The most difficult combination of those that I use is Ctrl + Meta + [1-9], combining several virtual desktops for the current one. Now it works by pressing the orange, green, lilac and the number keys on the top row, it is not too convenient, but I definitely will figure out how to make it easier.

    Improvements I want to make in version 2



    Found a great NXP PCF8574AP I / O port expander in a DIP package. You can replace the circuit board with a thin four-wire cable. I do not understand yet whether it is worth contacting I 2 C, according to rumors, the protocol is very slow, and a lot of time in the firmware is spent on it. Alternatively, use the shift registers 74HC164 and 74HC165.

    There is a strong desire to replace Teensy with bare AVR with the number of inputs and outputs sufficient for one half of the keyboard, and entrust the second half to PCFs. There is another option to make on the basis of the microchip from Microchip, PIC18F25K50, it is even cheaper, and among other things, it does not need an external quartz to work with USB.

    Make a printed circuit board so that there is no such mounting, preferably thin and bendable. Ideally, it should already solder all components, such as a controller, diodes, capacitor, programming button.

    Add a trackpoint on the Hall sensor, preferably between the HJNM keys, and three buttons under the mouse (possibly use keyboard keys). Until I realized where it would be convenient for hands to find them.

    Try to transparent or red (here after this memo) Cherry MX switches.

    Make a case of 1.5mm plywood instead of plexiglass. It doesn’t look so beautiful, but. Plywood is easy to process, less fragile. With proper processing, it is quite durable and resistant to moisture. It is harder to bend, but with such a thickness it should not be so hard. To everything else, you can make a design from several sheets by making slots and pins so that it can be assembled-disassembled, according to the principle of Lego. There is confidence that the thickness of plywood does not walk on the sheet area by + 20%, unlike plexiglass.

    Make an inexpensive, adjustable in position and with mount for both halves of the keyboard arm-manipulator, mounted on a flat surface.

    PS
    And yes, of course, how could I forget!

    Also popular now: