Arduino PS / 2键盘模拟器问题


10

是的,我已经搜索了Arduino.cc论坛和此处。是的,我找到了有关ps2dev库的文章。是的,我已经在该网站上阅读了(好的,我略读了一些)权威的PS / 2接口文章。是的,我有这个工作。我需要一些想法来实现全面工作的飞跃。:)

不,我不能只是仿真USB HID键盘而已-它需要是PS / 2键盘仿真。是的,我正在发送适当的接通和断开信号-它甚至可以处理非常复杂的按键组合。就目前而言,我已经为我的Arduino编写了如下代码(技术上是Freeduino 1.22),并且我已经通过Serial Monitor或PuTTY终端发送了击键,并且使用了方便的Python包装器/驱动器来发送实际的PS / 2扫描码信息-通常会使我的生活变得更轻松-也减轻了Arduino的负担。

现在,我在Arduino上运行了一个模拟PS / 2键盘的草图。自然,我必须启动“目标”计算机(PS / 2 Plug进入的计算机),然后看到“握手”发生。引导至WinDoze,打开记事本,然后使用我的Python“驱动程序”将键击成功驱动到屏幕。(驱动程序只是代替了Serial Monitor / PuTTY终端,并使用称为PySerial的模块读取/写入串行端口。)所有这些操作均在ASUS主板“目标”中的AMD上完成。

现在,目标是使其在基于英特尔母板的“目标”上的英特尔处理器上运行,我将其插入,启动并且没有骰子。因此,我对草图进行了一些修改,以尝试使自己了解我的小阿迪朋友的实际情况。mods之后的版本如下所示。据我了解(代码是从另一个Arduino.cc论坛帖子“借来的”,此处)它将首先尝试通过PS / 2与“目标”建立连接,并在.5秒内闪烁板载LED,直到建立连接。Intel目标不会超过.5秒闪烁,并且永远不会与“主机”建立串行连接。

我的问题是:ps / 2键盘与目标计算机建立通信的方式是否有重大不同?这真的是设计上的区别吗?还是我应该在这里寻找更基本的东西?我听说过一些关于在数据/时钟输入上需要上拉电阻的信息,但这应该在代码中处理,特别是因为它在另一个目标上工作,而不是我需要它工作的目标。

有任何想法吗?我很想尽快使该工作正常进行-我将继续进行调试,任何指针或建议将不胜感激。他们将得到充分考虑,因为我需要在这个问题上有新的眼光。也许需要在ps2dev库中更好地实现?

#include "ps2dev.h" // to emulate a PS/2 device

// Orange = 2
// Blue = 3
// Red = 5V (3 in)
// Black = GND (4 in)
// EXT Power, USB for COM only

PS2dev keyboard(3,2); // PS2dev object (2:data, 3:clock)
int enabled = 0; // pseudo variable for state of "keyboard"
boolean serialConnected = false;
int incomingByte = 0;

void ack() {
  //acknowledge commands
  while(keyboard.write(0xFA));
}

int kbdCmd(int command) {
  unsigned char val;
  switch (command) {
  case 0xFF: //reset
    ack();
    //the while loop lets us wait for the host to be ready
    while(keyboard.write(0xAA)!=0);
    break;
  case 0xFE: //resend
    ack();
    break;
  case 0xF6: //set defaults
    //enter stream mode
    ack();
    break;
  case 0xF5: //disable data reporting
    //FM
    enabled = 0;
    ack();
    break;
  case 0xF4: //enable data reporting
    //FM
    enabled = 1;
    ack();
    break;
  case 0xF3: //set typematic rate
    ack();
    keyboard.read(&val); //do nothing with the rate
    ack();
    break;
  case 0xF2: //get device id
    ack();
    keyboard.write(0xAB);
    keyboard.write(0x83);
    break;
  case 0xF0: //set scan code set
    ack();
    keyboard.read(&val); //do nothing with the rate
    ack();
    break;
  case 0xEE: //echo
    //ack();
    keyboard.write(0xEE);
    break;
  case 0xED: //set/reset LEDs
    ack();
    keyboard.read(&val); //do nothing with the rate
    ack();
    break;
  }
}

void connectHost() {
  while (Serial.available() <= 0) {
    Serial.print('A');   // send a capital A
    delay(300);
  }
}

void setup() {
  pinMode(13, OUTPUT);
  //establish serial connection with host
  Serial.begin(9600);
  // establish ps/2 connection with target
  while(keyboard.write(0xAA)!=0){
    digitalWrite(13, HIGH);
    delay(500); 
    digitalWrite(13, LOW);
    delay(500);
  }
  delay(100);  
  
  connectHost();
  Serial.println("\nSerial Host Connected");
  Serial.flush();
}

void loop() {
  unsigned char c;
  if( (digitalRead(3)==LOW) || (digitalRead(2) == LOW)) {
    if(digitalRead(3)==LOW){
      Serial.println("pin 3  is LOW");
    } else {
      Serial.println("pin 2 is LOW");
    }
    while(keyboard.read(&c));
    kbdCmd(c);
    Serial.print("Target: 0x");
    Serial.println(c, HEX);
  }  
  else {//if host device wants to send a command:
    //echo ASCII code from terminal and write to ps/2
    if(Serial.available() > 0) {
      incomingByte = Serial.read();
      keyboard.write(incomingByte);      
      Serial.print("Host: 0x");
      Serial.print(incomingByte, HEX);
      Serial.print(" ");
      Serial.print(incomingByte);
      Serial.print(" ");
      Serial.println(incomingByte, BIN);
    }
  }
}

一些问题:“ Sketch”是Arduino语言的“程序”吗?这些python驱动程序的东西独立于目标计算机,对吗?您的问题是它可以在一台目标计算机上运行,​​而不能在另一台目标计算机上运行,​​对吗?您是否尝试使用连接的PS / 2键盘启动无法工作的目标,然后将其与Arduino互换?
2011年

是的,Ardu-lingo中的Sketch ==程序。我尝试了一下,但它似乎没有用(但是我需要修改草图,以便它在发送字符之前不必等待目标的ACK。)当我有机会对其进行测试时,我会通知您。今天晚些时候。
chisaipete

因此,我按照您的建议测试了该程序,它可以正常工作!最后,我希望能够在安装了键盘模拟器的情况下关闭并重新启动目标,并能够更改其BIOS设置。所以,我在想启动握手已经结束了吗?
chisaipete11年

应该是。您是否在computer-engineering.org/ps2keyboard的最底部看到了初始化顺序?我将从比较我的顺序开始。
2011年

1
抱歉,我让这个话题变得过时了-我还没有时间尝试AndreKR的解决方案。此外,我没有使用上拉电阻,因此很难确定哪一端没有上拉电阻:)
chisaipete

Answers:


5

据我了解,您将Arduino连接到两台不同的目标机器,其中一台可以工作,而另一台则不行。

因此,似乎两台计算机的初始化要求之间存在差异。在此页面的最底部,列出了可能的初始化序列。首先将您的初始化与该初始化进行比较。

使用逻辑分析仪会容易得多。我正在使用Intronix Logicport,但是有便宜和更好的两者,尽管不是同时使用的。

接入开放式集电极总线有点麻烦,因为您看不到哪个设备在讲话。但是,如果在没有上拉电阻的一端插入一个串联电阻,则可以通过电压电平来确定哪个器件使总线保持低电平。每个集电极开路总线(如PS / 2)都需要上拉电阻,通常它们内置在PC中。您可以在DSO上轻松看到不同的电压电平。仅使用LA,您必须使用不同的阈值电压记录两次。


比我预期的要难得多,是由谁来决定是否提供悬赏,但是您的回答获得了最多的选票,我稍微偏爱。我希望每个人都得到奖励!
Kortuk 2011年

3

考虑到您的项目可以使用一个母板而不是另一个母板,您似乎在项目中甚至在其中一个母板中都有“部分规格合规”的经典案例。但是大多数键盘都可以在任何主板上使用,因此可靠的实现应该是可移植的。挑战在于您将不得不弄清楚为什么不是。

您可以通过盯着问题并思考问题的工作方式(也许是休息一下或一天后答案就可以解决问题)来做到这一点,但是如果您能够进行监控,您将更加有效到底是怎么回事。对于意味着问题的电气问题,对于协议,则是逻辑分析仪。该区域有一些廉价的选择,例如,“ bus pirate”板具有某些针对键盘协议的特定功能,或者是基于FPGA的板,可以具有更长的捕获缓冲区(请参见sump.org)。

您可以尝试的另一件事是使用另一种设备(微控制器或FPGA)来构建键盘主机,并使用该主机来测试您的项目,以达到规范的极限。


2

我没有看过ps2dev库来确切地了解它是如何工作的,但是有一件事确实跳了我一眼。

目前仅尝试连接到“主机”计算机。如果失败,将等待一整秒(LED点亮0.5s,LED熄灭0.5s),然后再尝试一次。

如果英特尔主板没有等待足够长的时间来检测键盘,那么它可能永远无法获得连接尝试,然后再继续启动顺序。

如果将等待时间减少为0.1s(将delay(500)行更改为delay(50)),可能会有些运气。

如果没有,请尝试更快。地狱,甚至可以毫不拖延地尝试一下,看看效果如何。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.