这是一个能够记录PS2键盘发出的按键信息的演示装置。
使用的元件:
Arduino UNO 一块
PS2 延长线(一端公头,一端母头) 一根
测试钩 三根
首先要将PS2延长线剥开,其中有四根线,分别是 Vcc/GND/Clock/Data。我们只需要钩取其中除了Vcc之外的三根线。
特别说一下这几根线的分布,在公头端和母头端看过去的Pin编号是对称的,如下图所示(网上有人说一些资料搞错了,我看了一下,是他本人搞错了公母而已)。选好线之后务必使用万用表确定接线无误。
连接方面,上面图片中白色测试钩钩取的是黄色线 GND;绿色测试钩钩取的是红色Data;白色测试钩钩取的是白色线 Clock。
PS2 头和线色对应关系如下图:
程序调用了PS2Keyboard library 【参考1】,用它来做PS2 协议的解码。调用的方式就是keyboard.begin(DataPin, IRQpin); DataPin 要给出Arduino上连接到 PS2 Data的Pin脚;IRQpin 要给出Arduino上连接到 PS2 Clock的Pin脚。本例中,分别是 Pin8 和 Pin2。
开始运行后, Setup()中会在串口输出一个菜单,提示如果输入 P ,那么会直接打印出 Arduino板载 EEPROM中的内容(UNO 的EEPROM不大,只有1K【参考2】。前面2个Byte用来存放一个记录当前要写入的位置。其余位置用来存储记录的键值。如果超过1K,那么返回开始处重新覆盖)。如果5秒之内没有输入 P ,那么程序会运行loop() 中的代码。先使用PS2Keyboard library 进行解码,然后每次都要从EEPROM中取出前2个Bytes组成一个指针,指示要将这个键值要存放在EEPROM中的位置。
#include "PS2Keyboard.h" #include <EEPROM.h> const int DataPin = 8; const int IRQpin = 2; const int MaxLength = 1024; PS2Keyboard keyboard; int SaveTo; void setup() { boolean TimeOutMark=true; keyboard.begin(DataPin, IRQpin); Serial.begin(9600); Serial.write("Keyboard Logger for Arduino\n"); Serial.write("www.lab-z.com 2014.5\n"); Serial.write(" p - for output record \n"); unsigned long _time = millis(); //用于超时 while ((millis() - _time) < 5000) { char inChar = Serial.read(); if ((inChar == 'p') || (inChar == 'P')) { TimeOutMark=false; for (int i=2; i<MaxLength; i++) { char c = EEPROM.read(i) ; // check for some of the special keys if (c == PS2_ENTER) { Serial.println(); } else if (c == PS2_TAB) { Serial.print("[Tab]"); } else if (c == PS2_ESC) { Serial.print("[ESC]"); } else if (c == PS2_PAGEDOWN) { Serial.print("[PgDn]"); } else if (c == PS2_PAGEUP) { Serial.print("[PgUp]"); } else if (c == PS2_LEFTARROW) { Serial.print("[Left]"); } else if (c == PS2_RIGHTARROW) { Serial.print("[Right]"); } else if (c == PS2_UPARROW) { Serial.print("[Up]"); } else if (c == PS2_DOWNARROW) { Serial.print("[Down]"); } else if (c == PS2_DELETE) { Serial.print("[Del]"); } else { // otherwise, just print all normal characters Serial.print(c); } // End of else }//End of for } //End of if ((inChar = 'p') || (inChar = 'P')) }// End of While if (TimeOutMark==true) {Serial.write("Timeout occured!\n"); } else {Serial.write('\n Output End!');} EEPROM.write(0,2); EEPROM.write(1,0); } // End of Setup void loop() { char c; if (keyboard.available()) { // read the next key c = keyboard.read(); Serial.print(c); SaveTo = EEPROM.read(0) + (EEPROM.read(1) <<8); EEPROM.write(SaveTo,c); SaveTo++; if (SaveTo>MaxLength) {SaveTo=2;} EEPROM.write(0,SaveTo); EEPROM.write(1,(SaveTo >> 8)); } }
实验中使用的是一个USB键盘,通过USB转PS2转为电脑上能使用的PS2 (资料上说现在的USB键盘内置2种协议,根据当前插入的接口自动选择输出的协议)。该键盘通过上面提到的PS2延长线接入电脑。记录结果如下:
因为尺寸的原因,可以看出来这个东西只有演示的价值,如果真想做一个实用性的东西,还要选择PIC系列的小尺寸单片机加上SPI ROM………
下载
KeyLog
参考:
1.http://playground.arduino.cc/Main/PS2Keyboard
2.Arduino上的单片机自带EEPROM 328P 有 1024字节
http://wiki.geek-workshop.com/doku.php?do=export_xhtml&id=arduino:libraries:eeprom。