Anyone reading this post has undoubtedly used a keyboard. How they work, however, is a bit more complicated than “one button, one input.” [PyroElectro] has a great tutorial about building a PS/2 keyboard interface with a 7-segment LED display (video after the break). The tutorial also includes quite a bit of theory behind it.
The system displayed below uses a PIC controller to display the letter or number pressed. A schematic of the whole project is given here as well as a detailed bill of materials.
As for how the PS/2 keyboard works, each keystroke is encoded into a binary number or “scan code”. Most of these codes are 8-bit, but some special symbols use a longer code. Although the article doesn’t fully address it, a very similar method can be used to send data back to the keyboard for such purposes as tuning on a “capslock” or “numlock” key. Although turning on a light is fun, we could see this being used as an expedient method to control a relay for automation purposes.
15 thoughts on “Interfacing With A PS/2 Keyboard”
Hahahah, good one!
This just made me realise how useful it would be to have a keyboard LCD which displays scan codes, HTML entities, etc for key presses while programming!
something like this: http://elektrickery.blogspot.com/2011/07/keyboards-4-lcd-of-awesome.html
Things get more difficult when you start tweaking scancodes. I’ve had to unplug/plug in my keyboard twice today already :(
should have posted this link from your hack, its more informative.
If you’re writing an interrupt-based PS/2 keyboard routine in C on the AVR, don’t forget the “volatile” keyword!
You might have something like this:
static int keyPressed = 0;
if (bitsReceived == 11)
keyPressed = 1;
You’ll run it and see that nothing happens when you press keys! The compiler isn’t smart enough to recognize that keyPressed can be set by the interrupt handler, so it thinks keyPressed will always be zero, and it optimizes out the entire if statement.
To fix this, just declare keyPressed with the volatile keyword:
static volatile int keyPressed = 0;
The meaning of volatile is vague and it differs from platform to platform, but based on the assembler output, it looks like AVR-GCC never keeps a volatile variable in a register: when used, its value is always loaded from memory, and when it’s changed, the new value is always immediately stored back to memory.
IIRC, the basic C/C++ Standard meaning of volatile: This variable can change behind the code path’s back, so don’t make any assumptions about it’s value. Basically, the compiler has to check it’s in-memory value every time the variable is used, so no caching in registers and no optimizing away “obvious” unreachable code.
Basically, it tells the compiler never to cache the value of the variable, and always read/write instantly so it doesn’t get an old value which may have changed since it was cached.
Interesting, I will keep this in mind. However, my compiler, pic ccs, has not shown this issue. I have several vars that get updated in isr’s and main code that checks them.
The letter ‘B’ was the same as the number 8.
I was all ready to see how the letter ‘K’ would be displayed, but you ended on the letter ‘J’. :o(
I expect H and K are the same.
What happened with printscreen and pause/break?
Did the engineer have a seizure while he was writing the spec?
It’s worth noting that many laptop touchpads also communicate via ps2. They are easily available for cheap and make slick input devices for uc’s.
I think there is an Arduino library for this…the only problem is finding a PS2 keyboard that still works…I only have one of them left…it is white, it is old, and some of the keys stick in spite of being cleaned because the springs are worn out. This would be a lot better with USB as you can get a brand-new keyboard in black from almost any store.
Several of the chips in the Picaxe range have ps/2 keyboard support built-in, as well as having the ability to turn the Scroll/Num/Caps Lock LEDs on/off.
hey, I am converting ps2 protocol to uart protocol. I am using stm32f0. Can you please let me know how ps/2 devices send data? First ps/2 device pulls the clock line down and then it releases the data line. then the host takes the control of clock line. Host toggles the clock line and with each toggle ps/2 device sends data. Is it that? Somebody told me something like this. Please correct me if I am wrong. Thank you.
did you get it working??
if so pls help me
Please be kind and respectful to help make the comments section excellent. (Comment Policy)