Interfacing With A PS/2 Keyboard

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

  1. 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;

    int main()
    // …
    while (1)
    if (keyPressed)

    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.

    1. 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.

      1. 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.

  2. 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.

  3. 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.

Leave a Reply

Please be kind and respectful to help make the comments section excellent. (Comment Policy)

This site uses Akismet to reduce spam. Learn how your comment data is processed.