WPM Calculation
The WPM feature uses time between keystrokes to compute a rolling average words per minute rate and makes this available for various uses.
Enable the WPM system by adding this to your rules.mk:
1
WPM_ENABLE = yes
Copied!
For split keyboards using soft serial, the computed WPM score will be available on the master AND slave half.

Configuration

Define
Default
Description
WPM_SMOOTHING
0.0487
Sets the smoothing to about 40 keystrokes
WPM_ESTIMATED_WORD_SIZE
5
This is the value used when estimating average word size (for regression and normal use)
WPM_ALLOW_COUNT_REGRESSOIN
Not defined
If defined allows the WPM to be decreased when hitting Delete or Backspace

Public Functions

Function
Description
get_current_wpm(void)
Returns the current WPM as a value between 0-255
set_current_wpm(x)
Sets the current WPM to x (between 0-255)

Callbacks

By default, the WPM score only includes letters, numbers, space and some punctuation. If you want to change the set of characters considered as part of the WPM calculation, you can implement your own bool wpm_keycode_user(uint16_t keycode) and return true for any characters you would like included in the calculation, or false to not count that particular keycode.
For instance, the default is:
1
bool wpm_keycode_user(uint16_t keycode) {
2
if ((keycode >= QK_MOD_TAP && keycode <= QK_MOD_TAP_MAX) || (keycode >= QK_LAYER_TAP && keycode <= QK_LAYER_TAP_MAX) || (keycode >= QK_MODS && keycode <= QK_MODS_MAX)) {
3
keycode = keycode & 0xFF;
4
} else if (keycode > 0xFF) {
5
keycode = 0;
6
}
7
if ((keycode >= KC_A && keycode <= KC_0) || (keycode >= KC_TAB && keycode <= KC_SLASH)) {
8
return true;
9
}
10
11
return false;
12
}
Copied!
Additionally, if WPM_ALLOW_COUNT_REGRESSION is defined, there is the uint8_t wpm_regress_count(uint16_t keycode) function that allows you to decrease the WPM. This is useful if you want to be able to penalize certain keycodes (or even combinations).
1
__attribute__((weak)) uint8_t wpm_regress_count(uint16_t keycode) {
2
bool weak_modded = (keycode >= QK_LCTL && keycode < QK_LSFT) || (keycode >= QK_RCTL && keycode < QK_RSFT);
3
4
if ((keycode >= QK_MOD_TAP && keycode <= QK_MOD_TAP_MAX) || (keycode >= QK_LAYER_TAP && keycode <= QK_LAYER_TAP_MAX) || (keycode >= QK_MODS && keycode <= QK_MODS_MAX)) {
5
keycode = keycode & 0xFF;
6
} else if (keycode > 0xFF) {
7
keycode = 0;
8
}
9
if (((get_mods() | get_oneshot_mods()) & MOD_MASK_CTRL} || weak_modded) && (keycode == KC_DEL || keycode == KC_BSPC)) {
10
return WPM_ESTIMATED_WORD_SIZE;
11
}
12
if (keycode == KC_DEL || keycode == KC_BSPC) {
13
return 1;
14
}
15
}
Copied!
Last modified 2mo ago