PS2 Keyboard Emulator

I'd like to use an Arduino Duemilanove as a PS2 keyboard emulator, that I can plug into a laptop. I would need to know the electrical connections, although I could gut an old PS2 keyboard as a starting point and maybe drive its internal electronics. I assume that would require generating some kind of matrix of input values, in place of the physical keyboard.

Any advice or pointers will be gratefully received.

Regards to all,
Mark
Ottawa, Ontario, Canada

Start with the links in the "Further readings" section of Arduino Playground - PS2Keyboard. You will find the protocols, scan codes, and everything you need to send out of the Arduino to the laptop, if you follow those links through about one or two levels deep.

Hello!
We are discussing here about how to send characters (and other data) into a laptop's PS2 keyboard (& mouse) input port?

The referenced page discusses the wonders of having the Arduino communicate with a keyboard.

/me

Time is like sleep, it goes faster when you're not using it.

We are discussing here about how to send characters (and other data) into a laptop's PS2 keyboard (& mouse) input port?

Yes, the original question asked for help sending keyboard info from the Arduino to a laptop. The referenced page has a section titled "Further readings" near the bottom of the page. If you follow the links in that "Further readings" section, you will find details of the PS2 keyboard communication protocols and electrical interfaces.

(Sorry, I almost didn't read your post because of the distracting scrolling line in your signature.)

Thanks TBAr that's very helpful although, to be clear, yes I am trying to emulate a keyboard, not interface with it, so it looks like I have work to do.

Main question I have next is with clock rates. The reading I have done mentioned 20 to 30 kHz, so I'm wondering how critical that is. If I drive the clock and data much slower will it still work, I wonder. I assume the clock pin mentioned in the Playground write-up is generated by the library code and not a built-in hardware feature?

I could try to reverse engineer the keyboard interface code, but I think I will start very simply from first principles. The references you pointed me to are very helpful. Thanks again.

BTW I'm a complete Arduino newbie. It's great fun!

Regards,
Mark
Ottawa, Ontario, Canada

Ok I have uploaded to the playground a library that implements the device side of the ps/2 protocol. I used it in a couple projects, including a sun type 5 to ps/2 interface. Also the ps/2 port on the computer can provide plenty of power to drive the arduino

Thanks for the contribution!

That library would be at the bottom of this page.

Thanks for doing the link

Ok I have uploaded to the playground a library that implements the device side of the ps/2 protocol. I used it in a couple projects, including a sun type 5 to ps/2 interface. Also the ps/2 port on the computer can provide plenty of power to drive the arduino

Very interesting! I have also made such a library, and it's quite similar to yours. However, I've had some timing-issues, especially when I try to emulate both a mouse and a keyboard at the same time. Have you tried this with your library? I will definitely look into this later today, as it might solve some problems I've been struggling with for weeks.

Well, your library wasn't really suited for my application (my library have read- and write-buffers, and I would need to change a lot of things to manage without them) so I just replaced my own ps2read/write-routines with yours (very slightly modified). So far it's looking good :slight_smile: I'm going to test it further, and if your code did the trick you deserve a big THANK YOU :slight_smile: I've struggled with the timing for almost two months now...

Very interesting! I have also made such a library, and it's quite similar to yours. However, I've had some timing-issues, especially when I try to emulate both a mouse and a keyboard at the same time. Have you tried this with your library? I will definitely look into this later today, as it might solve some problems I've been struggling with for weeks.

I have used it as a mouse and a keyboard but never both at once

Does anyone have a working implementation of any arduino PS/2 keyboard emulator library? I can't seem to get the ps2dev one to work. QQ

Also looking for a way to cut my pc's ps2 keyboard and plug an arduino there...
Couldnt make the ps2dev.h to work.
Couldnt find ps2dev.h references or something that I could read to build my own application.
Actually Im kind of stuck...sorry.

Any help?
A simple sample to compile within arduino which will make it send a letter 'A' to PC for each second would be a nice start.

:wink:
Btp~

I second that :slight_smile:

A basic overview of what's needed (hardware and software) wise would be great.

It seems an Arduino acting as a keyboard via PS/2 is easier (hardware and software wise) than doing it via USB.

It seems an Arduino acting as a keyboard via PS/2 is easier (hardware and software wise) than doing it via USB

To sum up in a pair of words... "MUCH easier."

The USB method requires you to essentially BIT-BANG the USB HID Emulation on the Arduino. While some Micro controllers are now built with USB HID support... the ones we use do not. A lot of people have used the software solution provided here --> V-USB - A Firmware-Only USB Driver for Atmel AVR Microcontrollers to build USB devices with AVR chips. (So it can be done)

The PS2 protocol is a simple synchronous serial connection and we already have the library code in the playground.

Yes, I thought as much :slight_smile:

Hardware wise, can I basically hook the port straight up to the arduino? Do I need to do something smarter? Finding lots of stuff about hooking up a keyboard to an arduino, but not the reverse....

ive given up on the usb hid , as it wont compile.

so ive gone down the ps/2 route.

Ive also considered using serial , i only want to run the exe and dont want to install software or .net framework.

Just wondering if anyone has been able to act as a ps/2 keyboard yet ?

If so can you post your code that would be a big help.

cheer
luke

My example of using ps2dev as a keyboard:

edit 'ps2dev.h'

comment out #include "WConstants.h"
and add a line #include <Wprogram.h>
...
//#include "WConstants.h"
#include <Wprogram.h>
...

here is code:
I used royboy's code siliconrepublic.blogspot.com

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

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

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

int keyboardcommand(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 setup() {
  // send the keyboard start up
  while(keyboard.write(0xAA)!=0);
  delay(10);
}

void loop() {
  unsigned char c;
  //if host device wants to send a command:
  if( (digitalRead(3)==LOW) || (digitalRead(2) == LOW)) {
    while(keyboard.read(&c)) ;
    keyboardcommand(c);
  }
  else{ //send keypresses accordingly using scancodes
  // secancodes: http://www.computer-engineering.org/ps2keyboard/scancodes2.html
  keyboard.write(0x1C); // \
  keyboard.write(0xF0); //  |- send 'a'
  keyboard.write(0x1C); // /
  delay (1000); // wait 1 second
  }
}