My quest for the ideal keyboard switch

01.06.2021 Permalink

Last year I built my first ergonomic mechanical keyboard with brown (tactile) switches. After an initial phase of training I am very happy with the layout and keymap. Typing has become much more relaxed, there's no need to ever look at the keyboard to find a key, and my hands always remain in the same position.

There is actually a wide variety of keyboard switches out there so as I was striving for the perfect personal keyboard experience I was curious about how other switches felt like.

So, I used the last 12 months to build 4 more boards with the exact same design but different colors of acrylic plates, a pair made of poplar plywood and different switches. Here's how they turned out:

Dark anthracite acrylic plates, Cherry MX Red switches (linear 45g, lubed). Never thought that I appreciate linear switches that much.

Translucent acrylic plates, covered by a stickerbomb, again Cherry MX Red switches (linear 45g, lubed). Initially, I didn't plan to cover the board with stickers. But unfortunately, the glue created an ugly look on the translucent plates so I used the stickers as a rescue.

Poplar plywood clear coated, Cherry MX Black switches (linear 60g, lubed). This very light wood makes the keyboard weigh only 280g. It is very quiet and I use it while sitting on the couch.

Poplar plywood yellow painted, Kailh Speed Copper switches (tactile, 50g, shorter travel distance, lubed, dampening O-rings). Actually much more tactile than any MX Brown or clone. The typing sound is considerable though. This is now my daily driver in the office.

And here's my first build again with white acrylic plates. I replaced the brown switches with Kailh BOX White switches (click-bar, 55g, shorter travel distance, dampening O-rings) to see if I like the sound and feeling. To me, in terms of clickyness it is by far superior to any click-jacket based switch like MX Blue or clones.

While it is fun and relaxing to build these boards it also served a serious purpose: find the ideal switch for me. Impressions from typical switch testers are limited because you can't do actual work with one of the switches.

What did I learn about switches and what type do I like best?

My very personal summary for the time being: MX Blacks are my leisure time switches, but for serious writing I use Copper Speed or MX Red. But who knows? There are still many more switches to try, so maybe I'll do some more builds just to find out.

Six years of professional Clojure development

10.05.2021 Permalink

Over the last couple of years me and my colleagues here at doctronic have been busy creating and maintaining more than a dozen of individual software systems for our clients.

We have the privilege to almost exclusively use Clojure and ClojureScript, as this is still the valid strategic technology decision made by doctronic shortly before I joined them in 2015. In this post I'd like to list some of the strengths and weaknesses in everyday real-life use of the language and its ecosystem.

Stability of the language and libraries: Anyone who ever created software of practical value for paying customers knows that reliability of core language constructs and libraries is important. It supports predictability, and eventually saves you from insanity whenever you want to benefit from performance improvements or bug fixes. Upgrading to a new version of a library or even Clojure itself is risk-free. The authors and maintainers really do care about stability. If you listened to talks of Rich Hickey or Stuart Halloway you know that this is no coincidence. "Don't break things!" is part of the culture.

Code size: If you compare some of the idiomatic code snippets in Clojure with the equivalents in more popular languages you might conject that whole Clojure code bases might in general be smaller compared to what you can achieve in other languages. Now, after having worked more than 20 years with imperative OO languages and more than 5 years with Clojure I can firmly state that you'll achieve the same functionality with a fraction of the amount of code. This impacts costs: My feeling is that we now build systems with only half of the staff that I used to have on projects with a comparable scope.

Finding staff: Clojure's popularity is still far, far behind imperative general purpose languages like Java or Python, so fewer people feel encouraged to invest the time to learn the concepts and gain practice. It seems that this makes hiring harder. doctronic addressed this challenge by positioning itself as a supporter of the language in Germany through organizing and sponsoring the annual :clojureD conference. This helps greatly with staffing. But even if a company has a lower visibility, the fact that it uses Clojure will attract aficionados of advanced programming languages. If these developers do enjoy their workplace they will usually stay around longer with their employer. So I'd argue that you gain quality in skills and a lower turnover rate, but it might take more patience to build up a team of Clojure developers.

Teaching the language to apprentices: doctronic constantly employs apprentices so I was able to accompany some of them and help them learn Clojure. Young minds with very few programming experience are remarkably fast in picking up the language and become productive, it seems. I assume there are two main reasons for this: There's actually a whole lot of things they don't need to master compared to OO land. And they don't need to unlearn anything, in other words, they don't need to overcome old habits of doing things.

Some discipline required: Clojure is a language that gives us a wide range of options to implement solutions. And it imposes very little ceremony. For example, there is no static type system that checks your code upon compilation, but you can get some of the benefits for your data at runtime by using Clojure spec. This also serves as documentation and possibly a generator for test data. It is up to the team to decide when and where more checks, restrictions and tests have to be added. If the team misses out on this the code base might be harder to understand and maintain than necessary. In essence: with great freedom comes great responsibility.

Navigating the code: When maintaining or extending an existing code base you often need to find specific places where a function or a piece of data is referenced. To support this kind of search for specific identifiers it is important that naming is self-explaining and consistent, even more so because there are no links established via a type system. To mitigate this weakness in Clojure, you should use qualified keywords whereever possible.

Documentation becomes more important: When you're trying to understand a function that invokes other, non-core functions you'll need a clear idea what kind of data these functions expect and return. Without any data type declarations the code itself often doesn't reveal how the data that flows through you functions looks like. You'll need either Clojure spec or more thorough documentation to mitigate this problem. It is not so rare that you need to test functions of interest isolated in the REPL to get a clear idea how the data looks like.

The promise of purity: Any practical software application must cause some side-effects. So even if Clojure strongly encourages developers to create pure functions your systems will contain substantial parts that either depend on some environment or cause side-effects. The trick is to separate these pieces sharply and keep the unpure parts small. Without any discipline you could easily spread side-effects everywhere and end up with the typical imperative mess. Clojure makes it easy to create a mostly pure implementation but it does not enforce this. To ensure this and other qualities the teams at doctronic conduct code reviews for almost every commit before it is promoted into the master branch.

Reusability: Here's where Clojure really shines. Because most functions are pure and operate on few common data structures (mostly maps, vectors and sets) it is very easy to write reusable code. We created many internal libraries just by separating the candidate functions into their own namespaces within the regular project source tree. To finally establish the library we move the code from the project repo into a new Git repo and include the resulting library Jar in the project.clj as dependency. Thus, we have a very lean process that results in production-quality reusable assets.

Startup time: Starting a fresh JVM with a Clojure Uber-Jar to bring up an application takes noticable time. I assume that JVM class loading causes this delay. So if you consider to create a command line tool that has a short net execution time you wouldn't want this runtime overhead.

Runtime stability: Clojure applications are in general very stable. I remember that in bigger Java projects from my past we always had to do some load testing in order to detect programming flaws like memory leaks or race conditions. With Clojure, we do load testing only to find real performance issues.

Ok, time to come to an end before this post becomes too long. The list is perhaps not complete, but I guess I included the most important aspects that recently popped into my mind. When I decided to fully jump on this train in 2015 I expected more unpleasant surprises. Now, six years later I have proven to myself that Clojure and ClojureScript are a practical and sound choice for real world software development, and I still enjoy using them.

A handwired ergonomic keyboard

21.06.2020 Permalink

In a recent post I explained how QMKs Mod-Tap feature helps me to keep my fingers on the home row, which finally enabled me to use touch typing for software development where I often have to use keyboard shortcuts involving one or more modifiers.

QMK with its multi layer support is a game changer insofar as your keyboard becomes like a stack of blank sheets upon which you can draw your keys just the way they fit your needs. However, there is an obvious limit. The physical placement of keys can not be changed like software. Just look at how the fingers of your left hand are supposed to travel across the keys:

While the fingers of your right hand can move in an almost natural way, you have to twist your left hand and its fingers in order to reach the keys as intended. In other words, the classical arrangement of keys isn't ideal for human hands.

Split keyboards are a consequential answer to this problem, and since I was in the middle of rethinking how I like one of my most important tools to be, I decided to search for a different layout.

The Atreus 42 is an open-source split keyboard in one piece with two panels, one for each hand, designed by Phil Hagelberg who is also the original author of Leiningen, Clojure's build tool. It is ultra compact and can even be used on your lap while sitting on the couch. It is sold by Keyboardio and FalbaTech. There is also a 62 key version, with a row dedicated to all the modifiers plus a dedicated number row, but since I'm fine with the Mod-Tap way of QMK, I wanted something in between.

There's a nice online tool for drawing realistic keyboard layouts, so I created some drafts. I printed my drafts on sheets of paper to get an impression of how the layout would fit my hands. And this is the layout I finally came up with:

Ok, a nice vision, but how can I realize the necessary piece of hardware?

When building a custom mechanical keyboard you typically need to have theses parts in place:

Real enthusiasts might also use some foam and lube to reach the ideal feel and sound.

It took some time and patience until I had everything in place that I needed to create an Atreus like keyboard on my own.

The case

The Atreus was initially developed as a DIY kit, so it has a DIY friendly sandwich design, that is, the keyboard is assembled by mounting a number of laser-cut plates. With this idea in mind I started to draw sketches using Inkscape. Here are the 5 plates of the final version:

Note that the drawings have to be really clean since they repesent the path for the laser, i.e. they should not contain razor sharp corners or duplicated lines. Please find my design files, my QMK keymap and other source files on GitHub.

After some search for a laser cutting service in Germany I found cutcraft, which provide an excellent and friendly service. I ordered all plates to be cut from a 3mm acryl glass. And here's what I received:

I used acryl glue and 8 pairs of screws and nuts to assemble the case:

The switches

I used 52 stock Greetech Brown switches which are comparable to Cherry MX Brown switches. They feel a bit more tactile and unfortunately also more scratchy despite lubing them.

I had to use hot glue to properly fix the switches to the plate.

Handwiring instead of a PCB

The electronic heart of a keyboard is usually a PCB (printed circuit board, hosting the controller) but I wanted to avoid learning on how to design a PCB on my own, since I had no plans to sell any number of the keyboards I might eventually build for myself. So the overhead would perhaps not pay off. The alternative is handwiring. The prerequisite is to understand how the controller uses a matrix to scan many more switches than there are inputs on the controller. For the practical part of creating the matrix on your own with only wires and diodes, I found help in existing guides like this one that explain how to approach the work. It is obvious that handwiring takes more time, I estimate about 4 hours compared to 1 hour for soldering the required switches onto a PCB. But after all it is a hobby to build a personal piece of hardware, not a competitive race, so I enjoyed to spend more time on it.

Soldering the rows and columns, including diodes, is very straight forward, and the result looked quite clean:

The controller I used is a tiny board called Pro Micro, including the ATmega32U4, which is available for just a few Euros. Connecting the rows and columns with the Pro Micro also requires considerable work, and the result didn't look as clean:

Although a handwired board might look a bit fragile compared to a PCB based board the soldered connections are quite solid, so I have no doubt about the longevity of the product.

The finish

After soldering I used a multimeter to check every single connection. I connected my PC with the controller using a USB cable. Then I had to flash the firmware to the controller using the QMK tooling and a jumper-like cable to short circuit the controllers RST with the GND pin twice. The final step was to close the case with the screws and put on colorful keycaps and a unicorn sticker that my daughter gave me:

I am quite pleased with the outcome. The keyboard with all parts weighs about 500 grams, its size is 29cm x 14cm. The sound is muted, and the acrylic plate that holds the switches is flexible but not bouncy.

The hard part

Then came the strenuous phase of training my fingers to find the right keys with an acceptable speed. The first three days required a large amount of energy and frustration tolerance but I made enough progress to keep me motivated. This became much better after about a week. Working on such a keyboard feels totally different compared to a classical layout because my hands always stay in the same position. I can reach every key just by bending or stretching my fingers. It took some practise to master the additional layers (for nav functions, numbers, symbols, umlaut composition, mouse pointer, mouse wheel) but this is getting better every day.

The project was quite satisfying, and perhaps I will try another build with a different type of switch and other case material like wood.

QMK and touch typing

20.05.2020 Permalink

Back in 2012 I bought my first keyboard with mechanical Cherry MX Brown switches, the yellow edition of a Ducky Shine 3 TKL. By that time I had virtually no clue about the world of keyboards, but the product felt nice to me and it looked extraordinary:

In my opinion a good mechanical keyboard makes a difference so last year I tried to find a nice one for my daughter, as she was beginning to spend more time on her PC. I was lucky enough to buy a Ducky x Varmilo Miya Pro which has a very fine build quality and typing sound.

During the search I was a bit surprised that it is actually a matter of luck and/or patience to acquire a high quality mechanical keyboard. There are so many nice keyboards out there, as r/MechanicalKeyboards demonstrates on a daily basis. The nice pictures and stories got me hooked, so I started to explore the world of mechanical keyboards more in depth. Eventually I decided that I wanted to tackle one of my long lasting weaknesses: the lack of consistent typing speed. Isn't this the perfect excuse to spend some money on a new keyboard?

I was never a good typist, I hardly used touch typing, although I tried more than once to properly learn it. I suspect my failures of using touch typing in everyday work were caused by the position of the modifiers (Ctrl, Shift, Alt, Super) and especially the nav cluster (arrow keys, page up, page down), constantly drawing my right hand away from the home row (the row with the keys for A, S, D, F and so on).

My exploration led me to the idea that a programmable keyboard with a 60% form factor (a keyboard without numpad, nav cluster or function key row) might bring me closer to my goal. After some more research I bought a KB Paradise V60 Type R because it featured an ATmega32U4 micro processor which is known to support the open source firmware QMK. This firmware allows you to freely program your keyboard with up to 32 layers using the programming language C. In essence, this allows you to make it truly your very own keyboard.

The 60% form factor eliminated the nav cluster, so I assigned the arrow keys to I, J, K and L, but the modifier position was still disturbing.

QMK provides a feature called Mod-Tap which allows you to assign a modifier to any key. If you just tap the key, you'll get the character, but if you hold it and press it in conjunction with another key you'll get the modified behaviour. I assigned the modifiers to my home row like this:


It took a bit of tweaking of QMK parameters and a few hours to really get used to it. But after all, my fingers stayed on the home row and my latest effort to properly learn touch typing succeeded!

But with this change the modifier keys on the bottom row of a classical keyboard became useless to me, so this leads me to think about keyboard layouts in a more general way. I am quite aware of Atreus and other split keyboards as a potentially more ergonomic arrangement of keys.

So this story might continue in the very near future...

DIY desktop with the i3 window manager

01.07.2018 Permalink

Linux offers several desktop environments and window managers, so if you don't want to stick to the default of your distro you're free to explore alternatives. I started using Ubuntu Linux in 2010 on my business notebook. Back then Ubuntu came with its Unity desktop environment, but this was eventually dropped in favor of Gnome 3 in 2017, featuring a virtual desktop feature called workspaces.

I usually have to handle at least a dozen of running applications, among them several terminals, Thunderbird, Slack, Emacs, a twin-panel file manager named Krusader, at least four different browser based apps and so on. Often I need to switch quickly between applications. To manage the corresponding windows I made heavy use of Gnome workspaces, giving me a multiple of desktop real estate.

Over time I observed that:

So there was room for improvement.

Looking for a solution, I came across a specific class of windows managers. A tiling window manager promises to automate arrangement of application windows to some degree. The main idea is that the window manager avoids any overlap and automatically splits the available screen space horizontally or vertically when a new window opens. Among the popular implementations i3 seemed to be the best choice for me, so I gave it a try. The following screenshot shows how i3 arranges multiple terminal windows.

i3 has some characteristics that I appreciate:

Please note, that the last item points to a substantial implication: i3 is not a desktop environment, and I had to add numerous features until the system was convenient to use. In particular the status bar required some research and time until it looked like this:

The following table shows which Linux tools I used together with a bit of Bash scripting. This illustrates that learning i3 is only the tip of the iceberg. I had to pick up with many more tools that make up a usable desktop experience on an X window system.

Feature Tool
Notebook display brightness control xbacklight or xrandr
Notebook display night light redshift or xrandr
Turn external monitors on/off xrandr
Screen lock i3lock, xdpyinfo, compton
Screen saver xset (dpms feature)
Wallpaper feh
Audio and music control pavucontrol, pactl, clementine
Bluetooth control blueman-applet
Networking control nm-applet
Switch keyboard layout, adjust autorepeat setxkbmap, xmodmap, inputplug, xset (r feature)
Application launcher dmenu
USB storage automount udiskie
Screenshot tool flameshot
System information in status bar i3blocks
Provide keyring keys gnome-keyring-daemon

After all, it was a fun project, and it eventually improved my productivity on Linux. The whole configuration including all scripts is hosted on Github.