This example project will show how to read key presses from a 16 (4 by 4) button keypad. This will introduce you to the concept of "strobe and scan" which a technique very commonly used for button input.

We will be using a 4 by 4 button keypad like the one shown below. You will also need 8 header pins or jumper wires to use for connecting the keypad to your PeekyPokey.

As you will see, this type of keypad is quite easy to use. It's only about 2 mm thick and has a self-adhesive backside so that you can stick it onto whatever you like. These keypads are very common will only cost you a few US dollars on popular on-line market places.

A 4 by 4 keypad contains 16 switches (one under each button) but you'll be able to detect all the 16 buttons using only the 8 GPIO pins of  the PeekyPokey. To achieve this, we'll be using "strobe and scan".

In a real world design, you would probably use a dedicated slave chip to control the keyboard but this example serves to demonstrate the strobe and scan technique in itself.

As can be seen, the ribbon cable of the keypad has 8 wires - one for each of the 4 rows and one for each of the 4 columns. The 16 switches of the keypad are arranged in a 4 by 4 matrix pattern as depicted below where circles symbolizes the switches:

When a button is pressed, the switch of the corresponding row and column is closed. Let's say you press the button "6" which sits in the intersection of row 2 and column 1. Since this closes the corresponding button switch, a voltage applied to row 2 would also be seen at column 1.

Working principle - strobe and scan
To read the keypad, you "strobe" each row by applying a voltage to each row in turn. While strobing a row, you "scan" the columns looking for one with a voltage on it. In pseudo code:

  1. Initialize a variable Y to zero
  2. Apply voltage to row Y
  3. Initialize a varible X to zero
  4. Check column X for the presence of voltage
  5. If voltage present, button at position (X,Y) is being pressed
  6. If X is less than 4, increment X and goto (4)
  7. If Y is less than 4, increment Y and goto (2)
  8. Goto (1)

You must repeat the process rather quickly not to miss out on a button being pressed in between scans.

Wire up your keypad to the PeekyPokey by connecting the 8 wires to gp0 through gp7 like this:

You'll be using C# code to implement the "strobe and scan" working principle described earlier. Here's what you do:

  1. Start Visual Studio
  2. Choose to create a new Console Application
  3. Replace the code "Program.cs" with this code block:


using System;
using System.Runtime.InteropServices;
using PeekyPokey;

namespace Keypad
    class Program
        private static extern void keybd_event(Byte virtualKeyCode, Byte scanCode, UInt32 dwFlags, UIntPtr dwExtraInfo);

        static void Main(string[] args)
            // 4 bit output bus for rows to strobe
            var rowbus = new Port.Bus(Device.Pin.Gpio4, Device.Pin.Gpio5, Device.Pin.Gpio6, Device.Pin.Gpio7);

            // 4 bit input bus for columns to scan
            var colbus = new Port.Bus(Device.Pin.Gpio0, Device.Pin.Gpio1, Device.Pin.Gpio2, Device.Pin.Gpio3);

            //  main loop
            for (int row = 0, lastkey = -1; true; )
                int key = -1;

                // strobe rows...
                for (int i = 0; i < 4; i++, row = (row + 1) & 3)
                    // set row bit
                    rowbus.Value = (byte)(1 << row);

                    // scan column inputs...
                    int col = ScanColumns(colbus.Value);
                    if(col != -1)
                        // key detected!
                        key = 4 * row + col;

                if (key != lastkey)
                    if (key != -1)
                        Console.WriteLine("Keycode Down: {0}", key);
                        Console.WriteLine("Keycode Up: {0}", lastkey);

                    lastkey = key;

        static int ScanColumns(byte mask)
            for (int col = 0; col < 4; col++)
                if ((mask & (1 << col)) != 0)
                    return col;
            return -1;

        // key symbols as printed on the keypad, item with 0x100 added to them
        // will use the shift key modifier
        static int[] _vkeys = { 'D' + 0x100, '3' + 0x100, '0', 'X', 'C' + 0x100, '9', '8', '7', 'B' + 0x100, '6', '5', '4', 'A' + 0x100, '3', '2', '1' };

        static void SendKey(int key)
            int vkey = _vkeys[key];

            // optional shift down
            if ((vkey & 0x100) != 0) keybd_event(0x10, 0, 0, UIntPtr.Zero);

            // send the key
            keybd_event((byte)vkey, 0, 0, UIntPtr.Zero);

            // optional shift up
            if ((vkey & 0x100) != 0) keybd_event(0x10, 0, 2, UIntPtr.Zero);


The code above is somewhat more complicated than the pseudo code and that is because I added some extra code to avoid key repetitions and to detect when keys are pressed or released respectively.

The "SendKey" method is used to send virtual key strokes to Windows, effectively simulating the event actual keyboard buttons being pressed and released.

Before hitting the green arrow to run your application, launch the PeekyPokey Dashboard and use it to configure gp0...gp3 for input and gp4...gp7 for output.

To test your keypad, simply launch Notepad and start typing. Notice which LEDs are lit as you hold down keyboard button and compare this to rows and columns.

Hint: By omitting the first row of keys A,B,C and D, you only need 4 + 3 = 7 GPIOs. The 8th pin can then be used for something else, like pulling a relay. You could use the keypad for entering a secret PIN code. If the code is correct, you use the relay to pull an electronic door latch.

Have fun!

Last edited Aug 26, 2013 at 11:13 PM by hanzibal, version 7