Keyboard HID codes not working

Status
Not open for further replies.
Morning all,

This is a question tied to the same project I posted earlier here:
https://forum.pjrc.com/threads/56715-Simultaneous-USB-Host-and-Device-mode

and just so you know I have done research on this topic before asking for help, here's a post that asked a question very similar to mine but I couldn't understand the answer given: https://forum.pjrc.com/threads/55737-T3-6-USB-Host-Keyboard?highlight=usb+hid

My Question:
So I've dug into developing this device that passes through USB keypresses up to the PC its connected to from a keyboard it is also hosting on USB using Teensy 3.6.
I am currently using the Keyboard.h library for its .press() and .release() functions and the USBHost_t36.h library for its USB host capabilities, it actually works pretty well, but when testing this yesterday I found most of the normal alphanumeric keys work as intended but none of the "extra" keys do.
For example, I couldn't get any of these to work: LeftCtrl, LeftAlt, LeftShift, RightCtrl, RightAlt, RightShift, or any of the arrow keys, or any of the numpad keys if numlock was not turned on.
I also noticed that pressing the right arrow key generated and swapped to a new Windows10 desktop which according to this website:
https://www.howtogeek.com/198122/32-new-keyboard-shortcuts-in-the-windows-10-technical-preview/
is the same keycombo as: WindowsKey+Ctrl+D
I don't know how the arrow key was able to press all three of those, I do recall pressing WinKey and Ctrl before I tested the arrow keys though so maybe they aren't being released properly?

But here's where it gets juicy, I went digging to try and solve this myself but only found that the HID codes being used to detect these characters are not correct according to the USB spec sheet for keyboard HID (beginning on page 53, the keys that aren't working for me are on page 59):
https://www.usb.org/document-library/hid-usage-tables-112

when compared to the ones being used for reference in teensy3/keylayouts.h:
Why were they done using a greycode rather than the ones from the HID reference sheet?
---Key name--------------------------------- What it currently is ----------- what it looks like it should be
#define MODIFIERKEY_CTRL ------------ ( 0x01 | 0xE000 ) -------------------- ( 0x00 | 0xE0 )
#define MODIFIERKEY_SHIFT ----------- ( 0x02 | 0xE000 ) -------------------- ( 0x01 | 0xE0 )
#define MODIFIERKEY_ALT -------------- ( 0x04 | 0xE000 ) -------------------- ( 0x02 | 0xE0 )
#define MODIFIERKEY_GUI -------------- ( 0x08 | 0xE000 ) -------------------- ( 0x03 | 0xE0 )
#define MODIFIERKEY_LEFT_CTRL ------ ( 0x01 | 0xE000 ) -------------------- ( 0x00 | 0xE0 )
#define MODIFIERKEY_LEFT_SHIFT ----- ( 0x02 | 0xE000 ) -------------------- ( 0x01 | 0xE0 )
#define MODIFIERKEY_LEFT_ALT -------- ( 0x04 | 0xE000 ) -------------------- ( 0x02 | 0xE0 )
#define MODIFIERKEY_LEFT_GUI ------- ( 0x08 | 0xE000 ) --------------------- ( 0x03 | 0xE0 )
#define MODIFIERKEY_RIGHT_CTRL ---- ( 0x10 | 0xE000 ) -------------------- ( 0x04 | 0xE0 )
#define MODIFIERKEY_RIGHT_SHIFT --- ( 0x20 | 0xE000 ) -------------------- ( 0x05 | 0xE0 )
#define MODIFIERKEY_RIGHT_ALT ------ ( 0x40 | 0xE000 ) -------------------- ( 0x06 | 0xE0 )
#define MODIFIERKEY_RIGHT_GUI ------ ( 0x80 | 0xE000 ) -------------------- ( 0x07 | 0xE0 )

I also wonder why these are different from normal Arduino definitions? Because this is a standard there should only be one right answer as to what is being passed up from the keyboard to the host, and that should be the HID code defined in the spec sheet right? So it seems no one has these codes right because Arduino uses 8 in place of E
C:\...\Arduino\libraries\Keyboard\src\Keyboard.h
#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


I'll get to this table later but it's important to also remember that the keys from the standard Arduino library were remapped to new keys:
(also in teensy3/keylayouts.h)
// for compatibility with Leonardo's slightly different names
#define KEY_UP_ARROW -------- KEY_UP
#define KEY_DOWN_ARROW ---- KEY_DOWN
#define KEY_LEFT_ARROW ------ KEY_LEFT
#define KEY_RIGHT_ARROW ---- KEY_RIGHT
#define KEY_RETURN ------------ KEY_ENTER
#define KEY_LEFT_CTRL -------- MODIFIERKEY_LEFT_CTRL
#define KEY_LEFT_SHIFT ------- MODIFIERKEY_LEFT_SHIFT
#define KEY_LEFT_ALT ---------- MODIFIERKEY_LEFT_ALT
#define KEY_LEFT_GUI ---------- MODIFIERKEY_LEFT_GUI
#define KEY_RIGHT_CTRL ------- MODIFIERKEY_RIGHT_CTRL
#define KEY_RIGHT_SHIFT ------ MODIFIERKEY_RIGHT_SHIFT
#define KEY_RIGHT_ALT --------- MODIFIERKEY_RIGHT_ALT
#define KEY_RIGHT_GUI --------- MODIFIERKEY_RIGHT_GUI


A really good piece of information I found when testing: When I was using a hobbytronics board that converted these USB packets to ASCII it had its own way of defining the windows key because WinKey isn't in the ASCII table, regardless, when I detected that special sequence I used Keyboard.press( KEY_LEFT_GUI ) and it actually did work fine. I saw the windows start menu pop up normally. (I'm not sure if it was using the Arduino definitions or the keylayouts.h redefined values in that final table above though.)
With this in mind, in my USBHost_t36 KeyboardController object I tied in two very basic one liner functions to the attachPress and attachRelase functions. All I did in them was Keyboard.print(key,HEX); to see what was kind of data was being passed to me, I eventually found it was Unicode characters, regardless, nothing was being passed to me for when the Ctrl, Alt, Shift, and WinKey were pressed, because nothing got printed. Ishould at least see some kind of hex value for them if they were being passed at all, but I just didn't.
So I know the problem isn't necessarily with the way these keys are defined in hex, because they worked weeks ago on a different setup using Keyboard.press() , but rather the issue may be with how they are being detected, possibly in the convert to Unicode function, and/or possibly how they are passed to the user's OnPress and OnRelase functions.


Thank you so much for the help these forums have given so far. And I thank you all in advance for the great help and understanding I know you will provide. I'll keep searching through this problem when I can but I'll be gone this next week.
I look forward to hearing from you guys and gals.
 
Last edited:
Status
Not open for further replies.
Back
Top