Keyboard Builders' Digest
Save 5% at Loobed Switches! Code: KBDNEWS
Keyboard Builders' Digest /

Forcy McForceFace

Jesse Vincent, cofounder of Keyboardio, describes building a force tester out of an old 3D printer: Forcy McForceFace.

Jesse Vincent
Published December 10, 2023
This post is part of the KBD.NEWS Advent Calendar 2023. The previous article was: Ergo Mech Fan Art by Philip Lalonde. Stay tuned and check back for more articles tomorrow!

Hi, I'm Jesse Vincent, one of the folks behind Keyboardio. We make the Model 100 and the Atreus and will soon be making the Bluetooth Keyboardio Preonic in partnership with OLKB. As part of our work, we sometimes need to go a little deeper into esoteric hardware than I ever could have imagined possible when we got into this business.

Force tester encounters

If you've been around mechanical keyboards for any length of time, you've probably run across a keyboard force diagram – it's that little chart that shows how much force it takes to press a given type of switch over the course of a keystroke.

The first time I saw a machine that measured keyswitch force curves, it was at Kailh's factory in Dongguan, China. It was a fancy, automatic custom machine that could press a switch and output a CSV file of force and position data.

The second time I saw a force tester, it was at a keyboard factory and was, for all intents and purposes, a stand, a handle, a gear, and an old-school analog force meter with a dial. (Think of it like an upside-down luggage scale that measures press instead of pull.) The engineer would crank the handle a little bit, which moved the force tester 0.1mm closer to the switch. They'd read the measurement off the force meter's dial and scribble it down on a sheet of paper. Later, someone would transcribe everything into Excel and they'd make a chart.

The issue

At Keyboardio, we had a problem—we were feeling pressure levels on switches that didn't come anywhere close to matching what the switch manufacturer had documented in their datasheets.

We needed some way to document and characterize the problem. And we were 100% willing to spend dozens of hours to build an automated tool, rather than having to take every reading by hand.

The plan

We didn't have the tens of thousands of dollars to buy a commercial force-testing apparatus. What we did have were a crappy old 3D printer that a friend had pawned off on us after it stopped printing, an Arduino, a Chinese knock-off of a fancy Japanese force testing probe with an undocumented serial protocol, and a desire to waste time reverse engineering things.

What we needed was a way to hold a force tester in a rigid, well defined position above a keyswitch and then slowly, in tiny increments, move it downward, taking force readings at every step.

Implementation

The 3D Printer, a Monoprice Mini, seemed like a great starting point for an automated gantry for our test setup. We disconnected the bed heater that would have melted keyswitches while testing them. We yanked off the hot end that's usually used to spew molten plastic as the whole "printing" part of 3D printing. We made a tiny little bracket to attach our Yisida brand force gauge to the hotend's mount point on the gantry. And then we got ready to detach the z-axis (vertical) motor from the 3D printer's control circuitry, so that we could control it with the aforementioned Arduino. Thankfully, before we did, we realized that we didn't need to build our own motor controller. That 3D printer – we could talk to it! All we had to do was to connect to the 3D printer with a serial connection and say "G1 Z0.01" to move the gantry up 0.01 mm.

We now had a robot that could go up and down, with a force testing head on it.

Pic: Forcy McForceface

Forcy McForceface

Next up, we needed to integrate the force tester. Conveniently, it had a USB port on it and would send every reading out over a serial protocol. Inconveniently, the only client for that undocumented serial protocol was a Chinese-language windows app. The app was able to output to Excel, but we needed to be able to read the output in realtime to know when to stop the 3D printer from driving the force tester through our keycap and switch. A couple hours with a protocol sniffer and we had…some slightly obtuse perl code that reliably read the readings off the force tester.

for ( my $i = 0 ; $i < 50 ; $i++ ) {
    my ( $count_in, $bytes ) = $ft->read(7);
    if ($count_in) {
        my @bytes = split( //, $bytes );
        while ( $#bytes >= 0 ) {
            my $byte = shift @bytes;
            if ( ord($byte) == 0x55 && ( $#current_force_measurement >= 5 ) ) {
                my @result = ( @current_force_measurement, $byte );
                @current_force_measurement = (@bytes);
                if (
                       ord( $result[0] ) != 0xAA
                    || ord( $result[6] ) != 0x55
                    || (   ( ord( $result[5] ) != 0x2C )
                        && ( ord( $result[5] ) != 0x0C )
                        && ( ord( $result[5] ) != 0x5C )
                        && ( ord( $result[5] ) != 0x7C ) )
                  )
                {
                    warn "had bad result in our measurement";
                    return get_next_force_measurement();
                }
                my $value =
                  ord( $result[4] ) +
                  ( 256 * ord( $result[3] ) ) +
                  ( 256 * 256 * ord( $result[2] ) ) +
                  ( 256 * 256 * 256 * ord( $result[1] ) );
                if ( ord( $result[5] ) == 0x0C ) {
                    $value = 0 - $value;
                }
                @current_force_measurement = ();
                return sanity_check_force_value($value);
            }
            push @current_force_measurement, $byte;
        }
    }
}

By watching for when keypress force went over 200g, we could detect when we'd bottomed out.

At this point, the only "hard" bit left was detecting keypresses. Finally, it was time for the Arduino to get put to work. We wrote an incredibly sophisticated custom keyscanner routine for Arduino:

// the number of the pushbutton pin
const int buttonPin = 2;
int buttonState = 0;
uint8_t oldState = HIGH;
void setup() {
  Serial.begin(57600);
  pinMode(buttonPin, INPUT);
  digitalWrite(buttonPin,HIGH);
}
void loop() {
    buttonState = digitalRead(buttonPin);
    if (buttonState != oldState) {
        delay(5);
        buttonState = digitalRead(buttonPin);
        if (buttonState != oldState) {
            if (buttonState == HIGH) {
                Serial.print("0");
            } else {
                Serial.print("1");
            }
            oldState = buttonState;
        }
    }
}

What this code does is: If the switch is toggled on, it prints "1" to the serial port. If the switch is toggled off, it prints "0" to the serial port.

With all these bits together, it was time to test out our force tester, newly christened "Forcy McForceFace".

Pic: Kailh BOX Noble Yellow force curve

Kailh BOX Noble Yellow force curve

The force curve for a Kailh BOX Noble Yellow switch. You can find the raw data here.

(Kailh was not the manufacturer with the misbehaving switches.)

After a little bit of tuning and bug-hunting, we had a fully-working force curve tester. Ok, fine, two and a half weeks of tweaking and tuning we had a slightly temperamental, but still totally functional, force curve tester.

If you're building your own force tester and happen to be using the same hardware as us, you might find our driver script useful.

From there, we set about to see what was going on with the weird results we were getting from the switches from the manufacturer we'd been having some trouble with. And indeed, we were able to figure out that some changes the manufacturer had made to the switch design had led to a change in their force curves from when they were first specced.

These days, we occasionally break Forcy out to test out new switches, but it mostly lives a well-deserved retirement in Keyboardio's museum of exotic keyboards.

This article was typed on a Keyboardio Model 100 with Kailh BOX Silent Brown switches.

Jesse Vincent

Handleobra
LocationCalifornia, USA
First keyboard build2012
Linkskeyboard.io, fsck.com
Do you like this post? Share, donate, subscribe, tip me off!

Published on Sun 10th Dec 2023. Featured in KBD #2023.


Related

Keyboard Case Design

Sadek Baroudi provides a detailed walkthrough of how he designs 3D models – Starting with a PCB, and ending with a model that you can export for 3D printing.

Maximising the effectiveness of Pro Micros in keyboard design

Moses Hoyt, from STHLM kb, shares his challenges, tips and tricks for overcoming the limitations of Pro Micro controllers in keyboard design.

3D printable keycap tutorial

A video tutorial by mcass_37 on how to merge files and create your own custom 3D printable keycap file (base keycap, source).

PS/2 protocol in action

A video on how the PS/2 keyboard protocol works. Posted by nucatus (source).

Soldering a YC8 connector

A video tutorial on soldering the YC8 detachable connector by actionspacecake.

Make a Keyboard

A handwired project and detailed tutorial on how to design and make a keyboard by berkstone.

×
top