Arduino Keyboard library (HID) on Leonardo

Another dumb n00b question… When sending keyboard events over USB HID from a Leonardo, there are several ways to go about it.

I can define a uint_8 value and use Keyboard.press and Keyboard.release methods to hold down a key for however many ms I choose.
I can define a unit_8 and use Keyboard.write method to press that one character for some default duration (one keystroke).
I can define a string and use Keyboard.print to send the whole string (series of keystrokes).

All this works great. I’ve tested all three methods.

But the lower level details are where it gets a bit murky for me: if I invoke, say, Keyboard.press(‘a’) and then Keyboard.press(KEY_LEFT_SHIFT), with the keyboard input visible in an xterm on the host, I would expect to see aaaaaaaaAAAAAAAAA… and so on, until one or both keys are released.

But it seems I can also use Keyboard.press(‘a’), then release(‘a’), then Keyboard.press(‘A’). This would result in aaaaaaaaaaaa(tiny hiccup)AAAAAAAAAAAAAAA and this is what I indeed see in my xterm because this is how I’m emulating a user holding down keys.

From the point of view of an application, like a WASD game controller or a text editor receiving characters or whatever… are the two actually identical (apart from the tiny hiccup between the release of ‘a’ and the press of ‘A’)?

And what about the case in which my code might press(‘a’) and then also press(‘A’)??? They are not really two different keys! When I use press(‘A’) does it really do an implicit press of a shift key?

At what level is the actual mechanical SHIFT key perceived? Only in the depths of the USB HID driver on the host, which then passes capital-letter A up to the application layer? Or are applications actually aware of the pressing of a SHIFT (or other modifier key)?

I haven’t yet found a nice clear writeup which explicitly states at what point SHIFT+key turns into “Capital Letter ASCII code”. I’m assuming (hoping) it is pretty low down in HID and the application is only aware of receiving an ascii ‘a’ or ‘A’.

I ask because my experimental app is not responding quite as I expected, and I’m wondering whether the puzzling inconsistencies in its response are due to my own Arduino loop code (timing issues) or might have something to do with my using press(‘A’) instead of press(KEY_LEFT_SHIFT) in addition to press(‘a’).

I don't know how the Arduino library works, but from the POV of the software on a computer, it depends.

Keyboard stuff is obviously pre-processed by the OS before reaching your program, but you choose how you want to "read" the keys being pressed, so it really depends on the program.

You might want to just concentrate on reading the "final" ASCII of whatever was pressed, or read each key press as it comes along, so you'll detect shift and then 'a'. You can also ask for the state of the shift key once you captured your ASCII 'a'.

So in short, who knows. :D

I'll see if I check when I get home to see what the Arduino is sending.

erm… well, it would have been obvious if I paid more attention to what I was thinking. :smiley:

A keyboard sends only ‘a’, the letter, no upper or lower case information. Is up to the 'puter to produce those.

Look at the scan codes:

https://www.win.tue.nl/~aeb/linux/kbd/scancodes-14.html

There is no ‘a’ vs ‘A’, just letter ‘a’.

You can look at the source code (libraries/Keyboard/src/Keyboard.cpp) to see how the USB messages are generated. The lookup table in the library will convert an ASCII character to the USB keycode that shows that character on the US-ASCII keyboard, along with a flag that indicates if a Shift is required. It always uses the left shift and always un-does the left shift if you release a shifted character.

The library sends USB keycodes. It is up to the OS to map those key numbers to characters. That is why the library acts funny when the OS is set for a non-US keyboard layout.