skip to Main Content

Interfacing a touch keypad with an AVR

I’ve always admired touchpad technology and I recently got a chance to make my own 12-key touchpad using Freescale’s MPR121Q. This nifty little chip supports upto 12 debounced pads, configurable registers and works on the I2C protocol. All the electrodes can be combined into one electrode that acts as a proximity sensor. Also of the 12 electrodes, 8 can also be used as GPIO pins that can drive LEDs.

For a rundown on how to create your own touch keypad using this chip see this post. Gerbers, schematics are all included in the download here.

The basic task to get the MPR121Q working is by setting up a bunch of registers. These essentially control a variety of things including touch and release thresholds, baseline levels, touch filter levels (for debounced outputs) etc. More details on that are in the datasheet. For a quick guide to knowing what these registers do and how to set them up read the AN3944 application note from Freescale.

The Schematic

My test setup included interfacing the MPR121Q with an Atmega8A. I also included an LCD display that shows which of the keypads were touched. The code includes the I2C and MPR121 read, write and configuration routines from Sparkfun’s code. The LCD code is based on Peter Fluery’s excellent LCD tutorial. Please note that the code is in C. I compiled it using Atmel Studio 6.1. If you are using any Arduino flavors, check out Sparkfun’s code which gives the code in Arduino syntax.

The MPR121Q is a 3.3V device and connecting it to a 5V device may cause it to burn out.

Though folks at Sparkfun say that this can be hooked up to an Uno or Duemilanove or other 5V Arduino’s directly (only the SDA, SCL and IRQ pins. The VCC still needs to be 3.3V) I’ve not tried it. My entire setup is based on 3.3V (except for the LCD which is on 5V).

The Code

Before you upload the code, you may want to set the Atmega8A fuse bits to use an external oscillator. Also since the whole setup is on 3.3V the maximum oscillator frequency is 8MHz. The code also supports sending data through an UART. Hence to keep error rates to 0.00% a 7.3728MHz crystal is chosen.


Here is my code. Its quite long and you may want to break it up into libraries. The code is appropriately commented. If you have queries give us a shout in the comments.

This Post Has 5 Comments
  1. So, if the ‘#’ is pressed, you end up reading either register 00 or 01  a total of 288 times before you determine what key was pressed ?

    1. To be honest, this was a very long time ago and I don’t remember much of it. In the ‘printPadLCD’ function the two registers seems to be read once each for 11 times before it reaches the ‘#’ key (through the ‘whichPad’ function). It obviously could’ve been written to just read the register once and store its value in a variable and then compare against a known set of values for printing on the LCD. The ‘whichPad’ function, each register gets read once and that value is then compared against the set values of the keypad.

    1. I’ve never used CVAVR and I do not have the hex file with me as of now. I worked on this project a long time ago… Sorry!

Leave a Reply

Your email address will not be published. Required fields are marked *

Back To Top