Many application requires large number of keys connected to a computing system.
Example includes a PC keyboard, Cell Phone keypad and Calculators. If we connect
a single key to MCU, we just connect it directly to
i/o line
. But we cannot connect, say 10 or 100 keys directly MCUs i/o. Because
:-

  • It will eat up precious i/o line.
  • MCU to Keypad interface will contain lots of wires.
Buy Matrix Keypad in India

Buy Matrix Keypad

We want to avoid all these troubles so we use some clever technique. The technique
is called multiplexed matrix keypad. In this technique keys are connected in
a matrix (row/column) style as shown below.

Matrix Keypad Diagram

Matrix Keypad Basic Connection

The rows R0 to R3 are connected to Input lines of Microcontroller. The i/o
pins where they are connected are made Input. This is done by setting the proper
DDR
Register
in AVR and TRIS Register in PIC. The column C0 to C3 are also connected
to MCUs i/o line. These are kept at High Impedance State (AKA input), in high
z state (z= impedance) state these pins are neither HIGH or LOW they are in
TRISTATE. And in their PORT value we set them all as low, so as soon as we change
their DDR bit to 1 they become output with value LOW.

One by One we make each Column LOW (from high Z state) and read state of R0
to R3.

Column 0 Selected

Column 0 Selected

As you can see in the image above C0 is made LOW while all other Columns are
in HIGH Z State. We can read the Value of R0 to R3 to get their pressed status.
If they are high the button is NOT pressed. As we have enabled internal pullups
on them, these pullups keep their value high when they are floating (that means
NOT connected to anything). But when a key is pressed it is connected to LOW
line from the column thus making it LOW.

After that we make the C0 High Z again and make C1 LOW. And read R0 to R3 again.
This gives us status of the second column of keys. Similarly we scan all columns.

Column 1 Selected

How to Do it All with AVRs

Each i/o port in AVR has three related registers PORTx, DDRx and PINx. For
example port A has

  • PORTA Port Driver – when any bit is set to 1 it appears
    as HIGH i.e. 5v . But this is the case only if that bit is OUTPUT. If it is
    input, setting any bit to 1 enables the internal pullup on that bit.
  • DDRA DATA DIRECTION REGISTER
    – Make any pin on than port as IN or OUT. When bit is 1 it represents Output.
    When bit is 0 it represents Input. Input state is also called tristate or
    high Z state.
  • PINA – Read it to get the level (HIGH or LOW) at the actual
    i/o pin. It is read when the pin is made input.

So now you know

  • How to make any i/o line Input(high Z) or Output.
  • How to enable internal pullup register on input lines.
  • How to read value that is present on input lines.

Please see the following tutorial for more clarification.

Why we make other Columns High Impedance while one column is made LOW?

Lets say we selected column number C0, so we make it LOW(i.e. GND or logic
0), in the same time we make all other columns high impedance (i.e. input).
If we don’t make other lines high impedance (tristate or Input) they are in
output mode. And in output mode they must be either LOW(GND or logic 0) or HIGH
(5v or logic 1). We can’t make other lines LOW as we can select only one line
at a time and C0 is already low as per assumption. So the only other possible
state is all other columns are HIGH. This is shown in figure below. Red colour
on column indicate high state while green is for low state.

keypad wrong connection

Wrong Way!

Suppose at that time the user presses KEY0 and KEY1 simultaneously as shown
below.

Short Circuit !

As you can see clearly that it create a short between C0 (GND) and C1 (5v),
this will burn out the buffer of the MCU immediately!

Short!

That’s why all other columns are kept at tristate(neither LOW nor HIGH) but
very high input impedance that prevent either source or sink of current from
them. So if we kept C1 at high impedance state it wont allow current to flow
to GND on C0.

avr-gcc C code for 4×3 matrix keypad


1     /******************************************************************************
2
3     Program to learn the use of Multiplexed 4x3 keypad with AVR Microcontroller.
4
5     Specific Skills Required
6        >> AVR GPIO details.(http://bit.ly/aq3ouw)
7        >> LCD Library.(http://bit.ly/agVUVc)
8        >> Operations on bits using C.(http://bit.ly/aFqg5n)
9
10
11    General Skills Required
12       >> AVR Studio Setup and use. (http://bit.ly/aZ43SZ)
13       >> avr-gcc setup and use.
14
15
16    Hardware
17    --------
18    ATmega32 @ 16MHz external crystal.
19    Fuse Byte setting HIGH = C9 and LOW = FF (MOST IMP.)
20
21
22    LCD   <->   AVR Connection
23
24       VSS ->GND
25       VDD ->+5V
26       VEE -> CENTER PIN OF 10K POT (OTHER TWO PIN OF POT TO +5V AND GND)
27             ADJ. THE POT UNTIL YOU HAVE A CLEAR TEXT DISPLAY.
28
29       RS -> PD3
30       RW -> PD6
31       E  -> PB4
32
33       DB0 -> N/C
34       DB1 -> N/C
35       DB2 -> N/C
36       DB3 -> N/C
37
38       DB4 -> PB0
39       DB5 -> PB1
40       DB6 -> PB2
41       DB7 -> PB3
42
43       LED+ ->+5V (VIA 100 OHM RES)
44       LED- ->GND
45
46    KEYPAD
47
48       COL1 ->  PA6
49       COL2 ->  PA5
50       COL3 ->  PA4
51
52       ROW1 ->  PA3
53       ROW2 -> PA2
54       ROW3 ->  PA1
55       ROW4 -> PA0
56
57                                NOTICE
58                               --------
59    NO PART OF THIS WORK CAN BE COPIED, DISTRIBUTED OR PUBLISHED WITHOUT A
60    WRITTEN PERMISSION FROM EXTREME ELECTRONICS INDIA. THE LIBRARY, NOR ANY PART
61    OF IT CAN BE USED IN COMMERCIAL APPLICATIONS. IT IS INTENDED TO BE USED FOR
62    HOBBY, LEARNING AND EDUCATIONAL PURPOSE ONLY. IF YOU WANT TO USE THEM IN
63    COMMERCIAL APPLICATION PLEASE WRITE TO THE AUTHOR.
64
65
66    WRITTEN BY:
67    AVINASH GUPTA
68    me@avinashgupta.com
69
70
71
72    ******************************************************************************/
73
74    #include <avr/io.h>
75    #include <util/delay.h>
76
77    #include "lcd.h"
78    #include "myutils.h"
79
80    #define KEYPAD A  //KEYPAD IS ATTACHED ON PORTA
81
82    //Don't Touch the lines below
83    //*******************************
84    #define KEYPAD_PORT PORT(KEYPAD)
85    #define KEYPAD_DDR   DDR(KEYPAD)
86    #define KEYPAD_PIN   PIN(KEYPAD)
87    //*******************************
88
89
90    /*******************************************
91
92    Function return the keycode of keypressed
93    on the Keypad. Keys are numbered as follows
94
95    [00] [01] [02]
96    [03] [04] [05]
97    [06] [07] [08]
98    [09] [10] [11]
99
100   Arguments:
101      None
102
103   Return:
104      Any number between 0-11 depending on
105      keypressed.
106
107      255 (hex 0xFF) if NO keypressed.
108
109   Precondition:
110      None. Can be called without any setup.
111
112   *******************************************/
113   uint8_t GetKeyPressed()
114   {
115      uint8_t r,c;
116
117      KEYPAD_PORT|= 0X0F;
118
119      for(c=0;c<3;c++)
120      {
121         KEYPAD_DDR&=~(0X7F);
122
123         KEYPAD_DDR|=(0X40>>c);
124         for(r=0;r<4;r++)
125         {
126            if(!(KEYPAD_PIN & (0X08>>r)))
127            {
128               return (r*3+c);
129            }
130         }
131      }
132
133      return 0XFF;//Indicate No key pressed
134   }
135
136
137   void main()
138   {
139      //Wait for LCD To Start
140      _delay_loop_2(0);
141
142      //Now initialize the module
143      LCDInit(LS_NONE);
144
145      uint8_t key;
146
147      while(1)
148      {
149         key=GetKeyPressed(); //Get the keycode of pressed key
150
151         LCDWriteIntXY(0,0,key,3);  //Print it at location 0,0 on LCD.
152      }
153
154   }

The above code make use of the LCD Library. You can get more information on
LCD Library here :-

Hardware for 4×3 Matrix Keypad and AVR interface.

The test circuit will be built around
ATmega32
microcontroller.
The output device will be a 16×2
lcd modul
e. So we set up a basic ATmega32 circuit. The circuit
will have the following :-

  1. ATmega32 MCU
  2. 16MHz Crystal
  3. Reset Circuit.
  4. 5v Power Supply Circuit.
  5. ISP (For programming)
  6. LCD Module.
  7. LCD Module Contrast adjust pot.
schematic for atmega32, lcd and keypad

ATmega32 + LCD + Keypad Interface.

We have built the above circuit on a Low
Cost AVR Development Board
, but it does not has inbuilt LCD Module
connector so you need to solder it yourself at the free area (and also do the
wiring).

Compile the above program using AVR Studio (compiler is avr-gcc). And finally
burn the program using any ISP
Programmer
to the ATmega32. The fuse bits must be set as
following to enable external crystal as clock source.

  • High Fuse = C9 (hex value)
  • Low fuse =FF (hex value)

After burning the HEX file to MCU, finally you are ready to power up the setup.
When powered on, the LCD Screen Should show you the keycode of the key
pressed on the keypad.
This complete our test.

Troubleshooting

  • NO Display on LCD
    • Make sure AVR Studio Project is set up for clock frequency of 16MHz
      (16000000Hz)
    • Adjust the Contrast Adj Pot.
    • Press reset few times.
    • Power On/Off few times.
    • Connect the LCD only as shown on schematic above.
  • No response to key press.
    • Check that keypad is connected on PORTA only.
    • If you want to attach keypad on different port, change the line 80 on
      source code (keypad.c)
    • #define KEYPAD A
      //KEYPAD IS ATTACHED ON PORTA
  • Compiler Errors
    1. Many people these days has jumped to embedded programming without a
      solid concept of computer science and programming. They don’t know the
      basics of compiler and lack experience. To learn basic of compilers and
      their working PC/MAC/Linux( I mean a desktop or laptop) are great platform.
      But embedded system is not good for learning about compilers
      and programming basics. It is for those who already have these
      skills and just want to apply it.
    2. Make sure all files belonging to the LCD Library are "added"
      to the "Project".
    3. avr-gcc is installed. (The Windows Binary Distribution is called WinAVR)
    4. The AVR Studio project Type is AVR GCC.
    5. Basics
      of Installing and using AVR Studio with avr-gcc is described in this tutorial
    6. How
      to add files to project is described in this tutorial.
  • General Tips for newbies

Video For 4×3 Keypad Interfacing.



User Videos

By Brendin

I really appreciate Brendin’s approach on getting his problem solved and successfully porting the demo to ATmega48. What I recommend the users is to get your basics strong. You need full understanding of C language concept and the full details of the device you are programming, this will save you lots of time. So please go and read the good book on C and the datasheet of AVRs before you dive in! – Avinash

Downloads

Help Us!

We try to publish beginner friendly tutorials for latest subjects in embedded
system as fast as we can. If you like these tutorials and they have helped you
solve problems, please help us in return. You can donate any amount
as you like securely using a Credit or Debit Card or Paypal
.





We would be very thankful for your kind help.

By

Avinash Gupta

Facebook,
Follow on Twitter.

www.AvinashGupta.com

me@avinashgupta.com