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