Adding a keypad

9 May

Adding a keypad
We can implement a numeric keypad using the previously mentioned buttons and interrupt events. But it will get a bit tedious to trap a large number of buttons and also store which was pressed. To simplify things a bit, we will use a keypad encoder. There are several on the market for 16 and 20 key keypads. Fairchild Semiconductor makes the MM74C922 and MM74C92313, and e-lab makes the EDE114414 keypad encoder integrated circuits. Figure 8-19 shows a typical keypad implementation based on a MM74C922.

Figure 8-19: Keypad schematic

We can monitor our keypad by polling the DataPort or we can attach the DataAvailable output from the IC to the /EXTINT pin on TINI (through an inverter since the DataAvailable line is active high). The schematic for the buttons in the previous section shows this DataAvailable (KBDA) line is connected to the 74VHC541 buffer and the external interrupt logic along with the push buttons. In this way, we can capture events from the keypad or the pushbuttons. If you only needed to use the keypad, without the push buttons, then there would be no need to implement the 74LS74 D flip flops to store the state of the buttons, as the only external interrupt would be from the keypad data available signal, and probably no need to use a circuit like Figure 8-17 to combine multiple interrupt sources. Be careful of the keypad pin-out. These encoder ICs need matrix switch keypads that are arranged in rows and columns, where a single button push will connect the row pin with the column pin for that key. Shown is the pin-out for one particular keypad. There appears to be quite a bit of variation between keypad pinouts.

The following class, Keypad, can be used to access a keypad implemented according to the schematic. You can use this by either polling or implementing an External Interrupt Event listener.

Listing 8-11: Keypad.java

import com.dalsemi.system.*;
// CLass Keypad defines methods for acceing a numeric keypad
class Keypad                                                   {
DataPort keypad;
public Keypad( int addr ) {
keypad = new DataPort( addr );
keypad.setStretchCycles(DataPort.STRETCH10);
}
// read raw key info from keypad
public int readRaw() {
int d=0;
try {
d = keypad.read();
}
catch (IllegalAddressException e)
System.out.println( “Error in reading keypad” );
System.out.println( e );
}
// mask off upper 4 bits
return( (d & 0×0F ) );
}
// read keypad and returs the symbol for the appropriate key
public char readKey() {
int d = readRaw();
char k = ‘ ‘;
switch(d) {
case 0×00 :                                                    k=’1′;     break;
case 0×01 :                                                    k=’2′;     break;
case 0×02 :                                                    k=’3′;     break;
case 0×03 :                                                    k=’ ‘;     break;
case 0×04 :                                                    k=’4′;     break;
case 0×05 :                                                    k=’5′;     break;
case 0×06 :                                                    k=’6′;     break;
case 0×07 :                                                    k=’ ‘;     break;
case 0×08 :                                                    k=’7′;     break;
case 0×09 :                                                    k=’8′;     break;
case 0×0A :                                                    k=’9′;     break;
case 0×0B :                                                    k=’ ‘;     break;
case 0×0C :                                                    k=’*’;     break;
case 0×0D :                                                    k=’0′;     break;
case 0×0E :                                                    k=’#’;     break;
case 0×0F :   k=’ ‘;     break;
default:      break;
}
return( k );
}
}

•  Keypad(  int  addr  ) is the constructor. It takes one parameter, the address of the keypad dataport.
•  readRaw() returns an integer representing the key position on the keypad. This starts with 0 and counts up through the rows sequentially.

•  ReadKey()maps the key position number into a specific character. This method returns a character of the key. You could modify this method for specific keypad meanings, possibly returning bytes, strings or even objects rather than simple characters.

We can read this keypad in a manner similar to how we read the buttons, by polling.

Listing 8-12: pollKeypad.java

import com.dalsemi.system.*;
// Class pollKeypad demonstrates how (not very well) to poll the keypad
public class pollKeypad {
public static void main(String[] args)
{
char key = ‘ ‘;
int now = 0, last=0, i=0;
Keypad mykeypad = new Keypad(0×00800010 );
while (i<200) {
now = mykeypad.readRaw();
key = mykeypad.readKey();
if (now!=last) {
System.out.println( “Key: “ + Integer.toHexString(now)
+ “, keypad “ + key );
}
last=now;
TINIOS.sleepProcess(50);
i++;
}
}
}

Compile this program:
C:\> cd src
C:\> javac -bootclasspath    %TINI_HOME%\bin\tiniclasses.jar
-d ..\bin pollKeypad.java
C:\> cd ..
C:\> java -classpath %TINI_HOME%\bin\tini.jar;. BuildDependency
-p  %TINI_HOME%\bin\owapi_dependencies_TINI.jar
-f bin
-x %TINI_HOME%\bin\owapi_dep.txt
-o bin\pollKeypad.tini
-d %TINI_HOME%\bin\tini.db

Unfortunately, the keypad encoder has no provision for clearing its output after we have read which key was pressed, so this works well only if we never expect the user to press the same key twice in a row. To overcome this minor limitation, we can implement the ExternalInterruptEventListener as we did for a single button earlier.

Listing 8-13: myKeypad.java

import  java.util.TooManyListenersException;
import com.dalsemi.system.*;

// Class myKeypad demonstrates reading the keypad and buttons
// using an ExternalInterruptEventListener
class myKeypad implements ExternalInterruptEventListener {
int i;
Keypad mykeypad = new Keypad(0×00800010 );
Button mybutton = new Button(0×00800000, 0×00800004 );
public void init() throws TooManyListenersException
{
// This is the signal to which we will add an event listener
ExternalInterrupt myInterrupt = new ExternalInterrupt();
// Add the event listener
myInterrupt.addEventListener(this);
mybutton.clear();
}
public void externalInterruptEvent(ExternalInterruptEvent ev)
{
int state = 0;
System.out.println( “Interrupt Caught: “ + ++i );
state = mybutton.read();
// We can catch multiple simultaneous presses
if (mybutton.isButton1()) {
System.out.println( “Keypad:                    “ + mykeypad.readKey() );
}
if (mybutton.isButton2()) {
System.out.println( “Button: 2” );
}
if (mybutton.isButton3()) {
System.out.println( “Button: 3” );
}
if (mybutton.isButton4()) {
System.out.println( “Button: 4” );
}
mybutton.clear();
if (i > 9) { System.exit(0); }
}
public static void main(String[] args) throws TooManyListenersException
{
myKeypad interrupt = new myKeypad();
interrupt.init();
while (true) {
// do nothing
}
}
}

Compile this program:
C:\> cd src
C:\> javac -bootclasspath %TINI_HOME%\bin\tiniclasses.jar
-d ..\bin myKeypad.java
C:\> cd ..
C:\> java  -classpath %TINI_HOME%\bin\tini.jar;. BuildDependency
-p%TINI_HOME%\bin\owapi_dependencies_TINI.jar
-f bin
-x %TINI_HOME%\bin\owapi_dep.txt
-o bin\myKeypad.tini
-d %TINI_HOME%\bin\tini.db

The output of this program looks like this (after some random button and keypad
pressing):
TINI /> java myKeypad.tini
Interrupt Caught: 1
Keypad:                                                                           5
Interrupt Caught: 2
Keypad:                                                                           9
Interrupt Caught: 3

Keypad:                0
Interrupt Caught: 4
Keypad:                5
Button:                2
Button:                3
Interrupt Caught: 5
Keypad:                2
Button:                2
Button:                3
Interrupt Caught: 6
Button:                2
Button:                3
Interrupt Caught: 7
Keypad:                7
Interrupt Caught: 8
Keypad:                5
Interrupt Caught: 9
Keypad:                6
Interrupt Caught: 10
Keypad:                9
TINI />

Much better. We can now identify which button was pressed, and which key on the keypad was pressed, and deal with multiple presses of the same key and also simultaneous presses of several buttons.

Random Posts

Comments are closed.