// 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 int clockPin = 2; int dataPin = 3; byte data = B0; int test = 0; int counter = 0; int numbits = 10; int speakerPin = 5; int keyReleaseBit = 0x80; char m[255]; // MODS // play speaker sounds of keys const bool modKeySounds = true; // replace CapsLock with Super key (aka GUI or Windows key) const bool modSuperCapslock = true; 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.println(")"); } void processKbdByte(byte data) { bool isRelease = data & keyReleaseBit; int key = data - (isRelease ? keyReleaseBit : 0); 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); } else { Keyboard.press(keyChar); Serial.print("Press: "); printChar(keyChar); } } void setup() { setupKeyMapping(); pinMode(dataPin, INPUT); pinMode(clockPin, INPUT); Serial.begin(9600); Keyboard.begin(); } 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; } }