Hi all,
I'm working on a personal project to use an Arduino Nano V3 (clone) as a PS2 Keyboard driver.
I know there are many libraries available for use, but I'd like to script my own so I can understand what's going on under the hood. That's how I like to learn things...
So I went off to the keyboards/keypads section of the playground
(Arduino Playground - PS2Keyboard)
Where I came across one written by Christian Weichel
Version History
002
Attach:PS2Keyboard002.zip
This library is at a very early stage. If anyone wants to revise/rewrite it, feel free to do so (published under the LGPL).
https://playground.arduino.cc/uploads/Main/PS2Keyboard002/index.zip
It was exactly what I was seeking, something at an early stage and not packed with C++ code which I don't understand, since I only really know BASIC language.
So I added the bits necessary to bring it half way to completion, and its compiled without errors, but I would love to know if it would work or not, currently I don't own any Arduino devices, so if someone could test it for me or look at the code and pinpoint any issues, that would be super...
void loop() {
// put your main code here, to run repeatedly:
}
I guess also that in the method listed above, I need to add code to transmit the asci code out to the host, but I'll have to research into that as i haven't reached that point yet.
My code is attached below, Thanks
The device I aim to use is the Arduino Nano 3 clone
(USB Nano V3.0 ATmega328 16M 5V Micro-controller CH340G board For Arduino)
This is the main program/sketch
/*
_JD_ASCIKEYCODES_
Define supported asci keys
*/
#ifndef _JD_ASCIKEYCODES_
#include "JD_AsciKeyCodes.h"
#endif
/*
_JD_PS2SCANCODES_
Define supported PS2 keyboard scancodes
*/
#ifndef _JD_PS2SCANCODES_
#include "JD_PS2ScanCodes.h"
#endif
/*
Define KeyTable Array - KeyTbl[x,y]
This will be our lookup table
Currently contains 69 key/value items for 69 pairs of keys/values
*/
#define PS2_LUT_Items 69
byte KeyTbl[2][69] = {SC1M_A, KEY_LCA, SC1M_B, KEY_LCB, SC1M_C, KEY_LCC, SC1M_D, KEY_LCD, SC1M_E, KEY_LCE, SC1M_F, KEY_LCF, SC1M_G, KEY_LCG, SC1M_H, KEY_LCH,
SC1M_I, KEY_LCI, SC1M_J, KEY_LCJ, SC1M_K, KEY_LCK, SC1M_l, KEY_LCL, SC1M_M, KEY_LCM, SC1M_N, KEY_LCN, SC1M_O, KEY_LCO, SC1M_P, KEY_LCP, SC1M_Q, KEY_LCQ, SC1M_R,
KEY_LCR, SC1M_S, KEY_LCS, SC1M_T, KEY_LCT, SC1M_U, KEY_LCU, SC1M_V, KEY_LCV, SC1M_W, KEY_LCW, SC1M_X, KEY_LCX, SC1M_Y, KEY_LCY, SC1M_Z, KEY_LCZ, SC1M_0, KEY_0,
SC1M_1, KEY_1, SC1M_2, KEY_2, SC1M_3, KEY_3, SC1M_4, KEY_4, SC1M_5, KEY_5, SC1M_6, KEY_6, SC1M_7, KEY_7, SC1M_8, KEY_8, SC1M_9, KEY_9, SC1M_SPACE, KEY_SPACE,
SC1M_BKSLASH, KEY_BACKSLASH, SC1M_FWDSLASH, KEY_FWDSLASH, SC1M_APOSTROPHE, KEY_APOSTROPHE, SC1M_COMMA, KEY_COMMA, SC1M_PERIOD, KEY_PERIOD, SC1M_SEMICOLON,
KEY_SEMICOLON, SC1M_MINUS, KEY_MINUS, SC1M_EQUALS, KEY_EQUALS, SC1M_OSQRPARENS, KEY_OSQRPAR, SC1M_CSQRPARENS, KEY_CSQRPAR, SC1M_BACKTICK, KEY_BACKTICK,
SC1M_KP0, KEY_0, SC1M_KP1, KEY_1, SC1M_KP2, KEY_2, SC1M_KP3, KEY_3, SC1M_KP4, KEY_4, SC1M_KP5, KEY_5, SC1M_KP6, KEY_6, SC1M_KP7, KEY_7, SC1M_KP8, KEY_8,
SC1M_KP9, KEY_9, SC1M_KPPLUS, KEY_PLUS, SC1M_KPMINUS, KEY_MINUS, SC1M_KPMULTIPLY, KEY_MULTIPLY, SC1M_KPPERIOD, KEY_PERIOD, SC2M_KPDIVIDE, KEY_DIVIDE,
SC2M_KPENTER, KEY_ENTER, SC1M_TAB, KEY_TAB, SC1M_ESCAPE, KEY_ESCAPE, SC1M_ENTER, KEY_ENTER, SC1M_BKSPC, KEY_BACKSPACE, SC2M_DEL, KEY_DELETE};
/*
This PIN is hardcoded in the init routine later on.
If you change this make sure you change the interrupt initialization as well.
*/
#define PS2_INT_PIN 3
/*
Driver System Variables
The variables below are used for internal management of the driver.
PLEASE DO NOT REFER TO THESE VARIABLES IN YOUR CODE AS THEY MIGHT VANISH ONE DAY!.
*/
int JD_PS2DataPin; // A variable to hold the PS2 comms datapin id (mcu to ps2 device - sda)
byte JD_PS2Buf[8]; // An 8 byte buffer to store keypresses which have not yet been read by the host
byte JD_PS2BufHead; // The current position in the buffer
byte JD_PS2BufTail; // The current position in the buffer
byte JD_PS2BufFull; // Flag that signifiesbuffer is full
byte JD_PS2IntPos; // The current bit position in the interrupt io buffer
byte JD_PS2IntByte; // Current byte in intterupt input buffer
byte JD_PS2Byte2Dcd; // Byte to be decoded
byte JD_PS2BreakActive; // whether the mcu is in break mode or not?
volatile byte JD_PS2IntBuf; // The single byte character buffer accessed within the interrupt method
/*
PS2_IsrOn3()
The ISR for the external interrupt
*/
void PS2_IsrOn3() {
noInterrupts();
int value = digitalRead(JD_PS2DataPin); // Current state of PS2 interface sda pin
if(JD_PS2IntPos > 0 && JD_PS2IntPos < 9) {
JD_PS2IntBuf |= (value << (JD_PS2IntPos - 1));
// else
// this is a start bit, parity bit or stop bit - so we skip it
}
JD_PS2IntPos++;
if(JD_PS2IntPos == 11) {
if(JD_PS2IntBuf == SC2M_PAUSE){
JD_PS2BreakActive = true;
} else if(JD_PS2BreakActive) {
JD_PS2BreakActive = false;
} else {
JD_PS2IntByte = JD_PS2IntBuf;
if (!(JD_PS2BufHead == JD_PS2BufTail)) {
// add key to buffer and advance
JD_PS2Buf[JD_PS2BufTail] = JD_PS2IntByte;
JD_PS2BufTail++;
if (JD_PS2BufTail > 7) {
JD_PS2BufTail = 0;
}
} else {
// key buffer is full
JD_PS2BufFull = true;
}
}
JD_PS2IntBuf = 0;
JD_PS2IntPos = 0;
interrupts();
return;
}
}
/*
Class clsJD_PS2Keyboard
Complete class for handling PS2 keyboard input
*/
class clsJD_PS2Keyboard {
private:
/*
PS2_InitProgVars
Initialises program variables
*/
void PS2_InitProgVars(byte pbDataPin) {
byte tmpRtn;
JD_PS2DataPin = pbDataPin; // Assign data io pin-id
JD_PS2BufHead = 0; // Set buffer head to first byte position
JD_PS2BufTail = 0; // Set buffer tail to first byte position
JD_PS2BufFull = false; // Set buffer full flag to false
JD_PS2IntPos = 0; // Set io bit postion in comms frame to first bit
JD_PS2IntBuf = 0; // Clear interrupt byte buffer to zero
JD_PS2IntByte = 0; // Clear interrupt final byte value to null
JD_PS2Byte2Dcd = 0; // Clear vyte to decode var
for (tmpRtn = 0; tmpRtn < 8; tmpRtn++) {
JD_PS2Buf[tmpRtn] = 0;
}
}
/*
PS2_DecodeKey
Decodes the scancode into an asci key code or 0 on failiure
*/
byte PS2_DecodeKey() {
byte tmpRtn;
byte tmpScId;
tmpRtn = 0;
for (tmpScId = 0; tmpScId <= 69; tmpScId++) {
if (KeyTbl[0][tmpScId] == JD_PS2Byte2Dcd) {
tmpRtn = KeyTbl[1][tmpScId];
return tmpRtn;
}
}
}
public:
/*
Begin()
The entry point
*/
void Begin(byte pbDataPin) {
PS2_InitProgVars(pbDataPin);
pinMode(PS2_INT_PIN, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(PS2_INT_PIN), PS2_IsrOn3, CHANGE);
}
/*
PS2_HasKey()
A function which returns whether a key (press) exists in the keyboard keys buffer.
it will only advance through keyboard buffer if no key is found.
Returns: True - a key exists in the buffer
False - No keys exist in keyboard keys buffer or keyboard keys buffer is empty
*/
byte PS2_HasKey() {
return (!(JD_PS2BufHead == JD_PS2BufTail));
}
/*
PS2_GetKey()
A function to return the key at the current position in the keyboard keys buffer.
Returns: Key - The key from the buffer (if one exists)
0 - Returns 0 if keyboard keys buffer is empty
*/
byte PS2_GetKey() {
byte tmpRtn;
tmpRtn = 0;
if (!(JD_PS2BufHead == JD_PS2BufTail)){
JD_PS2Byte2Dcd = JD_PS2Buf[JD_PS2BufHead];
tmpRtn = PS2_DecodeKey();
JD_PS2BufHead++;
if (JD_PS2BufHead > 7){
JD_PS2BufHead = 0;
}
}
return tmpRtn;
}
/*
PS2_BufferFull()
A function which returns whether the buffer is full or not
Returns: True - When the buffer is full
False - When the buffer has free space
*/
byte PS2_BufferFull() {
return JD_PS2BufFull;
}
};
clsJD_PS2Keyboard JD_PS2;
void setup() {
// put your setup code here, to run once:
JD_PS2.Begin(11);
}
void loop() {
// put your main code here, to run repeatedly:
if(JD_PS2.PS2_HasKey() == true){
byte ascikey = JD_PS2.PS2_GetKey();
// send ascikey out through an output pin to host
// to be completed
}
}
This is the ascii keys definition include file
/*
JD_PS2Keyboard - PS 2Keyboard Driver
Copyright (c) 2021 Jaan Doh. All rights reserved.
Written by Jaan Doh <jaan.doh.786@gmail.com>
This code module: Include file containing asci key codes supported by this program
This code file: JD_AsciKeyCodes.h
This program/library is a fork from PS2Keyboard_002 originally written by Christian Weichel <info@32leaves.net>.
PS2Keyboard.h - PS2Keyboard library
Copyright (c) 2007 Free Software Foundation. All rights reserved.
Written by Christian Weichel <info@32leaves.net>
Url: https://playground.arduino.cc/Main/PS2Keyboard/
Source Url: https://playground.arduino.cc/uploads/Main/PS2Keyboard002/index.zip
This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General
Public License as published by the Free Software Foundation;
either version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with this library;
If not, write to:
The Free Software Foundation, Inc.,
51 Franklin St,
Fifth Floor,
Boston,
MA 02110-1301
USA
*/
#ifndef _JD_ASCIKEYCODES_
//
#define _JD_ASCIKEYCODES_
//
// '===============================================================================================================
// '=> [START] JD ASCI KEY DEFINITIONS
// '===============================================================================================================
// '---------------------------------------------------------------------------------------------------------------
//'-> [Start] Asci Key Codes - Non Visible Keys [5]
// '---------------------------------------------------------------------------------------------------------------
const byte KEY_BACKSPACE = 8; // 'Back-Space
const byte KEY_TAB = 9; // 'Tab
const byte KEY_LINEFEED = 10; // 'Line-Feed
const byte KEY_ENTER = 13; // 'Enter
const byte KEY_ESCAPE = 27; // 'Escape
const byte KEY_DELETE = 127; // 'Delete
// '---------------------------------------------------------------------------------------------------------------
// '-> [Start] Asci Key Codes - Visible Keys [96]
// '---------------------------------------------------------------------------------------------------------------
const byte KEY_SPACE = 32; // 'Space
const byte KEY_EXCLAIM = 33; // '!
const byte KEY_DBLQUOTE = 34; // '"
const byte KEY_HASH = 35; // '#
const byte KEY_DOLLAR= 36; // '$
const byte KEY_PERCENT = 37; // '%
const byte KEY_AMPERSAND = 38; // '&
const byte KEY_APOSTROPHE = 39; // ''
const byte KEY_OBRACKET = 40; // '(
const byte KEY_CBRACKET = 41; // ')
const byte KEY_MULTIPLY = 42; // '*
const byte KEY_PLUS = 43; // '+
const byte KEY_COMMA = 44; // ',
const byte KEY_MINUS = 45; // '-
const byte KEY_PERIOD = 46; // '.
const byte KEY_DIVIDE = 47; // '/
const byte KEY_FWDSLASH = 47; // '/
const byte KEY_0 = 48; // '0
const byte KEY_1 = 49; // '1
const byte KEY_2 = 50; // '2
const byte KEY_3 = 51; // '3
const byte KEY_4 = 52; // '4
const byte KEY_5 = 53; // '5
const byte KEY_6 = 54; // '6
const byte KEY_7 = 55; // '7
const byte KEY_8 = 56; // '8
const byte KEY_9 = 57; // '9
const byte KEY_COLON = 58; // ':
const byte KEY_SEMICOLON = 59; // ';
const byte KEY_LESSTHAN = 60; // '<
const byte KEY_EQUALS = 61; // '=
const byte KEY_MORETHAN = 62; // '>
const byte KEY_QUESTION = 63; // '?
const byte KEY_ATSYMBOL = 64; // '@
const byte KEY_UCA = 65; // 'A
const byte KEY_UCB = 66; // 'B
const byte KEY_UCC = 67; // 'C
const byte KEY_UCD = 68; // 'D
const byte KEY_UCE = 69; // 'E
const byte KEY_UCF = 70; // 'F
const byte KEY_UCG = 71; // 'G
const byte KEY_UCH = 72; // 'H
const byte KEY_UCI = 73; // 'I
const byte KEY_UCJ = 74; // 'J
const byte KEY_UCK = 75; // 'K
const byte KEY_UCL = 76; // 'L
const byte KEY_UCM = 77; // 'M
const byte KEY_UCN = 78; // 'N
const byte KEY_UCO = 79; // 'O
const byte KEY_UCP = 80; // 'P
const byte KEY_UCQ = 81; // 'Q
const byte KEY_UCR = 82; // 'R
const byte KEY_UCS = 83; // 'S
const byte KEY_UCT = 84; // 'T
const byte KEY_UCU = 85; // 'U
const byte KEY_UCV = 86; // 'V
const byte KEY_UCW = 87; // 'W
const byte KEY_UCX = 88; // 'X
const byte KEY_UCY = 89; // 'Y
const byte KEY_UCZ = 90; // 'Z
const byte KEY_OSQRPAR = 91; // '[
const byte KEY_BACKSLASH = 92; // '\\ had to write backslash twice for some mad reason
const byte KEY_CSQRPAR = 93; // ']
const byte KEY_CARAT = 94; // '^
const byte KEY_UNDERSCORE = 95; // '_
const byte KEY_BACKTICK = 96; // '`
const byte KEY_LCA = 97; // 'a
const byte KEY_LCB = 98; // 'b
const byte KEY_LCC = 99; // 'c
const byte KEY_LCD = 100; // 'd
const byte KEY_LCE = 101; // 'e
const byte KEY_LCF = 102; // 'f
const byte KEY_LCG = 103; // 'g
const byte KEY_LCH = 104; // 'h
const byte KEY_LCI = 105; // 'i
const byte KEY_LCJ = 106; // 'j
const byte KEY_LCK = 107; // 'k
const byte KEY_LCL = 108; // 'l
const byte KEY_LCM = 109; // 'm
const byte KEY_LCN = 110; // 'n
const byte KEY_LCO = 111; // 'o
const byte KEY_LCP = 112; // 'p
const byte KEY_LCQ = 113; // 'q
const byte KEY_LCR = 114; // 'r
const byte KEY_LCS = 115; // 's
const byte KEY_LCT = 116; // 't
const byte KEY_LCU = 117; // 'u
const byte KEY_LCV = 118; // 'v
const byte KEY_LCW = 129; // 'w
const byte KEY_LCX = 120; // 'x
const byte KEY_LCY = 121; // 'y
const byte KEY_LCZ = 122; // 'z
const byte KEY_OCLYPAR = 123; // '{
const byte KEY_PIPE = 124; // '|
const byte KEY_CLYPAR = 125; // '}
const byte KEY_TILDE = 126; // '~
// '---------------------------------------------------------------------------------------------------------------
// '-> [Finish] Asci Key Codes - Total key codes [101]
// '---------------------------------------------------------------------------------------------------------------
// '===============================================================================================================
// '=> [FINISH] JD ASCI KEY DEFINITIONS
// '===============================================================================================================
#endif
This is the scancodes include file
/*
JD_PS2Keyboard - PS 2Keyboard Driver
Copyright (c) 2021 Jaan Doh. All rights reserved.
Written by Jaan Doh <jaan.doh.786@gmail.com>
This code module: Include file containing ps2 scancode set 2 keymake/keybreak scancodes
This code file: JD_PS2ScanCodes.cpp
This program/library is a fork from PS2Keyboard_002 originally written by Christian Weichel <info@32leaves.net>.
PS2Keyboard.h - PS2Keyboard library
Copyright (c) 2007 Free Software Foundation. All rights reserved.
Written by Christian Weichel <info@32leaves.net>
Url: https://playground.arduino.cc/Main/PS2Keyboard/
Source Url: https://playground.arduino.cc/uploads/Main/PS2Keyboard002/index.zip
This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General
Public License as published by the Free Software Foundation;
either version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with this library;
If not, write to:
The Free Software Foundation, Inc.,
51 Franklin St,
Fifth Floor,
Boston,
MA 02110-1301
USA
*/
#ifndef _JD_PS2SCANCODES_
//
#define _JD_PS2SCANCODES_
//
// '===============================================================================================================
// '=> [START] JD SCANCODE MAKE-KEY SCANCODES
// '===============================================================================================================
// '---------------------------------------------------------------------------------------------------------------
//'-> [Start] Single Byte Make-Key Scan Codes - Aphabetic keys [26]
// '---------------------------------------------------------------------------------------------------------------
const byte SC1M_A = 0x1C; // 'A
const byte SC1M_B = 0x32; // 'B
const byte SC1M_C = 0x21; // 'C
const byte SC1M_D = 0x23; // 'D
const byte SC1M_E = 0x24; // 'E
const byte SC1M_F = 0x2B; // 'F
const byte SC1M_G = 0x34; // 'G
const byte SC1M_H = 0x33; // 'H
const byte SC1M_I = 0x43; // 'I
const byte SC1M_J = 0x3B; // 'J
const byte SC1M_K = 0x42; // 'K
const byte SC1M_l = 0x4B; // 'L
const byte SC1M_M = 0x3A; // 'M
const byte SC1M_N = 0x31; // 'N
const byte SC1M_O = 0x44; // 'O
const byte SC1M_P = 0x4D; // 'P
const byte SC1M_Q = 0x15; // 'Q
const byte SC1M_R = 0x2D; // 'R
const byte SC1M_S = 0x1B; // 'S
const byte SC1M_T = 0x2C; // 'T
const byte SC1M_U = 0x3C; // 'U
const byte SC1M_V = 0x2A; // 'V
const byte SC1M_W = 0x1D; // 'W
const byte SC1M_X = 0x22; // 'X
const byte SC1M_Y = 0x35; // 'Y
const byte SC1M_Z = 0x1A; // 'Z
// '---------------------------------------------------------------------------------------------------------------
// '-> [Start] Single Byte Make-Key Scan Codes - Numeric keys [10]
// '---------------------------------------------------------------------------------------------------------------
const byte SC1M_0 = 0x45; // '0
const byte SC1M_1 = 0x16; // '1
const byte SC1M_2 = 0x1E; // '2
const byte SC1M_3 = 0x26; // '3
const byte SC1M_4 = 0x25; // '4
const byte SC1M_5 = 0x2E; // '5
const byte SC1M_6 = 0x36; // '6
const byte SC1M_7 = 0x3D; // '7
const byte SC1M_8 = 0x3E; // '8
const byte SC1M_9 = 0x46; // '9
// '---------------------------------------------------------------------------------------------------------------
// '-> [Start] Single Byte Make-Key Scan Codes - Visible Mixed keys [12]
// '---------------------------------------------------------------------------------------------------------------
const byte SC1M_SPACE = 0x29; // 'Space
const byte SC1M_BKSLASH = 0x5D; // 'Backslash
const byte SC1M_FWDSLASH = 0x4A; // 'Fwd Slash
const byte SC1M_APOSTROPHE = 0x52; // 'Apostrophe
const byte SC1M_COMMA = 0x41; // 'Comma
const byte SC1M_PERIOD = 0x49; // 'Period
const byte SC1M_SEMICOLON = 0x4C; // 'Semicolon
const byte SC1M_MINUS = 0x4E; // 'Minus
const byte SC1M_EQUALS = 0x55; // 'Equals
const byte SC1M_OSQRPARENS = 0x54; // '[
const byte SC1M_CSQRPARENS = 0x5B; // ']
const byte SC1M_BACKTICK = 0x0E; // 'BackTick
// '---------------------------------------------------------------------------------------------------------------
// '-> [Start] Single Byte Make-Key Scan Codes - Non-Visible Mixed keys [11]
// '---------------------------------------------------------------------------------------------------------------
const byte SC1M_LSHIFT = 0x12; // 'L-shift
const byte SC1M_RSHIFT = 0x59; // 'Rshift
const byte SC1M_CAPSLOCK = 0x58; // 'CapsLock
const byte SC1M_LALT = 0x11; // 'L-alt
const byte SC1M_LCTRL = 0x14; // 'L-Ctrl
const byte SC1M_ESCAPE = 0x76; // 'Escape
const byte SC1M_TAB = 0x0D; // 'Tab
const byte SC1M_ENTER = 0x5A; // 'Enter
const byte SC1M_BKSPC = 0x66; // 'Backspace
const byte SC1M_NUMLOCK = 0x77; // 'Num Lock
const byte SC1M_SCRLOCK = 0x7E; // 'Scroll Lock
// '---------------------------------------------------------------------------------------------------------------
// '-> [Start] Single Byte Make-Key Scan Codes - Keypad keys [14]
// '---------------------------------------------------------------------------------------------------------------
const byte SC1M_KP0 = 0x70; // 'KP 0
const byte SC1M_KP1 = 0x69; // 'KP 1
const byte SC1M_KP2 = 0x72; // 'KP 2
const byte SC1M_KP3 = 0x7A; // 'KP 3
const byte SC1M_KP4 = 0x6B; // 'KP 4
const byte SC1M_KP5 = 0x73; // 'KP 5
const byte SC1M_KP6 = 0x74; // 'KP 6
const byte SC1M_KP7 = 0x6C; // 'KP 7
const byte SC1M_KP8 = 0x75; // 'KP 8
const byte SC1M_KP9 = 0x7D; // 'KP 9
const byte SC1M_KPPLUS = 0x79; // 'KP Plus
const byte SC1M_KPMINUS = 0x7B; // 'KP Minus
const byte SC1M_KPMULTIPLY = 0x7C; // 'KP Multiply
const byte SC1M_KPPERIOD = 0x71; // 'KP Period
// '---------------------------------------------------------------------------------------------------------------
// '-> [Start] Double Byte Make-Key Scan Codes - Supported keys [16] - Note: Leading *0xE0* has been stripped out
// '---------------------------------------------------------------------------------------------------------------
const byte SC2M_HOME = 0x6C; // 'Home
const byte SC2M_END = 0x69; // 'End
const byte SC2M_INS = 0x70; // 'Insert
const byte SC2M_DEL = 0x71; // 'Delete
const byte SC2M_PGUP = 0x7D; // 'Page Up
const byte SC2M_PGDN = 0x7A; // 'Page Down
const byte SC2M_LEFT = 0x6B; // 'Csr Left
const byte SC2M_RIGHT = 0x74; // 'Csr Right
const byte SC2M_UP = 0x75; // 'Csr Up
const byte SC2M_DOWN = 0x72; // 'Csr Down
const byte SC2M_KPDIVIDE = 0x4A; // 'KP Divide
const byte SC2M_KPENTER = 0x5A; // 'KP Enter
const byte SC2M_LGUI = 0x1F; // 'LGui
const byte SC2M_RGUI = 0x27; // 'RGui
const byte SC2M_RALT = 0x11; // 'RAlt
const byte SC2M_RCTRL = 0x14; // 'RCtrl
// '---------------------------------------------------------------------------------------------------------------
// '-> [Start] Double Byte Make-Key Scan Codes - Multumedia keys [9] - Note: Leading *0xE0* has been stripped out
// '---------------------------------------------------------------------------------------------------------------
// These are currently not supported
// const byte SC2M_MMPLAY = 0x34; // 'MM Play/Pause
// const byte SC2M_MMSTOP = 0x3B; // 'MM Stop
// const byte SC2M_MMPRVTRK = 0x15; // 'MM Prev Track
// const byte SC2M_MMNXTTRK = 0x4D; // 'MM Next Track
// const byte SC2M_MMSELTRK = 0x50; // 'MM Select
// const byte SC2M_MMVOLUP = 0x32; // 'MM Vol Up
// const byte SC2M_MMVOLDN = 0x21; // 'MM Vol Down
// const byte SC2M_MMVOLMUTE = 0x23; // 'MM Mute
// const byte SC2M_MMCALC = 0x2B; // 'MM calculator
// '---------------------------------------------------------------------------------------------------------------
// '-> [Start] Double Byte Make-Key Scan Codes - Web keys [9] - Note: Leading *0xE0* has been stripped out
// '---------------------------------------------------------------------------------------------------------------
// These are currently not supported
// const byte SC2M_WEBHOME = 0x3A; // 'Web Home
// const byte SC2M_WEBSEARCH = 0x10; // 'Web Search
// const byte SC2M_WEBFAVS = 0x18; // 'Web Favourites
// const byte SC2M_WEBREFRESH = 0x20; // 'Web Refresh
// const byte SC2M_WEBSTOP = 0x28; // 'Web Stop
// const byte SC2M_WEBFWD = 0x30; // 'Web Forward
// const byte SC2M_WEBBACK = 0x38; // 'Web Back
// const byte SC2M_WEBEMAIL = 0x48; // 'Web Email
// '---------------------------------------------------------------------------------------------------------------
// '-> [Start] Double Byte Make-Key Scan Codes - Miscellaneous keys [9] - Note: Leading *0xE0* has been stripped out
// '---------------------------------------------------------------------------------------------------------------
// These are currently not supported
// 'const byte SC2M_APPS = 0x2F; // 'Apps
// 'const byte SC2M_MYPC = 0x40; // 'MyComputer
// 'const byte SC2M_POWER = 0x37; // 'Acpi Power
// 'const byte SC2M_SLEEP = 0x3F; // 'Acpi Sleep
// 'const byte SC2M_WAKE = 0x5E; // 'ACPI Wake
const byte SC2M_PAUSE = 0xE1; // Only first byte is used
// const byte SC2M_PAUSE = 0xE1, 0x14, 0x77, 0xE1, 0xF0, 0x14, 0xF0, 0x77; // 'Pause Pressed
// 'const byte SC2M_PRINTSCREEN = 0xE0, 0x12, 0xE0, 0x7C 0xE0, 0xF0, 0x7C, 0xE0, 0xF0, 0x12; // 'Print Screen
// '---------------------------------------------------------------------------------------------------------------
// '-> [Start] Double Byte Make-Key Scan Codes - Function keys [12] - Note: Leading *0xE0* has been stripped out
// '---------------------------------------------------------------------------------------------------------------
const byte SC1M_F1 = 0x05; // 'F1
const byte SC1M_F2 = 0x06; // 'F2
const byte SC1M_F3 = 0x04; // 'F3
const byte SC1M_F4 = 0x0C; // 'F4
const byte SC1M_F5 = 0x03; // 'F5
const byte SC1M_F6 = 0x0B; // 'F6
const byte SC1M_F7 = 0x83; // 'F7
const byte SC1M_F8 = 0x0A; // 'F8
const byte SC1M_F9 = 0x01; // 'F9
const byte SC1M_F10 = 0x09; // 'F10
const byte SC1M_F11 = 0x78; // 'F11
const byte SC1M_F12 = 0x07; // 'F12
// '---------------------------------------------------------------------------------------------------------------
// '===============================================================================================================
// '=> [FINSIH] JD SCANCODE MAKE-KEY SCANCODES
// '===============================================================================================================
#endif
Thanks