diff --git a/XtKeyboard.ino b/XtKeyboard.ino index 9e7ea18..758524f 100644 --- a/XtKeyboard.ino +++ b/XtKeyboard.ino @@ -5,21 +5,36 @@ int clockPin = 2; int dataPin = 3; -byte data = B0; +volatile byte data = B0; int test = 0; -int counter = 0; +volatile int counter = 0; int numbits = 10; int speakerPin = 5; -int keyReleaseBit = 0x80; +int keysPressed = 0; +unsigned long repeatTimeout = 0; +unsigned long repeatTimeoutValue = 1000; +const int keyReleaseBit = 0x80; char m[255]; +bool pressed[255]; -// MODS -// play speaker sounds of keys -const bool modKeySounds = true; -// replace CapsLock with Super key (aka GUI or Windows key) +// 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'; @@ -128,24 +143,62 @@ char translateKeyToChar(int key) { } void printChar(char keyChar) { - Serial.print("'"); Serial.print(keyChar); Serial.print("' ("); Serial.print(int(keyChar)); Serial.println(")"); + 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); - Serial.print("Release: "); - printChar(keyChar); + if (pressed[key]) { + pressed[key] = false; + keysPressed--; + } + if (modConsoleLog) { + Serial.print("Release: "); + printChar(keyChar); + } } else { Keyboard.press(keyChar); - Serial.print("Press: "); - printChar(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; } } @@ -153,28 +206,46 @@ void setup() { setupKeyMapping(); pinMode(dataPin, INPUT); - pinMode(clockPin, INPUT); + pinMode(clockPin, INPUT_PULLUP); + Serial.begin(9600); + Keyboard.begin(); + clearPressedKeys(); + + attachInterrupt(digitalPinToInterrupt(clockPin), clockInterrupt, CHANGE); } void loop() { - if(digitalRead(clockPin) == LOW && test == 0 && counter < numbits) { - test = 1; - data = data >> 1; - if(digitalRead(dataPin) == HIGH) { - bitSet(data, 7); - } - counter++; - } - if(digitalRead(clockPin) == HIGH && test == 1) { - test = 0; - } if(counter >= numbits) { - //Serial.println(int(data)); 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); + } } }