252 satır
5.5 KiB
C++
252 satır
5.5 KiB
C++
// XtKeyboard source: https://forum.arduino.cc/index.php?topic=18396.0
|
|
// XT protocol: https://www.win.tue.nl/~aeb/linux/kbd/scancodes-1.html
|
|
|
|
#include <Keyboard.h>
|
|
|
|
int clockPin = 2;
|
|
int dataPin = 3;
|
|
volatile byte data = B0;
|
|
int test = 0;
|
|
volatile int counter = 0;
|
|
int numbits = 10;
|
|
int speakerPin = 5;
|
|
int keysPressed = 0;
|
|
unsigned long repeatTimeout = 0;
|
|
unsigned long repeatTimeoutValue = 1000;
|
|
const int keyReleaseBit = 0x80;
|
|
|
|
char m[255];
|
|
bool pressed[255];
|
|
|
|
// MODS >>>
|
|
// [1] send debug scancode information to serial port
|
|
bool modConsoleLog = true;
|
|
const int modConsoleLogKey = 59; // F1
|
|
// [2] play speaker sounds of keys
|
|
bool modKeySounds = false;
|
|
const int modKeySoundsKey = 60; // F2
|
|
// [3] replace CapsLock with Super key (aka GUI or Windows key)
|
|
const bool modSuperCapslock = true;
|
|
// [4] stuck key guard: release all the pressed keys if no data comes from the keyboard in a while
|
|
bool modStuckKeyGuard = false;
|
|
// [13] mod switcher: enable changing of active mods!
|
|
const bool modModSwitcher = true;
|
|
const int modSwitcherKey = 55; // PRTSC *
|
|
// <<< MODS
|
|
|
|
// https://www.arduino.cc/en/Reference/KeyboardModifiers
|
|
void setupKeyMapping() {
|
|
m[1]=KEY_ESC;
|
|
m[2]='1';
|
|
m[3]='2';
|
|
m[4]='3';
|
|
m[5]='4';
|
|
m[6]='5';
|
|
m[7]='6';
|
|
m[8]='7';
|
|
m[9]='8';
|
|
m[10]='9';
|
|
m[11]='0';
|
|
m[12]='-';
|
|
m[13]='=';
|
|
m[14]=KEY_BACKSPACE;
|
|
m[15]=KEY_TAB;
|
|
m[16]='q';
|
|
m[17]='w';
|
|
m[18]='e';
|
|
m[19]='r';
|
|
m[20]='t';
|
|
m[21]='y';
|
|
m[22]='u';
|
|
m[23]='i';
|
|
m[24]='o';
|
|
m[25]='p';
|
|
m[26]='[';
|
|
m[27]=']';
|
|
m[28]=KEY_RETURN;
|
|
m[29]=KEY_LEFT_CTRL;
|
|
m[30]='a';
|
|
m[31]='s';
|
|
m[32]='d';
|
|
m[33]='f';
|
|
m[34]='g';
|
|
m[35]='h';
|
|
m[36]='j';
|
|
m[37]='k';
|
|
m[38]='l';
|
|
m[39]=';';
|
|
m[40]='\'';
|
|
m[41]='`';
|
|
m[42]=KEY_LEFT_SHIFT;
|
|
m[43]='\\';
|
|
m[44]='z';
|
|
m[45]='x';
|
|
m[46]='c';
|
|
m[47]='v';
|
|
m[48]='b';
|
|
m[49]='n';
|
|
m[50]='m';
|
|
m[51]=',';
|
|
m[52]='.';
|
|
m[53]='/';
|
|
m[54]=KEY_RIGHT_SHIFT;
|
|
m[55]='\335'; // num-*
|
|
m[56]=KEY_LEFT_ALT;
|
|
m[57]=' ';
|
|
m[58]=(modSuperCapslock ? KEY_LEFT_GUI : KEY_CAPS_LOCK); // EVIL
|
|
m[59]=KEY_F1;
|
|
m[60]=KEY_F2;
|
|
m[61]=KEY_F3;
|
|
m[62]=KEY_F4;
|
|
m[63]=KEY_F5;
|
|
m[64]=KEY_F6;
|
|
m[65]=KEY_F7;
|
|
m[66]=KEY_F8;
|
|
m[67]=KEY_F9;
|
|
m[68]=KEY_F10;
|
|
// https://forum.arduino.cc/index.php?topic=266688.msg1880644#msg1880644
|
|
// http://www.quadibloc.com/comp/scan.htm
|
|
const byte KEY_NUM_LOCK = 219;
|
|
m[69]=KEY_NUM_LOCK;
|
|
const byte KEY_SCROLL_LOCK = 207;
|
|
m[70]=KEY_SCROLL_LOCK;
|
|
m[71]='\347'; // num-7
|
|
m[72]='\350'; // num-8
|
|
m[73]='\351'; // num-9
|
|
m[74]='\336'; // num--
|
|
m[75]='\344'; // num-4
|
|
m[76]='\345'; // num-5
|
|
m[77]='\346'; // num-6
|
|
m[78]='\337'; // num-+
|
|
m[79]='\341'; // num-1
|
|
m[80]='\342'; // num-2
|
|
m[81]='\343'; // num-3
|
|
m[82]='\352'; // num-0
|
|
m[83]='\353'; // num-.
|
|
//...
|
|
m[101]=KEY_F11;
|
|
m[102]=KEY_F12;
|
|
m[107]=KEY_INSERT;
|
|
m[108]=KEY_DELETE;
|
|
m[109]=KEY_UP_ARROW;
|
|
m[110]=KEY_DOWN_ARROW;
|
|
m[111]=KEY_LEFT_ARROW;
|
|
m[112]=KEY_RIGHT_ARROW;
|
|
//m[]=KEY_;
|
|
}
|
|
|
|
char translateKeyToChar(int key) {
|
|
if (sizeof(m) <= key) {
|
|
return 0;
|
|
}
|
|
return m[key];
|
|
}
|
|
|
|
void printChar(char keyChar) {
|
|
Serial.print("'"); Serial.print(keyChar); Serial.print("' ("); Serial.print(int(keyChar)); Serial.print("), Pressed keys: ["); Serial.print(keysPressed); Serial.println("]");
|
|
}
|
|
|
|
void processKbdByte(byte data) {
|
|
bool isRelease = data & keyReleaseBit;
|
|
int key = data - (isRelease ? keyReleaseBit : 0);
|
|
if (modConsoleLog) {
|
|
Serial.print("Scancode: <"); Serial.print(int(data)); Serial.print("> ");
|
|
Serial.print("Key: <"); Serial.print(int(key)); Serial.print("> ");
|
|
}
|
|
char keyChar = translateKeyToChar(key);
|
|
|
|
if (isRelease) {
|
|
Keyboard.release(keyChar);
|
|
if (pressed[key]) {
|
|
pressed[key] = false;
|
|
keysPressed--;
|
|
}
|
|
if (modConsoleLog) {
|
|
Serial.print("Release: ");
|
|
printChar(keyChar);
|
|
}
|
|
} else {
|
|
Keyboard.press(keyChar);
|
|
if (!pressed[key]) {
|
|
pressed[key] = true;
|
|
keysPressed++;
|
|
}
|
|
if (modConsoleLog) {
|
|
Serial.print("Press: ");
|
|
printChar(keyChar);
|
|
}
|
|
}
|
|
}
|
|
|
|
void clearPressedKeys() {
|
|
Keyboard.releaseAll();
|
|
keysPressed = 0;
|
|
for (int i = 0; i < sizeof(pressed); i++) {
|
|
pressed[i] = false;
|
|
}
|
|
Serial.println("Pressed keys list cleared.");
|
|
}
|
|
|
|
void clockInterrupt() {
|
|
int clockValue = digitalRead(clockPin);
|
|
if (clockValue == LOW && test == 0 && counter < numbits) {
|
|
test = 1;
|
|
data = data >> 1;
|
|
if (digitalRead(dataPin) == HIGH) {
|
|
bitSet(data, 7);
|
|
}
|
|
counter++;
|
|
}
|
|
if (clockValue == HIGH && test == 1) {
|
|
test = 0;
|
|
}
|
|
}
|
|
|
|
void setup() {
|
|
setupKeyMapping();
|
|
|
|
pinMode(dataPin, INPUT);
|
|
pinMode(clockPin, INPUT_PULLUP);
|
|
|
|
Serial.begin(9600);
|
|
|
|
Keyboard.begin();
|
|
clearPressedKeys();
|
|
|
|
attachInterrupt(digitalPinToInterrupt(clockPin), clockInterrupt, CHANGE);
|
|
}
|
|
|
|
void loop() {
|
|
if(counter >= numbits) {
|
|
processKbdByte(data);
|
|
if (modKeySounds) tone(speakerPin, 60 + int(data), 25);
|
|
data = B0;
|
|
counter = 0;
|
|
repeatTimeout = millis() + repeatTimeoutValue;
|
|
}
|
|
if (modStuckKeyGuard && keysPressed > 0) {
|
|
unsigned long timeNow = millis();
|
|
if (repeatTimeout < timeNow) {
|
|
if (modConsoleLog) Serial.println("Stuck key detected!");
|
|
clearPressedKeys();
|
|
}
|
|
}
|
|
if (modModSwitcher && pressed[modSwitcherKey]) {
|
|
int fired = 0;
|
|
if (pressed[modConsoleLogKey]) {
|
|
modConsoleLog = !modConsoleLog;
|
|
fired = 1;
|
|
}
|
|
if (pressed[modKeySoundsKey]) {
|
|
modKeySounds = !modKeySounds;
|
|
fired = 2;
|
|
}
|
|
if (fired > 0) {
|
|
tone(speakerPin, 400 + fired * 20, 300);
|
|
Serial.print("Metakey fired: "); Serial.println(fired);
|
|
clearPressedKeys();
|
|
delay(300);
|
|
}
|
|
}
|
|
}
|