I have a working sketch that reads the input from a play station 2 game controller and sends keyboard characters though the 34u2 as USB HID keyboard to the computer. This has been working great thanks to the Keyboard.press and Keboard.release commands of the keyboard library.
I have an Adafruit Feather 32u4 Bluefruit LE and thought it would be a great upgrade to make a controller that is a wireless bluetooth controller.
To send an "up arrow" I'm using the command;
ble.atcommand("AT+BleKeyboardCode=00-00-52-00-00-00-00-00");
To release the "up arrow" I'm using the command
ble.atcommand("AT+BleKeyboardCode=00-00-00-00-00-00-00-00");
My problem is that the release command releases all key presses in this single command. If I am holding down the left arrow and press fire, the release of the fire button also releases the left arrow.
How can I release individual key presses?
AT+BLEKEYBOARDCODE release single key press on an Adafruit Feather 32u4 Bluefruit LE
Moderators: adafruit_support_bill, adafruit
Please be positive and constructive with your questions and comments.
- krueg
- Posts: 8
- Joined: Sun Apr 07, 2013 10:49 am
- adafruit_support_mike
- Posts: 67446
- Joined: Thu Feb 11, 2010 2:51 pm
Re: AT+BLEKEYBOARDCODE release single key press on an Adafruit Feather 32u4 Bluefruit LE
Every HID packet means 'these buttons are currently held down'. A packet with all zero means 'no buttons are currently held down'.
Sending that packet does tell the computer a button has been released, but it does so by telling the computer -all- the buttons have been released.
1 - a packet that only lists the 'left arrow' key.
2 - a packet that lists the 'left arrow' and key and the 'fire' key.
3 - a packet that only lists the 'left arrow' key.
Sending that packet does tell the computer a button has been released, but it does so by telling the computer -all- the buttons have been released.
You want the following set of HID packets:
1 - a packet that only lists the 'left arrow' key.
2 - a packet that lists the 'left arrow' and key and the 'fire' key.
3 - a packet that only lists the 'left arrow' key.
- krueg
- Posts: 8
- Joined: Sun Apr 07, 2013 10:49 am
Re: AT+BLEKEYBOARDCODE release single key press on an Adafruit Feather 32u4 Bluefruit LE
Thanks adafruit_support_mike,
This is working great, playing any games that use a keyboard are mush easier with a game controller. It's working with windows and linux, I am sure it will work for a mac as well (not tested) as it appears as an everyday bluetooth keyboard or mouse.
I came up with the code below, some of it is a little awkward, I haven't come up with a clean way of dealing with the modifier byte for each player so I hard coded it at the beginning of the part that creates the key report string.
This is working great, playing any games that use a keyboard are mush easier with a game controller. It's working with windows and linux, I am sure it will work for a mac as well (not tested) as it appears as an everyday bluetooth keyboard or mouse.
I came up with the code below, some of it is a little awkward, I haven't come up with a clean way of dealing with the modifier byte for each player so I hard coded it at the beginning of the part that creates the key report string.
Code: Select all
/***********************************************************************************************
The Ultimate Cheap Mame Controller **Now with Bluetooth LE**
By Joel Krueger 1-1-2022
This sketch takes a 10 dollar GameStop ps2x controller, decodes it with an
Adafruit 32U4 Bluefruit LE microcontroller and connects to a computer like a
bluetooth HID keyboard using the default mame keystrokes. Because it connects
like a bluetooth keyboard it works for Windows, Mac, and Linux.
https://learn.adafruit.com/adafruit-feather-32u4-bluefruit-le
Huge credit goes to "The Mind Of Bill Porter" for his BANNED 2 Controller library
and info on how to wire it all up.
http://www.billporter.info/2010/06/05/BANNED-2-controller-arduino-library-v1-0/
The keymaps for the button presses can be changed below to work with any game that
uses keyboard or mouse inputs.
The START button sends a "p" key stroke, MAME games will pause.
The SELECT buttom on the controller acts like a shift button,
when it's held down and you press:
START will cycle through players 1 -> 2 -> 3 -> 4 -> start over at 1 -> 2 -> 3 -> 4 -> and so on.
X will enable/disable mouse mode on the left joystick
R1 raises the mouse speed
R2 lowers the mouse speed
The basic concept:
Read the game controller
Step through all the controller buttons
If the button was pressed set it's flag to "1"
If the button was released set it's flag to "0"
The joysticks need some calculating to check their positions and set their flags in the same way
Step through all the flags, if it equals "1" then grab the key code from the array and add it to the key report
***********************************************************************************************/
#include <PS2X_lib.h> //for v1.6
#include <Mouse.h>
#include <Keyboard.h>
//----BLE Stuff----
#include <Arduino.h>
#include <SPI.h>
#if not defined (_VARIANT_ARDUINO_DUE_X_) && not defined(ARDUINO_ARCH_SAMD)
#include <SoftwareSerial.h>
#endif
#include "Adafruit_BLE.h"
#include "Adafruit_BluefruitLE_SPI.h"
#include "Adafruit_BluefruitLE_UART.h"
#include "BluefruitConfig.h"
/* ...hardware SPI, using SCK/MOSI/MISO hardware SPI pins and then user selected CS/IRQ/RST */
Adafruit_BluefruitLE_SPI ble(BLUEFRUIT_SPI_CS, BLUEFRUIT_SPI_IRQ, BLUEFRUIT_SPI_RST);
//----End BLE Stuff----
#define VBATPIN A9
int led1 = A1; //Player 1 mode
int led2 = A2; //Player 2 mode
int led3 = A3; //Player 3 mode
int led4 = A4; //Player 4 mode
int led5 = A5; //Joystick is in mouse mode
PS2X ps2x; // create PS2 Controller Class
byte player = 1; // 1=player 1, 2=player 2, 3=player 3, 4=player 4
byte vibrate = 0;
boolean shift = 0; // Flag for when select button is pushed
boolean joyMouse = 0; // 0=keyboard, 1=mouse
int joyMouseSense = 6; // Increase this to move mouse slower
//joystick analog positions
int ly;
int lx;
int ry;
int rx;
//distance from joystick center to trigger a keystroke output
int deadband = 64;
//Button flags and key codes for 1 - 4 players in hex ie. "-04" is a, "-28" is ENTER, NOT ASCII **See the list at the bottom of the code below**
//char *[button] = {button pressed flag, player 1 key, player 2 key, player 3 key, player 4 key};
//Joysticks to button flags and keyboard codes for 4 players
// flag P1 P2 P3 P4
char *lu[] = {"0", "-08", "-56", "-08", "-56"}; //e, NUMPAD - player 1 & 3 are the same
char *ld[] = {"0", "-07", "-57", "-07", "-57"}; //d, NUMPAD +
char *ll[] = {"0", "-16", "-54", "-16", "-54"}; //s, NUMPAD / plaver 2 & 4 are the same
char *lr[] = {"0", "-09", "-55", "-09", "-55"}; //f, NUMPAD *
char *ru[] = {"0", "-0C", "-5F", "-0C", "-5F"}; //i, NUMPAD 7
char *rd[] = {"0", "-0E", "-5B", "-0E", "-5B"}; //k, NUMPAD 3
char *rl[] = {"0", "-0D", "-59", "-0D", "-59"}; //j, NUMPAD 1
char *rr[] = {"0", "-0F", "-61", "-0F", "-61"}; //l, NUMPAD 9
//D-pad buttons
// flag P1 P2 P3 P4
char *PAD_UP[] = {"0", "-52", "-15", "-0C", "-60"}; //UP ARROW, r, i, NUMPAD 8
char *PAD_DOWN[] = {"0", "-51", "-09", "-0E", "-5A"}; //DOWN ARROW, f, k, NUMPAD 2
char *PAD_LEFT[] = {"0", "-50", "-07", "-0D", "-5C"}; //LEFT ARROW, d, j, NUMPAD 4
char *PAD_RIGHT[] = {"0", "-4F", "-0A", "-0F", "-5E"}; //RIGHT ARROW, g, l, NUMPAD 6
//Right side buttons
char *BLUE[] = {"0", "", "-04", "", "-62"}; //LEFT CTRL, a, RIGHT CTRL, NUMPAD 0
char *RED[] = {"0", "", "-16", "", "-63"}; //LEFT ALT, s, RIGHT SHIFT, NUMPAD .
char *PINK[] = {"0", "-2C", "-14", "-28", "-58"}; //SPACEBAR, q, RETURN, NUMPAD ENTER
char *GREEN[] = {"0", "", "-1A", "-1A", "-1A"}; //LEFT SHIFT, w, w, w
//Top buttons
char *L1[] = {"0", "-28", "-28", "-28", "-28"}; //RETURN, RETURN, RETURN, RETURN
char *L2[] = {"0", "-29", "-29", "-29", "-29"}; //ESCAPE, ESCAPE, ESCAPE, ESCAPE
char *R1[] = {"0", "-1E", "-1F", "-20", "-21"}; //1, 2, 3, 4
char *R2[] = {"0", "-22", "-23", "-24", "-25"}; //5, 6, 7, 8
boolean START = 0;
boolean SELECT = 0;
byte MOD1 = 0; //Keyboard modifier byte 00001111
byte MOD2 = 0; //Keyboard modifier byte 11110000
String buttonsPressed = ""; //blekeyboardcode string
String lastButtonsPressed = ""; //Last blekeyboardcode sent
// cycles per second variables
int cycleCount = 0;
long nextStep = millis() + 1000;
bool count = false;
bool debug = false;
void setup() {
delay(2000);
ps2x.config_gamepad(6, 11, 10, 12, true, true); // setup pins and settings: GamePad(clock, command, attention, data, Pressures?, Rumble?) check for error
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(led3, OUTPUT);
pinMode(led4, OUTPUT);
pinMode(led5, OUTPUT);
digitalWrite(led1, HIGH); // set leds to show player 1
digitalWrite(led2, LOW);
digitalWrite(led3, LOW);
digitalWrite(led4, LOW);
digitalWrite(led5, LOW);
//----BLE Setup----
ble.begin(VERBOSE_MODE);
ble.sendCommandCheckOK(F( "AT+BleHIDEn=On" ));
//ble.sendCommandCheckOK(F( "AT+BleKeyboardEn=On" ));
ble.sendCommandCheckOK(F( "ATZ" ));
//----End of the BLE Stuff
}
void loop() {
if (count) { //cycles per second routine
cycleCount++;
if (millis() > nextStep) {
Serial.print("Cycles per second = ");
Serial.println(cycleCount);
cycleCount = 0;
nextStep = millis() + 1000;
}
}
//Check battery level
float measuredvbat = analogRead(VBATPIN);
measuredvbat *= 2; // we divided by 2, so multiply back
measuredvbat *= 3.3; // Multiply by 3.3V, our reference voltage
measuredvbat /= 1024; // convert to voltage
//Serial.print("VBat: " ); Serial.println(measuredvbat);
if (measuredvbat < 3.5) {
digitalWrite(led1, HIGH); // Battery low
digitalWrite(led2, HIGH); // light up all LEDs
digitalWrite(led3, HIGH);
digitalWrite(led4, HIGH);
digitalWrite(led5, HIGH);
}
ps2x.read_gamepad(false, vibrate); // read controller and set large motor to spin at 'vibrate' speed **not connected**
if (ps2x.ButtonPressed(PSB_SELECT) && shift == 0) {
shift = 1;
}
if (ps2x.ButtonReleased(PSB_SELECT) && shift == 1) {
shift = 0;
ble.println("AT+BleKeyboardCode=00-00"); //Just to make sure all keys are released
}
//--------------------------------------------------------------------------------
if (shift == 1) { // SELECT button is being held
if (ps2x.ButtonPressed(PSB_START)) { // button START pressed to select player
if (player == 1) {
player = 2;
digitalWrite(led1, LOW);
digitalWrite(led2, HIGH);
if (debug) {
Serial.println("player = 2");
}
}
else if (player == 2) {
player = 3;
digitalWrite(led2, LOW);
digitalWrite(led3, HIGH);
if (debug) {
Serial.println("player = 3");
}
}
else if (player == 3) {
player = 4;
digitalWrite(led3, LOW);
digitalWrite(led4, HIGH);
if (debug) {
Serial.println("player = 4");
}
}
else if (player == 4) {
player = 1;
digitalWrite(led4, LOW);
digitalWrite(led1, HIGH);
if (debug) {
Serial.println("player = 1");
}
}
}
//if(ps2x.ButtonReleased(PSB_START))
if (ps2x.ButtonPressed(PSB_R1)) { // button R1 raises mouse speed
joyMouseSense--;
joyMouseSense = constrain(joyMouseSense, 1, 8);
}
if (ps2x.ButtonPressed(PSB_R2)) { // button R2 lowers mouse speed
joyMouseSense++;
joyMouseSense = constrain(joyMouseSense, 1, 8);
}
if (ps2x.ButtonPressed(PSB_BLUE)) { // button(R3) RIGHT JOYSTICK turn on/off mouse joystick
if (joyMouse == 0) { // The BLUE X is easier
joyMouse = 1;
digitalWrite(led5, HIGH); // mouse mode enabled
}
else {
joyMouse = 0;
digitalWrite(led5, LOW); // disable mouse mode
}
}
}
else {
//-------------------------------------------------------------
//Direction pad on left // SELECT is not pressed (normal gaming mode)
if (ps2x.ButtonPressed(PSB_PAD_UP)) // D-pad UP
PAD_UP[0] = "1";
if (ps2x.ButtonReleased(PSB_PAD_UP))
PAD_UP[0] = "0";
if (ps2x.ButtonPressed(PSB_PAD_DOWN)) // D-pad DOWN
PAD_DOWN[0] = "1";
if (ps2x.ButtonReleased(PSB_PAD_DOWN))
PAD_DOWN[0] = "0";
if (ps2x.ButtonPressed(PSB_PAD_LEFT)) // D-pad LEFT
PAD_LEFT[0] = "1";
if (ps2x.ButtonReleased(PSB_PAD_LEFT))
PAD_LEFT[0] = "0";
if (ps2x.ButtonPressed(PSB_PAD_RIGHT)) // D-pad RIGHT
PAD_RIGHT[0] = "1";
if (ps2x.ButtonReleased(PSB_PAD_RIGHT))
PAD_RIGHT[0] = "0";
//Buttons on right
if (ps2x.ButtonPressed(PSB_BLUE)) // button X
BLUE[0] = "1";
if (ps2x.ButtonReleased(PSB_BLUE))
BLUE[0] = "0";
if (ps2x.ButtonPressed(PSB_RED)) // button CIRCLE
RED[0] = "1";
if (ps2x.ButtonReleased(PSB_RED))
RED[0] = "0";
if (ps2x.ButtonPressed(PSB_PINK)) // button SQUARE
PINK[0] = "1";
if (ps2x.ButtonReleased(PSB_PINK))
PINK[0] = "0";
if (ps2x.ButtonPressed(PSB_GREEN)) // button TRIANGLE
GREEN[0] = "1";
if (ps2x.ButtonReleased(PSB_GREEN))
GREEN[0] = "0";
//Top buttons
if (ps2x.ButtonPressed(PSB_L1)) // top left L1
L1[0] = "1";
if (ps2x.ButtonReleased(PSB_L1))
L1[0] = "0";
if (ps2x.ButtonPressed(PSB_L2)) // bottom left L2
L2[0] = "1";
if (ps2x.ButtonReleased(PSB_L2))
L2[0] = "0";
if (ps2x.ButtonPressed(PSB_R1)) // top right R1
R1[0] = "1";
if (ps2x.ButtonReleased(PSB_R1))
R1[0] = "0";
if (ps2x.ButtonPressed(PSB_R2)) // bottom right R2
R2[0] = "1";
if (ps2x.ButtonReleased(PSB_R2))
R2[0] = "0";
if (ps2x.ButtonPressed(PSB_START)) // button START
START = 1;
if (ps2x.ButtonReleased(PSB_START))
START = 0;
//Joystick controls
ly = ps2x.Analog(PSS_LY); // Read joystick positions
lx = ps2x.Analog(PSS_LX);
ry = ps2x.Analog(PSS_RY);
rx = ps2x.Analog(PSS_RX);
if (joyMouse == 1) { // Joystick is in mouse mode
int mx = ((lx - 128) / joyMouseSense); //+((rx-128)/joyMouseSense);
int my = ((ly - 128) / joyMouseSense); //+((ry-128)/joyMouseSense);
mx = constrain(mx, -127, 127);
my = constrain(my, -127, 127);
if (!mx == 0 || !my == 0) //joystick is not centered
ble.println("AT+BLEHIDMOUSEMOVE=" + String(mx) + "," + String(my));
}
else { // Joystick is in keyboard mode
if (ly < 128 - deadband && lu[0] == "0") //Left joystick up
lu[0] = "1";
else if (ly > 128 - deadband && lu[0] == "1")
lu[0] = "0";
if (ly > 128 + deadband && ld[0] == "0") //Left joystick down
ld[0] = "1";
else if (ly < 128 + deadband && ld[0] == "1")
ld[0] = "0";
if (lx < 128 - deadband && ll[0] == "0") //Left joystick left
ll[0] = "1";
else if (lx > 128 - deadband && ll[0] == "1")
ll[0] = "0";
if (lx > 128 + deadband && lr[0] == "0") //Left joystick right
lr[0] = "1";
else if (lx < 128 + deadband && lr[0] == "1")
lr[0] = "0";
if (ry < 128 - deadband && ru[0] == "0") //Right joystick up
ru[0] = "1";
else if (ry > 128 - deadband && ru[0] == "1")
ru[0] = "0";
if (ry > 128 + deadband && rd[0] == "0") //Right joystick down
rd[0] = "1";
else if (ry < 128 + deadband && rd[0] == "1")
rd[0] = "0";
if (rx < 128 - deadband && rl[0] == "0") //Right joystick left
rl[0] = "1";
else if (rx > 128 - deadband && rl[0] == "1")
rl[0] = "0";
if (rx > 128 + deadband && rr[0] == "0") //Right joystick right
rr[0] = "1";
else if (rx < 128 + deadband && rr[0] == "1")
rr[0] = "0";
}
//----------------------------------------------------------------------------
//add up the key report to be sent
buttonsPressed = "AT+BleKeyboardCode=";
if (player == 1) { //Dealing with the modifier byte for the key report
MOD1 = 0;
if (BLUE[0] == "1") //Left Control
MOD1 += 1;
if (RED[0] == "1") //Left Alt
MOD1 += 4;
if (GREEN[0] == "1") //Left Shift
MOD1 += 2;
}
if (player == 3) {
MOD2 = 0;
if (BLUE[0] == "1") //Right Control
MOD2 += 1;
if (RED[0] == "1") //Right Alt
MOD2 += 4;
}
buttonsPressed += String(MOD2) + String(MOD1) + "-00";
if (BLUE[0] == "1") //Add right side buttons to the key report
buttonsPressed += BLUE[player];
if (RED[0] == "1")
buttonsPressed += RED[player];
if (PINK[0] == "1")
buttonsPressed += PINK[player];
if (GREEN[0] == "1")
buttonsPressed += GREEN[player];
if (PAD_UP[0] == "1") //Add d-pad to the key report
buttonsPressed += PAD_UP[player];
if (PAD_DOWN[0] == "1")
buttonsPressed += PAD_DOWN[player];
if (PAD_LEFT[0] == "1")
buttonsPressed += PAD_LEFT[player];
if (PAD_RIGHT[0] == "1")
buttonsPressed += PAD_RIGHT[player];
if (L1[0] == "1") //Add the top buttons to the key report
buttonsPressed += L1[player];
if (L2[0] == "1")
buttonsPressed += L2[player];
if (R1[0] == "1")
buttonsPressed += R1[player];
if (R2[0] == "1")
buttonsPressed += R2[player];
if (lu[0] == "1") //Add joysticks to the key report
buttonsPressed += lu[player];
if (ld[0] == "1")
buttonsPressed += ld[player];
if (ll[0] == "1")
buttonsPressed += ll[player];
if (lr[0] == "1")
buttonsPressed += lr[player];
if (ru[0] == "1")
buttonsPressed += ru[player];
if (rd[0] == "1")
buttonsPressed += rd[player];
if (rl[0] == "1")
buttonsPressed += rl[player];
if (rr[0] == "1")
buttonsPressed += rr[player];
if (START)
buttonsPressed += "-13"; // "p" key stroke for pause in MAME games
if (!buttonsPressed.equals(lastButtonsPressed)) //If key report has changed, send the new one
{
lastButtonsPressed = buttonsPressed;
ble.println(buttonsPressed);
ble.waitForOK();
/*Serial.print("buttonsPressed = ");
Serial.println(buttonsPressed);
Serial.print("tmp = ");
Serial.println(tmp);
*/
}
}
delay(20);
}
/*
0x00 Reserved (no event indicated)
0x01 Keyboard ErrorRollOver
0x02 Keyboard POSTFail
0x03 Keyboard ErrorUndefined
0x04 Keyboard a and A
0x05 Keyboard b and B
0x06 Keyboard c and C
0x07 Keyboard d and D
0x08 Keyboard e and E
0x09 Keyboard f and F
0x0A Keyboard g and G
0x0B Keyboard h and H
0x0C Keyboard i and I
0x0D Keyboard j and J
0x0E Keyboard k and K
0x0F Keyboard l and L
0x10 Keyboard m and M
0x11 Keyboard n and N
0x12 Keyboard o and O
0x13 Keyboard p and P
0x14 Keyboard q and Q
0x15 Keyboard r and R
0x16 Keyboard s and S
0x17 Keyboard t and T
0x18 Keyboard u and U
0x19 Keyboard v and V
0x1A Keyboard w and W
0x1B Keyboard x and X
0x1C Keyboard y and Y
0x1D Keyboard z and Z
0x1E Keyboard 1 and !
0x1F Keyboard 2 and @
0x20 Keyboard 3 and #
0x21 Keyboard 4 and $
0x22 Keyboard 5 and %
0x23 Keyboard 6 and ^
0x24 Keyboard 7 and &
0x25 Keyboard 8 and *
0x26 Keyboard 9 and (
0x27 Keyboard 0 and )
0x28 Keyboard Return (ENTER)
0x29 Keyboard ESCAPE
0x2A Keyboard DELETE (Backspace)
0x2B Keyboard Tab
0x2C Keyboard Spacebar
0x2D Keyboard - and (underscore)
0x2E Keyboard = and +
0x2F Keyboard [ and {
0x30 Keyboard ] and }
0x31 Keyboard \ and |
0x32 Keyboard Non-US # and ~
0x33 Keyboard ; and :
0x34 Keyboard ' and "
0x35 Keyboard Grave Accent and Tilde
0x36 Keyboard, and <
0x37 Keyboard . and >
0x38 Keyboard / and ?
0x39 Keyboard Caps Lock
0x3A Keyboard F1
0x3B Keyboard F2
0x3C Keyboard F3
0x3D Keyboard F4
0x3E Keyboard F5
0x3F Keyboard F6
0x40 Keyboard F7
0x41 Keyboard F8
0x42 Keyboard F9
0x43 Keyboard F10
0x44 Keyboard F11
0x45 Keyboard F12
0x46 Keyboard PrintScreen
0x47 Keyboard Scroll Lock
0x48 Keyboard Pause
0x49 Keyboard Insert
0x4A Keyboard Home
0x4B Keyboard PageUp
0x4C Keyboard Delete Forward
0x4D Keyboard End
0x4E Keyboard PageDown
0x4F Keyboard RightArrow
0x50 Keyboard LeftArrow
0x51 Keyboard DownArrow
0x52 Keyboard UpArrow
0x53 Keypad Num Lock and Clear
0x54 Keypad /
0x55 Keypad *
0x56 Keypad -
0x57 Keypad +
0x58 Keypad ENTER
0x59 Keypad 1 and End
0x5A Keypad 2 and Down Arrow
0x5B Keypad 3 and PageDn
0x5C Keypad 4 and Left Arrow
0x5D Keypad 5
0x5E Keypad 6 and Right Arrow
0x5F Keypad 7 and Home
0x60 Keypad 8 and Up Arrow
0x61 Keypad 9 and PageUp
0x62 Keypad 0 and Insert
0x63 Keypad . and Delete
0x64 Keyboard Non - US \ and |
0x65 Keyboard Application
0x66 Keyboard Power
0x67 Keypad =
0x68 Keyboard F13
0x69 Keyboard F14
0x6A Keyboard F15
0x6B Keyboard F16
0x6C Keyboard F17
0x6D Keyboard F18
0x6E Keyboard F19
0x6F Keyboard F20
0x70 Keyboard F21
0x71 Keyboard F22
0x72 Keyboard F23
0x73 Keyboard F24
0x74 Keyboard Execute
0x75 Keyboard Help
0x76 Keyboard Menu
0x77 Keyboard Select
0x78 Keyboard Stop
0x79 Keyboard Again
0x7A Keyboard Undo
0x7B Keyboard Cut
0x7C Keyboard Copy
0x7D Keyboard Paste
0x7E Keyboard Find
0x7F Keyboard Mute
0x80 Keyboard Volume Up
0x81 Keyboard Volume Down
0x82 Keyboard Locking Caps Lock
0x83 Keyboard Locking Num Lock
0x84 Keyboard Locking Scroll Lock
0x85 Keypad Comma
0x86 Keypad Equal Sign
0x87 Keyboard International1
0x88 Keyboard International2
0x89 Keyboard International3
0x8A Keyboard International4
0x8B Keyboard International5
0x8C Keyboard International6
0x8D Keyboard International7
0x8E Keyboard International8
0x8F Keyboard International9
0x90 Keyboard LANG1
0x91 Keyboard LANG2
0x92 Keyboard LANG3
0x93 Keyboard LANG4
0x94 Keyboard LANG5
0x95 Keyboard LANG6
0x96 Keyboard LANG7
0x97 Keyboard LANG8
0x98 Keyboard LANG9
0x99 Keyboard Alternate Erase
0x9A Keyboard SysReq / Attention
0x9B Keyboard Cancel
0x9C Keyboard Clear
0x9D Keyboard Prior
0x9E Keyboard Return
0x9F Keyboard Separator
0xA0 Keyboard Out
0xA1 Keyboard Oper
0xA2 Keyboard Clear / Again
0xA3 Keyboard CrSel / Props
0xA4 Keyboard ExSel
0xE0 Keyboard LeftControl
0xE1 Keyboard LeftShift
0xE2 Keyboard LeftAlt
0xE3 Keyboard Left GUI
0xE4 Keyboard RightControl
0xE5 Keyboard RightShift
0xE6 Keyboard RightAlt
0xE7 Keyboard Right GUI
*/
Please be positive and constructive with your questions and comments.