Arduino Leonardo (Atmel Mega32U4) adapter for an XT keyboard to be used as a USB keyboard.
25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.

252 satır
5.5 KiB

  1. // XtKeyboard source: https://forum.arduino.cc/index.php?topic=18396.0
  2. // XT protocol: https://www.win.tue.nl/~aeb/linux/kbd/scancodes-1.html
  3. #include <Keyboard.h>
  4. int clockPin = 2;
  5. int dataPin = 3;
  6. volatile byte data = B0;
  7. int test = 0;
  8. volatile int counter = 0;
  9. int numbits = 10;
  10. int speakerPin = 5;
  11. int keysPressed = 0;
  12. unsigned long repeatTimeout = 0;
  13. unsigned long repeatTimeoutValue = 1000;
  14. const int keyReleaseBit = 0x80;
  15. char m[255];
  16. bool pressed[255];
  17. // MODS >>>
  18. // [1] send debug scancode information to serial port
  19. bool modConsoleLog = true;
  20. const int modConsoleLogKey = 59; // F1
  21. // [2] play speaker sounds of keys
  22. bool modKeySounds = false;
  23. const int modKeySoundsKey = 60; // F2
  24. // [3] replace CapsLock with Super key (aka GUI or Windows key)
  25. const bool modSuperCapslock = true;
  26. // [4] stuck key guard: release all the pressed keys if no data comes from the keyboard in a while
  27. bool modStuckKeyGuard = false;
  28. // [13] mod switcher: enable changing of active mods!
  29. const bool modModSwitcher = true;
  30. const int modSwitcherKey = 55; // PRTSC *
  31. // <<< MODS
  32. // https://www.arduino.cc/en/Reference/KeyboardModifiers
  33. void setupKeyMapping() {
  34. m[1]=KEY_ESC;
  35. m[2]='1';
  36. m[3]='2';
  37. m[4]='3';
  38. m[5]='4';
  39. m[6]='5';
  40. m[7]='6';
  41. m[8]='7';
  42. m[9]='8';
  43. m[10]='9';
  44. m[11]='0';
  45. m[12]='-';
  46. m[13]='=';
  47. m[14]=KEY_BACKSPACE;
  48. m[15]=KEY_TAB;
  49. m[16]='q';
  50. m[17]='w';
  51. m[18]='e';
  52. m[19]='r';
  53. m[20]='t';
  54. m[21]='y';
  55. m[22]='u';
  56. m[23]='i';
  57. m[24]='o';
  58. m[25]='p';
  59. m[26]='[';
  60. m[27]=']';
  61. m[28]=KEY_RETURN;
  62. m[29]=KEY_LEFT_CTRL;
  63. m[30]='a';
  64. m[31]='s';
  65. m[32]='d';
  66. m[33]='f';
  67. m[34]='g';
  68. m[35]='h';
  69. m[36]='j';
  70. m[37]='k';
  71. m[38]='l';
  72. m[39]=';';
  73. m[40]='\'';
  74. m[41]='`';
  75. m[42]=KEY_LEFT_SHIFT;
  76. m[43]='\\';
  77. m[44]='z';
  78. m[45]='x';
  79. m[46]='c';
  80. m[47]='v';
  81. m[48]='b';
  82. m[49]='n';
  83. m[50]='m';
  84. m[51]=',';
  85. m[52]='.';
  86. m[53]='/';
  87. m[54]=KEY_RIGHT_SHIFT;
  88. m[55]='\335'; // num-*
  89. m[56]=KEY_LEFT_ALT;
  90. m[57]=' ';
  91. m[58]=(modSuperCapslock ? KEY_LEFT_GUI : KEY_CAPS_LOCK); // EVIL
  92. m[59]=KEY_F1;
  93. m[60]=KEY_F2;
  94. m[61]=KEY_F3;
  95. m[62]=KEY_F4;
  96. m[63]=KEY_F5;
  97. m[64]=KEY_F6;
  98. m[65]=KEY_F7;
  99. m[66]=KEY_F8;
  100. m[67]=KEY_F9;
  101. m[68]=KEY_F10;
  102. // https://forum.arduino.cc/index.php?topic=266688.msg1880644#msg1880644
  103. // http://www.quadibloc.com/comp/scan.htm
  104. const byte KEY_NUM_LOCK = 219;
  105. m[69]=KEY_NUM_LOCK;
  106. const byte KEY_SCROLL_LOCK = 207;
  107. m[70]=KEY_SCROLL_LOCK;
  108. m[71]='\347'; // num-7
  109. m[72]='\350'; // num-8
  110. m[73]='\351'; // num-9
  111. m[74]='\336'; // num--
  112. m[75]='\344'; // num-4
  113. m[76]='\345'; // num-5
  114. m[77]='\346'; // num-6
  115. m[78]='\337'; // num-+
  116. m[79]='\341'; // num-1
  117. m[80]='\342'; // num-2
  118. m[81]='\343'; // num-3
  119. m[82]='\352'; // num-0
  120. m[83]='\353'; // num-.
  121. //...
  122. m[101]=KEY_F11;
  123. m[102]=KEY_F12;
  124. m[107]=KEY_INSERT;
  125. m[108]=KEY_DELETE;
  126. m[109]=KEY_UP_ARROW;
  127. m[110]=KEY_DOWN_ARROW;
  128. m[111]=KEY_LEFT_ARROW;
  129. m[112]=KEY_RIGHT_ARROW;
  130. //m[]=KEY_;
  131. }
  132. char translateKeyToChar(int key) {
  133. if (sizeof(m) <= key) {
  134. return 0;
  135. }
  136. return m[key];
  137. }
  138. void printChar(char keyChar) {
  139. Serial.print("'"); Serial.print(keyChar); Serial.print("' ("); Serial.print(int(keyChar)); Serial.print("), Pressed keys: ["); Serial.print(keysPressed); Serial.println("]");
  140. }
  141. void processKbdByte(byte data) {
  142. bool isRelease = data & keyReleaseBit;
  143. int key = data - (isRelease ? keyReleaseBit : 0);
  144. if (modConsoleLog) {
  145. Serial.print("Scancode: <"); Serial.print(int(data)); Serial.print("> ");
  146. Serial.print("Key: <"); Serial.print(int(key)); Serial.print("> ");
  147. }
  148. char keyChar = translateKeyToChar(key);
  149. if (isRelease) {
  150. Keyboard.release(keyChar);
  151. if (pressed[key]) {
  152. pressed[key] = false;
  153. keysPressed--;
  154. }
  155. if (modConsoleLog) {
  156. Serial.print("Release: ");
  157. printChar(keyChar);
  158. }
  159. } else {
  160. Keyboard.press(keyChar);
  161. if (!pressed[key]) {
  162. pressed[key] = true;
  163. keysPressed++;
  164. }
  165. if (modConsoleLog) {
  166. Serial.print("Press: ");
  167. printChar(keyChar);
  168. }
  169. }
  170. }
  171. void clearPressedKeys() {
  172. Keyboard.releaseAll();
  173. keysPressed = 0;
  174. for (int i = 0; i < sizeof(pressed); i++) {
  175. pressed[i] = false;
  176. }
  177. Serial.println("Pressed keys list cleared.");
  178. }
  179. void clockInterrupt() {
  180. int clockValue = digitalRead(clockPin);
  181. if (clockValue == LOW && test == 0 && counter < numbits) {
  182. test = 1;
  183. data = data >> 1;
  184. if (digitalRead(dataPin) == HIGH) {
  185. bitSet(data, 7);
  186. }
  187. counter++;
  188. }
  189. if (clockValue == HIGH && test == 1) {
  190. test = 0;
  191. }
  192. }
  193. void setup() {
  194. setupKeyMapping();
  195. pinMode(dataPin, INPUT);
  196. pinMode(clockPin, INPUT_PULLUP);
  197. Serial.begin(9600);
  198. Keyboard.begin();
  199. clearPressedKeys();
  200. attachInterrupt(digitalPinToInterrupt(clockPin), clockInterrupt, CHANGE);
  201. }
  202. void loop() {
  203. if(counter >= numbits) {
  204. processKbdByte(data);
  205. if (modKeySounds) tone(speakerPin, 60 + int(data), 25);
  206. data = B0;
  207. counter = 0;
  208. repeatTimeout = millis() + repeatTimeoutValue;
  209. }
  210. if (modStuckKeyGuard && keysPressed > 0) {
  211. unsigned long timeNow = millis();
  212. if (repeatTimeout < timeNow) {
  213. if (modConsoleLog) Serial.println("Stuck key detected!");
  214. clearPressedKeys();
  215. }
  216. }
  217. if (modModSwitcher && pressed[modSwitcherKey]) {
  218. int fired = 0;
  219. if (pressed[modConsoleLogKey]) {
  220. modConsoleLog = !modConsoleLog;
  221. fired = 1;
  222. }
  223. if (pressed[modKeySoundsKey]) {
  224. modKeySounds = !modKeySounds;
  225. fired = 2;
  226. }
  227. if (fired > 0) {
  228. tone(speakerPin, 400 + fired * 20, 300);
  229. Serial.print("Metakey fired: "); Serial.println(fired);
  230. clearPressedKeys();
  231. delay(300);
  232. }
  233. }
  234. }