|
- // 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);
- }
- }
- }
|