I want to create a custom keyboard mapping in the official arduino keyboard library

Why do the key definitions add 136 to each number?

See Keyboard_es_ES.h on github

#define KEY_MASCULINE_ORDINAL    (136+0x35)
#define KEY_GRAVE                (136+0x2f)
#define KEY_N_TILDE              (136+0x33)
#define KEY_ACUTE                (136+0x34)
#define KEY_C_CEDILLA            (136+0x31)

Looking at the ascii table, I see nothing special about value 136


1 Answer 1


It could be argued that this is an implementation detail of the library, that does not need to be documented. ;-) Anyway, here is the reason...

The keyboard library uses a custom encoding scheme for representing both characters and keys. The public methods press(), release(), write(), print() and println() interpret the user-provided data according to this scheme. With this encoding, the interpretation of a byte depends on which of these three ranges it belongs to:

  • Bytes in the range [0, 127] are understood to be ASCII characters. This is what enables you to write things like Keyboard.println("Hello!");. The library uses a keyboard layout array to map those characters to key scan codes¹, possibly modified by Shift or AltGr. You provide a pointer to this array as an argument to begin().

  • Bytes in the range [128, 135] are interpreted as modifier keys, such as KEY_LEFT_CTRL, KEY_RIGHT_SHIFT, etc. Note that these keys do not have proper scan codes, as their state is transmitted to the host as a bit map (one byte for the eight keys) rather than as codes added to a list.

  • Bytes in the range [136, 255] are interpreted as raw scan codes in the range [0, 119], shifted by 136. This is what lets you actuate arbitrary keys such as KEY_PRINT_SCREEN or KEY_LEFT_ARROW. All scan codes of a standard full-size PC keyboard (ANSI 104 or ISO 105) lie in the range [4, 101]: you can access all of them, and even some more like KEY_F24.

Regarding the file Keyboard_es_ES.h: the codes in there are for keys that match ASCII characters in the US layout but not in the Spanish layout. The purpose is to ensure that every key of a ISO 105 keyboard can be actuated using either an ASCII character (like Keyboard.press('a');) or a KEY_* macro.

¹ The USB standard calls them “usage codes”, but the old term “scan codes” seems more prevalent.

  • Just an idea for self-documenting source, but I'm quite sure you are aware of this. ;-) You could use symbolic constants instead of magic numbers. Aug 9, 2022 at 6:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.