How To Connect a PS/2 Keyboard to the iPhone

by awgh on October 13, 2009 · 44 comments

in Fun, Hardware Hacks, iPhone

Although I’ve seen many pictures of PS/2 keyboards plugged into iPhones on the Internet, no one has yet published a detailed howto on how to get this working yourself.  Until now, that is.

In this article I will show you how you can make a PS/2 keyboard to iPhone converter, including all hardware and software instructions. As the bugs get worked out, or improvements are made, I’ll update this page.

Motivation: The Great Apple-Elf Conspiracy

After using an iPhone for a couple years, I have started to believe that the developers of the iPhone actually hate those of us with broad, round thumbs.  I can’t make very efficient use of the virtual keyboard, even in landscape, and they refuse to add real support for Bluetooth or really any external keyboards.  I have a friend with pointy little thumbs who can type like 36 wpm on the thing.  I’ve also noticed that of all the Apple employees I’ve actually met, they all seem to be relatively nimble and elf-like, with pointy little thumbs.  Coincidence?

My thumbs are round, which is apparently an afront to Steve Jobs and his nimble elven-fingered lackies.

My thumbs are round, which is apparently an afront to Steve Jobs and his nimble elven-fingered lackies.

Perhaps if Apple employed more broad-thumbed people, they wouldn’t be so stubborn about actively disallowing using external keyboards on the iPhone.

If you are wondering why someone would want to be typing quickly into an iPhone, I can say with great certainty that you are on the wrong web site. Unless you got here by searching for “Elf Conspiracy”, then you should email me.  Please include a picture of your thumbs for verification.

Prerequisites

  • Jailbroken iPhone – The official SDK doesn’t allow access to the serial port due to the Elf Conspiracy, so the jailbreak is required.  All you need to know about jailbreaking is at the iPhone Dev Team Blog.
  • Arduino Diecimila or Dumilanove (or clone), available from many places.  This howto assumes that your Arduino is assembled.
  • An iPod Breakout board, like this one from Sparkfun.  Any similar product will work.
  • A Female PS/2 (Din 6) Keyboard connector.  Pull one off an old computer or buy one from Digikey or similar vendor.
  • Wire, preferably several colors and about 24 gauge.  I’m using a spool from RadioShack in the pics below.
  • One 500k Resistor.  I’m using an axial through-hole resistor from RadioShack, but you could add this to your Digikey order as well.
  • Soldering Iron and Solder.  If you don’t know how to solder, you can learn here and here.
  • (Optional) Pin Headers, like these.  I break these off and solder them to the ends of wires, so that they plug nicely into the Arduino.
  • (Optional) Sweet 9v Battery harness so your Arduino becomes portable available from the Maker Store.
  • (Optional) Stereo Headphone Jack from RadioShack or Digikey.

Wiring Things Up

Once all your ingredients arrive, fire up the soldering iron and have a quick look at the iPod Connector Pin-Out.

We’ll be making use of four of these pins for the keyboard: 11, 13, 16 and 21.  The definition of pin 21 says we need to place a 500k resistor between pin 21 and ground to enable serial communications to the iPhone, so we’re going to stick a resistor between pin 21 and pin 16, which is the serial ground.  We’re also going to be adding pin headers to pins 11 and 13, which will act as the TX and RX pins for serial communications.  Since we’ll ONLY be sending to the iPhone, we only make use of the iPhone’s RX pin, so we’ll also be adding a piece of wire to connect pin 11, the unused TX pin,  directly to the ground at pin 16.

You can also optionally add the stero headphone jack to pins 2, 3 and 4 right now and it will work whenever the breakout is plugged in.  This has nothing to do with the keyboard, but if you have a 1G iPhone with the lame non-standard headphone jack, this will fix it.

iPhone Breakout Wiring - Front

iPhone Breakout Wiring - Front

Here is the front of the fully wired-up breakout board.  Click on the image to have a closer look.

The backside is below.

iPhone Breakout Wiring - Back

iPhone Breakout Wiring - Back

I’ve put the jumper between pin 11 and pin 16 on the back of the breakout board.  It can be a bit tricky to fit everything on to pin 16, so I recommend first sticking the resistor through the hole, then wrapping the end of the jumper wire around it and soldering them together before clipping off the resistor lead.

Another tactic which may be useful here is to first tin the ends of your wire, then blob a little solder on the hole you want to stick the wire to.  Use the side of the soldering iron to warm your blob of solder and the SLIDE the tinned end of the wire into the blob.  Remove the iron, let blob cool, then let go of wire.

PS/2 Connector Wiring - Front

PS/2 Connector Wiring - Front

There is no path you can take through the pin numbering of the PS/2 Connector that makes any kind of sense outside the context of the deranged ramblings of a committee meeting.  Don’t think too hard about the pin numbers, just check out the picture above.

We’ll be making use of four pins here, and connecting all of them to the Arduino.  Ground will be wired to Ground on the Arduino, VCC will be wired to 5V, and the Data and Clock pins will be brought over to two of the Arduino’s digital pins (3 and 4).

PS/2 Connector Wiring - Bottom

PS/2 Connector Wiring - Bottom

The bottom of the PS/2 Connector is even less intuitive than the numbering scheme.  I recommend checking this picture, but also verifying that the pins on the bottom of your connector match the numbered pins you think they do before soldering anything.  You can check for connectivity with a regular multimeter by setting it to measure resistance and connecting one probe to the pin on the bottom and sticking the other in the hole.  If there is any resistance at all, then that pin is connected to that hole.

I’m using the Green wire for the Clock pin, the Red wire for VCC, the White wire for Data, and the Black wire for ground.

step5

Once you’ve got the connectors wired up, strip the other ends of the wires and solder the leads to pin headers.  This will let you plug them in to the Arduino easily.  If you didn’t get the pin headers, you can try carefully tinning the wires to make them stay in the Arduino pin holes better.

I attached some wires to the pin headers on pins 11 and 13 of the iPhone breakout board.  The Black wire is to Ground (pin 11) and the Red wire is to VCC (pin 13).  I’ve then soldered pin headers to the leads for the two wires from the breakout board and the four coming from the PS/2 connector.

step6

I’m using an Arduino Diecimila, since this program doesn’t require a better chip.  This is shown with a 9V battery harness from SparkFun for portability.

Attach PS/2 leads to the Arduino.

Attach PS/2 leads to the Arduino.

Next, we connect the PS/2 Connector to the Arduino.  Connect the Clock wire to Digital Pin 3, the Data wire to Digital Pin 4, and connect the Ground wire to Ground on the Arduino and the VCC wire to the 5V pin.

Attach iPhone leads to the Arduino.

Attach iPhone leads to the Arduino.

To connect the iPhone breakout, simply connect the lead from Pin 13 to the TX Pin on the Arduino (Digital Pin 1) and then connect the lead from Pin 11 to any available Ground on the Arduino.

IMPORTANT: To avoid trouble with flashing the Arduino, please disconnect the TX Pin on the Arduino before flashing.  More on this later.

Putting it all together.

Putting it all together.

After that, all the soldering is done.  Now it’s time to move on to programming the Arduino!

The Arduino Code

The Arduino software clocks data out of the keyboard, translates the keyboard scan codes to key codes, and handles presses of the shift and caps lock keys.

First off, download and install the Arduino development environment from here.  Follow the directions on the site, but be sure to install the appropriate FTDI driver from the drivers directory in the Arduino installation.

Next, you’ll need an additional Arduino library for PS/2.  Download the file “ps2.zip” from this page.  To install, unzip the download to a folder and move that folder to be a subdirectory of the “hardware/libraries” directory under your Arduino installation.  On OSX, you can go to Arduino.app and “Show Package Contents” first.

Once Arduino and the ps2 library are installed, download the source code from here.  Open the Arduino application, create a new project, and paste the source code into it.  Save, and then go to Sketch->Verify/Compile to make sure that it builds.  If it doesn’t, make sure the library is installed correctly.

On a side note, I actually wrote absolutely no code for this project.  I started out trying to use the PS2KeyboardExt2 library, but that library is based on interrupts and while it can run on an Arduino that is also speaking serial at 9600 bps, once I cranked the serial up to 19200 bps, the interrupts stopped working in a stable way.  So I yanked all of the nice code out of PS2KeyboardExt2, including the key definitions and the nice handling of shifts and caps lock and reworked it into a program that doesn’t use interrupts and makes use of a different, much simpler PS/2 library.  This makes it capable of handling 19200 bps serial in a reliable manner.

Now, to program the Arduino!

Disconnect the lead going to Pin 1 on the Arduino.  Then, connect the Arduino to your computer via USB cable.  You may need to restart the Arduino application so that it detects the new USB serial device correctly.  Load the saved sketch with the source, and then hit the Upload button to program the Arduino.

Once the program is uploaded, plug the keyboard into the PS/2 connector.  You should see the lights flash.  You can open up the Serial Monitor in the Arduino application and try typing some letters on the keyboard.  You should see those letters show up in the Serial Monitor.  Try turning the Caps Lock on and off, the light on the keyboard should go on and off and the characters should come out correctly capitalized.

The iPhone Client

Now to set up the iPhone client program.

For the client code, I’m using a program I found on Anthony Pray’s Google Code page.  This program reads input from the serial port at 19200 bps and then injects the appropriate keyboard event using a VNC client library.  I’ve made a local text-only mirror of the source here, which can be easily fetched with wget.

Since we’ll be injecting keypresses by VNC, you’ll also need to be running a VNC Server on the iPhone.  We’re going to use Veency (which is awesome and you should install anyway).

Go to Cydia or Icy and install the following packages:

  • Veency - Provides the VNC Server, configure it to run at startup
  • LibVNCServer - Provides libvncclient
  • iPhone 2.0 Toolchain - Provides a build environment (gcc, libgcc, ldid, libz are required if you go another route)
  • MobileTerminal - So you can access the iPhone terminal
  • wget - So you can pull down the source file

Now to download and build the source.  Either open up MobileTerminal or SSH into your phone, and then do the following:

  • wget http://awgh.org/files/TouchClient.c
  • gcc -static-libgcc -o TouchClient TouchClient.c -lvncclient
  • ldid -S TouchClient

The last step, using ldid, fakes signing the binary.  Without it, the iPhone OS will kill your process immediately.

To start the program, run it from Mobile Terminal with:

./TouchClient

This will cause Veency to pop up a dialog asking if you want to accept the VNC connection.  Hit Accept.

I’ve noticed that running this from MobileTerminal keeps the program alive even when you leave MobileTerminal, but it would be better to use launchd.  I haven’t figured that out just yet.

Finishing Touches and Future Work

To finish up, reconnect the lead from Pin 13 on the iPhone breakout to the TX pin (pin 1) on the Arduino.  Disconnect the USB cable and switch the Arduino to external power.  Plug the iPhone breakout into your iPhone.

If:

  • TouchClient is running on your iPhone
  • The PS2 software is running on your Arduino
  • The Keyboard is plugged into the connector, and the connector wired to the Arduino correctly
  • Veency is running and you have accepted the connection from TouchClient
  • Nothing else is screwed up

You should be able to type on the PS/2 keyboard and have those keystrokes translated to the appropriate iPhone keystrokes.  This will work anywhere in the iPhone, in any app or native feature.

This solution isn’t perfect, but it’s a general-purpose approach to using the Arduino to add PS/2 keyboard support to almost anything that can read simple serial messages.

Future work:

  • The scan code mapping could be moved entirely to the iPhone, and the hardware part of this project could be reimplemented on a much cheaper and lower power consumption chip, like a PIC.  This would reduce the cost of the unit by about $30, although it would require a PIC programmer.
  • Not all special keys are correctly mapped, but if you look in the Arduino code and then at the iPhone code, you’ll see that this is an incredibly simple process.  Please post any changes you make back here as a comment!
  • Rather than being a crazy wire hack, I’d like to see this fit into a snug little enclosure for real portability.  Any ideas in this department would be appreciated.
  • I would like to give TouchClient a password for Veency so that there isn’t that annoying Accept/Decline pop-up.
  • This exact method could be used to add a Bluetooth keyboard.  Simply add a Bluetooth-Serial module to the iPhone breakout and keep using TouchClient & Veency.

That’s it.  I hope you enjoyed the howto!  Looking forward to your comments.

Regards,

-awgh

{ 25 comments… read them below or add one }

PlastBox October 15, 2009 at 2:37 am

I will never feel right ponying up the cash for a product so locked down as the iPod but regardless, sweet hack!

The next logical step as far as I can see is to get a keyboard that matches the iPod, is relatively portable but has sufficient room to fit a completely stripped Arduino (really just the AtMega chip, resonator and FTDI chip if necessary) inside. Drop the entire PS/2 cable and use an iPod cable of some sorts instead and you have yourself a Ipodboard that is truly portable and even more awesome!

And btw, screw those Apple elves! I bet they don’t even speak Sindarin or have pointy ears!

Clara October 15, 2009 at 3:15 am

Great job!,

So will be posible to plug an X-Arcade with ps/2 interface to the iphone for mame? yeahhhhhh

Ricardo October 15, 2009 at 3:39 am

That’s a great hack. What I’ve never understood is why every phone doesn’t have a USB Host (Master) connector, so people can plug any peripheral they like into it – USB Keyboard, hard drive, printer, etc. That way, you treat phones as the centre of a system, like a laptop, not as a peripheral to a PC. Any ideas on how to add a USB Host socket?

Anthony Pray October 15, 2009 at 8:48 am

Thanks for your interest in my code.
This code all so supports touch input , it will will support any input into the iphone.
so yes Clara an X-Arcade would be possible!

Ryan Ray October 15, 2009 at 8:54 am

Good Stuff!! I’ve been wishing I could hack into my iphone for years now so that I could respond to my text messaging via my computer and keyboard, rather than having to pick up the extra device and type. Way to go Awgh!!

Ryan

Vance October 15, 2009 at 9:10 am

Awesome hack, and very clear write-up.

Could this be adjusted to work with a USB keyboard?

Leon October 15, 2009 at 9:19 am

I would builkd one immediately if it was a deamon and didn’t require any user intervention. Maybe one day I will find the time and hack up something decent.

BTW, I would think that there is plenty of space left inside the keyboard to stuff in a microcontroller. A keyboard with iPod dock out, how cool is that…

JAmerican October 15, 2009 at 9:19 am

Ricardo, my phone has USB Host because it rules!!!

Check out my mod :)… http://www.jamerican.net/?p=74

SpeedySurfer October 15, 2009 at 9:39 am

@Ricardo: Because if they don’t add a USB host, they can charge more for peripherals. Also, certain things need drivers (printers for example) so need the manufacturers support too.

h October 15, 2009 at 10:27 am

This sounds like a great idea. So for someone not as good at hacking things, would someone be interested in creating one of these, so it just needs a keyboard and an iphone plugged into it?
I wonder how much that would be. If it could be made a little smaller I see a huge market for external iphone keyboards.

justin October 15, 2009 at 2:12 pm

I thought that with 3.0 they opened up the serial port? I was planning on using it myself but cant find out how, did they really not open it up?

thanks!

awgh October 15, 2009 at 3:52 pm

To the best of my knowledge, there is no way I can do this through the SDK, even in 3.0. If I could, I probably would be selling an AppStore app and a tiny version of the hardware using a PIC. Still planning on doing the PIC version anyway :)

Anonymous 167 October 15, 2009 at 9:59 pm

Add a com.awgh.touchclient.plist file to /System/Library/LaunchDaemons, that looks something like this:

Label
com.awgh.touchclient
ProgramArguments

/Applications/TouchClient.app
darwin

RunAtLoad

UserName
mobile

Anonymous 167 October 15, 2009 at 10:00 pm

Err… well, the comment box stripped the XML, but you get the idea.

admin October 15, 2009 at 11:07 pm

Something like this, maybe? I haven’t tried it, it assumes the binary is in /var/mobile/bin:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"&gt;
<plist version="1.0">
<dict>
<key>Label</key>
<string>org.awgh.touchclient</string>
<key>ProgramArguments</key>
<array>
<string>/var/mobile/bin/TouchClient</string>
</array>
<key>UserName</key>
<string>mobile</string>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>

D@rkNeo October 16, 2009 at 9:10 am

awesome.. great work

Colin October 16, 2009 at 10:20 am

Not clear why you have to tie iPod’s TX to ground. In fact it sounds like a Bad Idea – seems that the pin driver on the iPhone will be sending current right to ground, wasting juice.

admin October 16, 2009 at 10:37 am

You may be right. It might be better with a pull-down resistor between pins 11 and 16 on the breakout? I’ll have to look at the iPhone spec again.

So you’d replace the jumper wire with about a 10k resistor and everything else is the same. I’m not sure that this would make any difference in power consumption or anything else, but you could try it.

I should point out that it would be trivial to wire up the TX pin to the Arduino and enable two-way serial communication with the keyboard. This would allow the iPhone software to handle things like the Caps Lock light, which is currently handled in the Arduino code.

-awgh

alviro October 16, 2009 at 5:27 pm

Good job!
I’ve made a similar project to connect a joypad to iphone.
If you would like to improve your project:
- use a microcontroller and not a dev board: pic16f88 is cheaper and internally clocked. It is considered the best choice for iphone hw.
- do not use veency to send the keyboard input, just keep out the code you need from veency source code. Simply seach iphone-tweaks on googlecode and use the KeyMouseRelay project (with some mods to work under fw 3.x).

If you need some helps feel free to contact me.

awgh October 16, 2009 at 7:03 pm

Thanks for your comment! I’ll check out KeyMouseRelay.

I’m planning on re-implementing this on a PIC, but this requires etching a board and completely rewriting the iPhone client. Should be an easy job for EagleCAD. Currently waiting for an order from Microchip :)

- awgh

alviro October 17, 2009 at 2:12 am

If you need the mod to make compatible KeyMouseRelay with 3.x mail me

Interested Blogger October 18, 2009 at 10:36 pm

I am truly interested in making an external keyboard for my iPhone, and was wondering if you would make the rig on request and sell it, or post a video of a ground-up construction of the rig. It would be very helpful. Thank you very much!

Thanks,
IBin

Bruce May 19, 2010 at 1:53 pm

[...] weten te hangen. Het project kost flink wat geduld en kennis van zaken, maar op zijn weblog is stap voor stap te lezen hoe je dit voor elkaar krijgt. Het resultaat verdient misschien geen schoonheidsprijs, [...]

Paul Kang July 4, 2010 at 11:08 pm

Hi, Awgh,

Thanks for the impressive blog. This is what I am looking for for a long time. I followed your steps and successfully build TouchClient.

I am wandering where can I find the linked library vncclient? I only found libvncclient.dyLib but no where to find vncclient.

Thank you in advance.

B/R,

Paul Kang

kruftindustries November 22, 2011 at 11:47 pm

http://www.circuitsathome.com/products-page/arduino-shields/usb-host-shield-for-arduino-pro-mini/

:) google is your friend, although programming support for those devices may be your enemy.

Leave a Comment

{ 19 trackbacks }

Previous post:

Next post: