Ja, ich habe die Arduino.cc-Foren und hier durchsucht. Ja, ich habe die Artikel zur ps2dev-Bibliothek gefunden. Ja, ich habe den endgültigen Artikel zur PS / 2-Benutzeroberfläche auf dieser Website gelesen (okay, einige habe ich überflogen) . Ja, das funktioniert irgendwie. Ich brauche einige Ideen, um den Sprung zum vollen Funktionieren zu schaffen. :) :)
Nein, ich kann nicht einfach eine USB HID-Tastatur emulieren und dabei belassen - es muss sich um eine PS / 2-Tastaturemulation handeln. Ja, ich sende die richtigen Make- und Break-Signale - es werden sogar sehr komplizierte Tastenkombinationen verarbeitet. So wie es jetzt aussieht, habe ich Code für mein Arduino geschrieben, wie unten angegeben (technisch ein Freeduino 1.22), und ich habe Tastenanschläge über den seriellen Monitor oder das PuTTY-Terminal sowie mit einem handlichen Python-Wrapper / -Treiber gesendet, der tatsächlich sendet PS / 2-Scancode-Informationen - und erleichtern mir im Allgemeinen das Leben - entlasten auch den Arduino.
Im Moment läuft auf dem Arduino eine Skizze, die eine PS / 2-Tastatur emuliert. Natürlich muss ich meinen "Ziel" -Maschinen booten (Computer, in den der PS / 2-Stecker eingeht), und ich sehe, dass der "Handshake" stattfindet. Booten Sie zu WinDoze, öffnen Sie den Editor und fahren Sie mit meinem Python-Treiber (erfolgreich) Tastenanschläge auf den Bildschirm. (Der Treiber ersetzt einfach das Serial Monitor / PuTTY-Terminal und liest / schreibt mit einem Modul namens PySerial auf die serielle Schnittstelle.) Dies erfolgt alles auf einem AMD im ASUS-Motherboard "target".
Jetzt ist das Ziel, es auf meinem Intel in Intel Motherboard-basierten "Ziel" zum Laufen zu bringen, ich stecke es ein, starte und ohne Würfel. Also habe ich die Skizze ein wenig modifiziert, um mir ein Bild davon zu machen, was tatsächlich mit meinem kleinen Ardy-Freund los ist. Die Version nach den Mods wird unten angezeigt. Wie ich es verstehe (Code „ausgeliehen“ von einem anderen Arduino.cc Forumsbeitrag wurde, hier ) Es wird versuchen, eine Verbindung mit dem „Ziel“ über PS / 2 zunächst zu etablieren, in einer 0,5 Sekunden Zeit , das Onboard - LED blinkt , bis die Verbindung wird hergestellt. Das Intel-Ziel überschreitet nicht die Blinkzeit von 0,5 Sekunden und die serielle Verbindung wird niemals mit dem "Host" hergestellt.
Meine Frage lautet: Gibt es einen großen Unterschied in der Art und Weise, wie ps / 2-Tastaturen die Kommunikation mit ihrem Zielcomputer herstellen? Ist es wirklich ein Designunterschied oder sollte ich nach etwas Grundlegenderem suchen, um das es hier geht? Ich habe etwas über die Notwendigkeit von Pull-up-Widerständen an den Daten- / Takteingängen gehört, aber das sollte im Code behandelt werden, insbesondere weil es auf einem anderen Ziel funktioniert, nur nicht auf dem, an dem ich arbeiten muss.
Irgendwelche Ideen? Ich würde es lieben, wenn dies so schnell wie möglich funktioniert - ich werde weiterhin debuggen, alle Hinweise oder Vorschläge wären sehr dankbar. Sie werden alle umfassend berücksichtigt, da ich neue Augen für dieses Thema brauche. Vielleicht ist eine bessere Implementierung in der ps2dev-Bibliothek erforderlich?
#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);
}
}
}