Help with Arduino Micro Keypress Algorithm
Modifier keys are treated no different to normal keys.

The Arduino Keyboard library contains code to map different keys from the internal list of macros to specific keypresses:


If the key value is >= 138 it's a non-printing special key (subtract 138)
If the key value is >= 128 it is a modifier key (1 &lt;&lt; (k - 128))
Otherwise look the code up in a mapping table.


That means you can use:

Keyboard.press(KEY_LEFT_SHIFT);


or

Keyboard.release(KEY_RIGHT_GUI);


The full list of modifier keys is:

#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


So to do a capital A you can use:

Keyboard.press(KEY_LEFT_SHIFT);
Keyboard.press('a');
Keyboard.release('a');
Keyboard.release(KEY_LEFT_SHIFT);


There is also a shortcut, and that is:

Keyboard.press('A');
Keyboard.release('A');


The character 'A' is the same in the lookup table as character 'a' except the high bit of the result is set, which triggers a "Press or release the shift key" addition in the mapping code.

A USB keyboard report consists of 8 bytes:


Up to 8 modifier keys (bitmap)
One reserved byte
6 bytes to indicate pressed keys


This means that you can have up to 6 keys pressed at once, plus modifier keys. Never any more than that. So you don't need to handle any more than that in your code.

The current list of pressed keys is maintained by the keyboard and is sent in every report. There's no concept as such of "pressed" or "released" - only the list of what is currently pressed. If a key is released it's just removed from that list of pressed keys. 

So what you need is some way of transferring that data in such a way that the Arduino can interpret it properly.

Since the data is not high throughput you can afford to be quite wasteful in your protocol.  I would suggest using a fairly verbose ASCII based protocol. 


All the protocol data is using ASCII characters between 32 and 127 inclusive
This frees up control characters (&lt;32) for controlling the protocol.


The simplest thing is to use a single control character (such as \n) to act as a line ending to break your data up into packets.  Each packet can then contain a list of instructions.

For example, you might choose to have a protocol that looks like:

P,129\n
P,97\n
R,97\n
R,129\n


By treating each line as a complete entity you know that you want to Press key 129 (#define KEY_LEFT_SHIFT    0x81), press key 97 ('a'), release 97, then release 129.

There's no confusion, since commands are all a single upper-case character, and keys are all a decimal number.

For your application, though, a "raw" access interface would be of more use, since you don't really want the Arduino interpreting things for you. However, the API doesn't provide that kind of thing.  So you just have to make the best of what you have and work around it.