Drobnicky

Drobničky 007 – Arduino jako klávesnice 1

Letmý pohled pod povrch Arduino Keyboard a USB komunikace

Dostala se ke mě otázka:

Pořídíl jsem si Arduino micro a trápím se s češtinou, potřebuji psát česky s diakritikou, čísly, speciálními znaky, ale vůbec se mi nedaří posílat znaky s háčky, čárky atd.

Takto odpovídám já

Odpověď v Arduino-forum.cz: Arduino jako klávesnice 2

Odpověď, která asi moc nepotěší, ale uvede věci na pravou míru:

Arduino jako klávesnice používá USB protokol pro klávesnici, ten sám je docela omezený (odesílá maximálně 6 kláves naráz + modifikátory (jako levý shift, pravý alt atd celkem 8 bitů=1byte) a docela složitý:

V podstatě (kromě spousty režie) klávesnice posílá počítači toto (viz Arduino/build/linux/work/libraries/Keyboard/src ):

Keyboard.h :75

typedef struct
{
 uint8_t modifiers;
 uint8_t reserved;
 uint8_t keys[6];
} KeyReport;

Aby to nebylo složité a lidi to nevyděsilo (=Arduino way), tak to je celé zabalené v něčem, co to umožní používat jednoduše, za cenu ztráty funkcionality a nepřesností – ta knihovna Keyboard – najděte si ji na svém počítači)

modifiers jsou různé „shifty“ viz Keyboard.h :37 (jen ta čísla (-0x80) odpovídají jednotlivým bitům)

#define KEY_LEFT_CTRL    0x80
#define KEY_LEFT_SHIFT  0x81
#define KEY_LEFT_ALT    0x82
#define KEY_LEFT_GUI    0x83
#define KEY_RIGHT_CTRL  0x84
#define KEY_RIGHT_SHIFT 0x85
#define KEY_RIGHT_ALT   0x86
#define KEY_RIGHT_GUI   0x87

keys[6] je pole aktuálně stisknutých tlačítek podle specifikace HID Usage Tables 1.12 strana 53 a další, v knihovně je „nějak“ převádějí ze zadaných písmen (a předpokládají anglickou klávesnici) a dál s tím dělají všeliké vylomeniny, aby to „nějak“ fungovalo

Keyboard.cpp :86

const uint8_t _asciimap[128] =

číslice se berou z řady kláves nad QWERTY, bez shiftu

Takže když zkoušíte psát ALT+0397 přes alt a číslice, tak vám to pochopitelně na té číslicové řadě nejde, (protože to počítač „vidí“ jako ALT+éšíý a nedává mu to smysl).

Navíc knihovna Keyboard předpokládá vypnutý NumLock a šipky píše na něm (s tím, že aby poznala, že jde o „speciální znaky“ tak jsou ty kódu posunuté o 136 nahoru a při použití od nich zase 136 odečte

#define KEY_UP_ARROW    0xDA
#define KEY_DOWN_ARROW  0xD9
#define KEY_LEFT_ARROW  0xD8
#define KEY_RIGHT_ARROW 0xD7

Takže buď si pro tyhle speciální kódy nadefinovat vlastní funkci, která přepíše Keyboard_::press, nebo si ty kódy pro numerickou klávesnici dopočítat a dodefinovat jako konstanty, tak aby to té funkci vyšlo správně (a možná bude potřeba to posílat jako sekvenci NumLock,Alt+0397,Numlock, nebo Shift+Alt+0397 – to už musíte vyzkoušet, co Windows pochopí správně)


Shrnutí: USB klávesnice (ať už Arduino, nebo klasická) vůbec neví nic o rozložení znaků, nebo jaký jazyk se právě používá a jen odesílá, jaké klávesy byly namačkané. OS z toho nějak usoudí, jaké písmena (nebo jiné věci, jako multimediální, spuštění programů a podobně) by to asi tak mohlo znamenat (aniž by tušil, co je na klávesnici napsáno)

Arduino knihovna Keyboard dělá spoustu triků, aby to před uživatelem schovala a složitě a nepřesně předstírá, že umi psát písmena. Pro složitější věci doporučuju si projít její kód a buď ji ošidit, nebo si napsat vlastní, která to bude dělat požadovaným způsobem (není to až zas tak těžké).