Using a 4x4 KeyPad With CircuitPython

Introduction: Using a 4x4 KeyPad With CircuitPython

About: Retired teacher of computing - started 1967 with FORTRAN IV. I now play with development boards such as Raspberry Pi, Pico, Arduino, micro:bit and Adafruit CircuitPython boards like the Insybitsy M4 and Circui…

This inexpensive keypad offers a simple method of numeric input to your CircuitPython projects. I'm going to use it with an Adafruit ItsyBitsy M0 express.

You will need:

  • Keypad - mine is 4x4
  • ItsyBitsy M0 Express or similar board
  • Mu Editor installed on your computer
  • USB cable to flash the code

Step 1: How the Keypad Works

They Keypad has 16 simple, slow acting bubble switches arranged in a 4 by grid with 8 connections at the bottom. If we number from the left from 0 to 7, the connections 0 to 3 are connected to each of the rows. Connection 0 to the top row and connection 3 to the bottom row. Connections 4 to 7 are connected to the columns with connection 4 on the left column and connection 7 to the right column. Each of the 16 switches makes a join between a different row/column combination. If we press key7 the third row is joined to the left column. We can sense if the 5 key if being pressed if its row is raised HIGH and we can read a HIGH on its column. To do this we OUTPUT to the rows and INPUT from the columns.

We need to set each row HIGH in turn, while the other rows are LOW, read each column in turn until we get a HIGH input. This is easily managed with nested for loops.

We need to take into account of the fact that these bubble switches are quite slow acting and need to be pressed quite hard to make them close. Scanning all 16 switches in this way can be done very quickly but we have to scan repeatedly to pick up a key press. We also need to 'debounce' with a short time delay so that we do not get keys repeating each time we press.

As the switches are quite 'squishy' we need some feedback to the user to indicate that a key press has been read. The built-in LED is flashed each time a key press is sensed.

Step 2: Physical Connections

Connections left to right on KeyPad
0 1 2 3 4 5 6 7

D7 D9 D10 D11 A5 A4 A3 A2 on ItsyBitsy

D7 to D11 are set out as OUTPUTs while A5 to A2 are set up as INPUTs with PULLDOWN.

The code has plenty of comments and should be quite easy to follow.

Step 3: How Getkey() Works

This function scans the keypad for a single key press. It quickly checks each of the keys in turn a maximum of 10 times to see if a key switch is closed. If a key is pressed it returns the key value, counting left to right from top to bottom (0 ...15) Note the values for the bottom row: 14, 0, 15,13 (Hex E,0,F,D). If no key was pressed it returns -999 as an error code which can be easily picked up in the main program. The built-in LED flashes if a key press is picked up as user feedback. This runs pretty quickly and the de-bounce wait of 0.2 seconds is only used when a key is pressed.

Step 4: Getvalue(digits)

This routine supplies an n digit value from the numeric keys. It ignores the red keys.

This Python code can easily be converted to run on another device, such as a Raspberry Pi, you probably only need to change the pin setup lines at the top of the script.

Please let me know if you find the code useful.

Stay safe and have fun!

Be the First to Share


    • Plywood Contest

      Plywood Contest
    • Cheese Challenge

      Cheese Challenge
    • Microcontroller Contest

      Microcontroller Contest



    1 year ago on Step 4

    Nice solution, thanks for sharing. I ported this onto a pi pico running circuitpython and it runs well but I am still getting some bounce issues with the buttons. If you increase the sleep it becomes unresponsive. However im interested in using this with a neopixel display so i can trigger different patterns, colours and effects with different keypad presses. Trouble is, the neopixels all run inside their own loops and im not sure how to interrupt the loops to check if a key is pressed? Is there way of getting the keypad to output simple integers I can then use to set colour/pattern on a neopixel strip?


    Reply 1 year ago

    Some time since I wrote this!
    Since you are using a Pico you could try MicroPython. This supports threads. You could use the main core to look after the keyboard and the other to drive the Neopixels. I've not tried it yet (been spending all my time on Explorer graphics.) There is some help in the official Raspberry Pi Picon SDK, easy to download.

    Best of luck. I'd be interested to know how you get on.