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.