Keypads are a very commonly used input device in microcontroller-based systems. In a keypad, multiple switches are arranged in rows and columns so that they could be interfaced to a microcontroller with a minimum number of I/O pins. For example, a 12-key keypad is arranged in a 4×3 format, which allows to interface the 12 keys to a microcontroller with only 7 connections. The location of each key on the keypad is defined by two coordinates: the row and the column. When a key is pressed, it connects its row with its column. The microcontroller must scan all the rows and columns to find out which key has been pressed. This is the most common way of interfacing a keypad to a microcontroller. There are tons of resources on the internet regarding this technique and so I am not going to discuss it here.
Today, I am going to share with you about a new keypad interfacing technique that uses only two I/O pins of a microcontroller: one for signalling the microcontroller when a key is pressed, and the other is to read the key information. It is based on a 555 timer IC which is configured as an astable multivibrator. I am not sure if anybody has ever tried using a 555 IC for keypad interfacing, but this technique really works. I am going to demonstrate this with a 4×3 keypad (a standard telephone dial pad). A PIC16F628A microcontroller will read the output of a 555 timer IC, determine what key has been pressed, and display it on a character LCD module.
This technique is based on a very simple principle. The output frequency of a 555 astable multivibrator is defined by two resistors and a capacitor, as shown below.
If we fix R1 and C, the frequency can be varied by varying R2. In this technique, each key on the keypad connects a different R2 resistor when it is pressed, and therefore, generates a different output frequency. The microcontroller can then read the output frequency and determine which key was pressed. At first it does seem more complex as it may require floating point math regarding the frequency calculations. Besides, the frequency may not be precisely stable all the time. But this can be simplified with the proper selection of resistors and the use of the timer module inside the microcontroller. So here’s how it works:
When a key is pressed, a certain value of R2 resistor is connected between pins 7 (Discharge) and 6 (Threshold) of the 555 timer, completing the astable multivibrator circuit. The output pulses are counted for 100 ms through a timer module (used as counter) in the microcontroller. The microcontroller determines the pressed key from the number of times the timer has overflown. If the timer module overflows 5 times, the pressed key is 5. Similarly, if 0 key is pressed, the timer doesn’t overflow in the 100 ms window. Isn’t it simple now?
The figure below shows how the 12 keys are connected to the 555 timer IC to generate 12 different frequencies. R0 through R# are 12 different resistors corresponding to those frequencies. You can see when a key is pressed, the corresponding resistor is connected between pins 6 (Threshold) and 7 (Discharge) and the astable multivibrator circuit is completed.
The values of R1 and C are 1 K and 0.01 uF. The following table shows the different values of R2 for each keys, the corresponding frequencies, and the number of times the Timer0 module overflows. Some of these resistors are made from combining two resistors together.
So when the # key is pressed, the Timer0 module overflows 11 times.
Important Note: For more reliable operation of this circuit, use lower tolerance values for capacitor C and R2 resistors. I am using 5% tolerance for R2 and C, but lower than this would be better.
Frequency and Pulse outputs
There are two outputs in this circuit. One is the frequency output derived directly from pin 3 that is fed to the T0CKI (Timer0 input) pin of a PIC16F628A microcontroller for counting. The second one is the smoothed pulse output using a capacitor Cp at the output of 555. When a key is pressed, the train of pulses at the output of 555 is smoothed out to a single pulse by the capacitor. This pulse is to signal the microcontroller when a key is pressed. The Rp (3.6 K) resistor provides the discharge path for the capacitor when the key is released so that another pulse would appear for next key press. The diode (D1) isolates the two outputs.
Significance of Rp and Cp values
The value of Rp is not picked randomly, it has its significance. If Rp is too high, there will be a long waiting time between any two key presses as the capacitor takes longer time to discharge through a higher resistance. Meanwhile, the value of Rp could not be too low that the capacitor voltage drops significantly between two successive pulses at the 555 output. With Rp=3.6 K and Cp = 1 uF, the RC time constant becomes 0.0036 s. It means that if the 555 output frequency is 278 Hz (1/0.0036), the voltage across the capacitor could fall down to 63% of its peak value in between the two consecutive pulses. This means the current values of Rp and Cp are not good enough to smooth out the signal. Therefore, the values of Rp and Cp must be chosen such that the RC time constant should be sufficient enough to smooth out the entire frequencies of operation and meanwhile it should be low enough that the user could press keys in sequence with minimum wait time. The current values of Rp and Cp introduces about 5 ms wait time and we don’t press keys that fast. Besides, the minimum frequency output is 1516 Hz (from the table above) which is much higher than 278 Hz.
Role of Rc resistor
If you look at the circuit diagram you will see a Rc (= 10 MΩ) resistor that is permanently connected between Vcc and C. This resistor plays a very interesting role. When you release a key, the astable multivibration is stopped because there is no R2 in the circuit. We know that the output stage of the 555 IC has a R-S flip-flop, the complement of which actually appear at the 555 output. Suppose the flip-flop was reset (which means the 555 output is high) at the moment when the key was released. Then there will be no way for the output to reset to 0 if the path through R2 is broken until we provide an alternative recharge path for the capacitor C. Once the capacitor gets charged to 2Vcc/3, the output will be zero again. Remember, we have to make sure that the output falls to zero before pressing another key. So Rc takes care of this. The high value of Rc (10 MΩ) makes sure that it has little impact on the charging of C during normal operation. If you didn’t get this part, please refer the functional block diagram of the 555 timer IC.
My 555 based 12-key keypad
I am using 5% tolerance for C
The two outputs from the keypad are connected to the PIC16F628A microcontroller. The pulse output goes to RA2 pin whereas the frequency output goes to RA4/T0CKI input of the microcontroller. A standard character LCD module is also connected to the microcontroller to display what key is pressed. I have also connected an LED with a 470R resistor in series at the output of 555 (not shown in the circuit diagram) so that it glows every time a key is pressed.
I have written a sample test program with MikroC compiler that uses Timer0 module to count the external pulses from the 555 timer output. The program polls for a pulse signal at RA2 pin, and when the pulse is detected, the Timer0 module is activated for 100 ms and the number of overflows is recorded. The pressed key is displayed on a 16×2 character LCD. You can download the source code and HEX file here.
I have got some feedbacks in past few days regarding this technique, and most of them say this would be hard from programming perspective. But let me tell you this. The microcontroller needs a program no matter you use the matrix keypad and scan rows/columns, or use a resistor divider network technique and write the program to read and compare the ADC values for the pressed key. I would say the programming part for this technique is not that hard, as I said you don’t have to deal with calculating any frequency here. You just need to enable a timer for a fixed interval (I am using 100 ms, and of course the key has to be pressed for at least that long) when a key press is detected. Then, the information regarding the pressed key is given by the number of times the timer is overflown. Here’s the flowchart of how this works.