Modified Arduino USB Host Shield Keyboard Example
// Modified from https://github.com/felis/USB_Host_Shield_2.0/blob/master/examples/HID/USBHIDBootKbd/USBHIDBootKbd.ino | |
// Modified to print the ASCII hex codes of the keys pressed, and to handle some of the non-printable keys. | |
#include <hidboot.h> | |
#include <usbhub.h> | |
// Satisfy IDE, which only needs to see the include statment in the ino. | |
#ifdef dobogusinclude | |
#include <spi4teensy3.h> | |
#endif | |
#define UHS_HID_BOOT_KEY_ESC 0x29 | |
#define UHS_HID_BOOT_KEY_DEL 0x4C | |
#define UHS_HID_BOOT_KEY_BACKSPACE 0x2A | |
#define UHS_HID_BOOT_KEY_HOME 0x4A | |
#define UHS_HID_BOOT_KEY_PAGE_UP 0x4B | |
#define UHS_HID_BOOT_KEY_END 0x4D | |
#define UHS_HID_BOOT_KEY_PAGE_DN 0x4E | |
#define UHS_HID_BOOT_KEY_TAB 0x2B | |
#define UHS_HID_BOOT_KEY_CAPS 0x39 | |
class KbdRptParser : public KeyboardReportParser | |
{ | |
void PrintKey(uint8_t mod, uint8_t key); | |
uint8_t mapExtraAsciiKeys(uint8_t); | |
protected: | |
virtual void OnControlKeysChanged(uint8_t before, uint8_t after); | |
virtual void OnKeyDown (uint8_t mod, uint8_t key); | |
virtual void OnKeyUp (uint8_t mod, uint8_t key); | |
virtual void OnKeyPressed(uint8_t key); | |
}; | |
void KbdRptParser::PrintKey(uint8_t m, uint8_t key) | |
{ | |
MODIFIERKEYS mod; | |
*((uint8_t*)&mod) = m; | |
Serial.print((mod.bmLeftCtrl == 1) ? "C" : " "); | |
Serial.print((mod.bmLeftShift == 1) ? "S" : " "); | |
Serial.print((mod.bmLeftAlt == 1) ? "A" : " "); | |
Serial.print((mod.bmLeftGUI == 1) ? "G" : " "); | |
Serial.print(" >"); | |
PrintHex<uint8_t>(key, 0x80); | |
Serial.print("< "); | |
Serial.print((mod.bmRightCtrl == 1) ? "C" : " "); | |
Serial.print((mod.bmRightShift == 1) ? "S" : " "); | |
Serial.print((mod.bmRightAlt == 1) ? "A" : " "); | |
Serial.println((mod.bmRightGUI == 1) ? "G" : " "); | |
}; | |
// Map some of the keys currently not handled by OemToAscii | |
uint8_t KbdRptParser::mapExtraAsciiKeys(uint8_t key) { | |
switch(key) { | |
case UHS_HID_BOOT_KEY_SPACE: return ' '; | |
case UHS_HID_BOOT_KEY_ZERO2: return '0'; | |
case UHS_HID_BOOT_KEY_PERIOD: return '.'; | |
case UHS_HID_BOOT_KEY_ESC: return 0x1B; | |
case UHS_HID_BOOT_KEY_DEL: return 0x7F; | |
case UHS_HID_BOOT_KEY_BACKSPACE: return 0x08; | |
case UHS_HID_BOOT_KEY_TAB: return 0x09; | |
} | |
return ( 0); | |
} | |
void KbdRptParser::OnKeyDown(uint8_t mod, uint8_t key) | |
{ | |
Serial.print("DN "); | |
PrintKey(mod, key); | |
uint8_t c = OemToAscii(mod, key); | |
if (!c) { | |
c = mapExtraAsciiKeys(key); | |
} | |
if (c) { | |
OnKeyPressed(c); | |
} | |
} | |
void KbdRptParser::OnControlKeysChanged(uint8_t before, uint8_t after) { | |
MODIFIERKEYS beforeMod; | |
*((uint8_t*)&beforeMod) = before; | |
MODIFIERKEYS afterMod; | |
*((uint8_t*)&afterMod) = after; | |
if (beforeMod.bmLeftCtrl != afterMod.bmLeftCtrl) { | |
Serial.println("LeftCtrl changed"); | |
} | |
if (beforeMod.bmLeftShift != afterMod.bmLeftShift) { | |
Serial.println("LeftShift changed"); | |
} | |
if (beforeMod.bmLeftAlt != afterMod.bmLeftAlt) { | |
Serial.println("LeftAlt changed"); | |
} | |
if (beforeMod.bmLeftGUI != afterMod.bmLeftGUI) { | |
Serial.println("LeftGUI changed"); | |
} | |
if (beforeMod.bmRightCtrl != afterMod.bmRightCtrl) { | |
Serial.println("RightCtrl changed"); | |
} | |
if (beforeMod.bmRightShift != afterMod.bmRightShift) { | |
Serial.println("RightShift changed"); | |
} | |
if (beforeMod.bmRightAlt != afterMod.bmRightAlt) { | |
Serial.println("RightAlt changed"); | |
} | |
if (beforeMod.bmRightGUI != afterMod.bmRightGUI) { | |
Serial.println("RightGUI changed"); | |
} | |
} | |
void KbdRptParser::OnKeyUp(uint8_t mod, uint8_t key) | |
{ | |
Serial.print("UP "); | |
PrintKey(mod, key); | |
} | |
void KbdRptParser::OnKeyPressed(uint8_t key) | |
{ | |
Serial.print("ASCII: "); | |
Serial.println(key, HEX); | |
}; | |
USB Usb; | |
//USBHub Hub(&Usb); | |
HIDBoot<HID_PROTOCOL_KEYBOARD> HidKeyboard(&Usb); | |
uint32_t next_time; | |
KbdRptParser Prs; | |
void setup() | |
{ | |
Serial.begin( 115200 ); | |
while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection | |
Serial.println("Start"); | |
if (Usb.Init() == -1) | |
Serial.println("OSC did not start."); | |
delay( 200 ); | |
next_time = millis() + 5000; | |
HidKeyboard.SetReportParser(0, (HIDReportParser*)&Prs); | |
} | |
void loop() | |
{ | |
Usb.Task(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment