How to Build a 10-Key Serial Keypad
Can your next PIC or BASIC Stamp product or project make use of a 10-key serial keypad that requires only a single I/O-pin for the interface...? Read on -------
This project has so many applications that you'll only be limited by your imagination. There are handy new serial devices popping-up for just about everything you can imagine, and making the addition of external peripherals to new microcontroller designs very simple and straight-forward.
The "10-Key" Serial Keypad
It's no big secret that using a single I/O-pin to integrate serial input/output devices can save considerable time & money.
The keypad scan routines used with older matrix keypad designs will often introduce unacceptable noise for some types of circuitry, and can be a big factor to deal with if the primary circuit is highly susceptible to electrical noise.
This basic design doesn't scan rows & columns like you'll often see with other serial matrix keypad ICs. It simply tests the input port occasionally to see if a button has been pressed. There's also a valid data output that can be used to generate an interrupt, and cause program execution to vector to the interrupt handler routine to further simplify the keypad data input firmware.
Another factor that makes this design very desirable is that it uses simple push-button switches. The cost of even the most generic matrix keypad is often prohibitive to new products, and especially the hobbyist or student.
The PIC16C620A was picked for this device for several reasons:
The circuit for the microcontroller/key connections is shown below in figure 1. The design was kept very simple, yet it's very effective at what is does.
The circuit for the serial keypad can easily be built on your bread board or you can design your own circuit boards.
The compiled file size is only 211 words, so there's plenty of room for additional code if your application requires it...!
Note: This code example has been modified considerably from the original version to make reading/understanding how & why it works easy for the beginner. There are many sections of this code that can be modified to be considerably more efficient, but this sample works very well, and is much easier for the beginner to understand.
' Using the PIC16C620A PIC For a serial keypad encoder ' The keypad sends each key number entered out PortA.3 ' serially, with PortA.4 acting as data-available pin. ' Dgood, [PortA.4] will remain high until key is released. ' Dgood will go low immediately after serial data is sent ' on Serpin [PortA.3] define osc 4 include "bs2defs.bas" cmcon = 7 'Port A all I/O [disable comparators]. dgood var porta.2 'Data available pin. serpin var porta.3 'Serial output pin baudin var porta.4 'Baud rate selection pin. nokey con %11111111 'No keys pressed keyin var portb 'Key input port on port B keydata var byte trisb = %11111111 'Port B = all inputs trisa = %00010011 '0,1,4 = inputs, rest outputs key1 var portb.0 key2 var portb.1 key3 var portb.2 key4 var portb.3 key5 var portb.4 key6 var portb.5 key7 var portb.6 key8 var portb.7 key9 var porta.0 key10 var porta.1 '=========== Find the key pressed ========== findkey: if key1 = 0 then press1 if key2 = 0 then press2 if key3 = 0 then press3 if key4 = 0 then press4 if key5 = 0 then press5 if key6 = 0 then press6 if key7 = 0 then press7 if key8 = 0 then press8 if key9 = 0 then press9 if key10 = 0 then press10 goto findkey '=========== Sort em out here ============== press1: keydata = 1 goto dout press2: keydata = 2 goto dout press3: keydata = 3 goto dout press4: keydata = 4 goto dout press5: keydata = 5 goto dout press6: keydata = 6 goto dout press7: keydata = 7 goto dout press8: keydata = 8 goto dout press9: keydata = 9 goto dout press10: keydata = 10 dout: low dgood 'Pulse data good pin PortA.2. pause 100 '100mS delay [software debounce]. wait1: if keyin <> nokey then wait1 'Is key released...? wait2: if key9 = 0 then wait2 if key10 = 0 then wait2 baudselect: if baudin = 1 then fast 'baudin=1 N9600,else N2400 serout serpin,N2400,[keydata]'Key value out PortA.3 goto x2 fast: serout serpin,N9600,[keydata] x2: high dgood keydata = %00000000 'Clear data storage byte variable. goto findkey end
Download the PicBasic Code HERE
How It Works:
The code for Ser-Key is extremely simple, and since the PIC is dedicated to the single function of serving as a keypad encoder, it can simply sit in the key-entry loop findkey all day long until a key has been pressed. The following example shows how it works, and assumes you have pressed key #1
Recognize The Key Press:
The routine findkey uses the basic commands if key1 = 0 then press1. This just checks the state of pin 1 to see if it's been pulled to ground. If it has, then program execution jumps to press1. If key1 (portB.0) is not = 0, then check the remaining keys for a logic 0. If none of the key inputs have been pulled to ground, then loop back to check all pins again until one = 0. The key recognition loop findkey cannot be exited until at least one of the input keys have been pressed.
Load a Value That Represents The Key # Pressed:
Press1 loads the value of 1 into the byte variable storage space named keydata, and then causes program execution to jump to the routine dout.
Inform The Target Microcontroller That Keypad Data Is Available:
The routine dout is assigned the task of informing the main processor using the serial keypad that valid key data is coming. Port-pin A.2 has been assigned as the Data Available Pin. The 10K pull-up resistor makes sure the data-available pin is always seen (by the microcontroller attached to the serial keypad) as a logic 1 (high) until a key has been pressed.
The command pause 100 after the data-available pin has been set to ground offers a 100mS key de-bounce time, and gives the microcontroller using the serial keypad time to vector to the key processing input routine.
The routine wait simply checks to see if portB, keys 1 through 8 are still being pressed. If you hold one of these keys down, wait will not let program execution proceed until you release the key. The byte variable nokey has been pre-assigned a constant value of %11111111. A value of %11111111 returned when the portB pins are read signifies that all of the portB key input pins are being held at a logic 1 (high), and no keys on portB are being pressed.
The portB pins have been re-named using the beginning statement of:
keyinvar portb 'Key input port on port B
The code below simply compares the value of the portB pins to the binary value of %11111111 assigned to nokey. If the portB pins are not equal to the value of nokey, then wait until they do.
if keyin <> nokey then wait1 'Wait for keys to be released.
The next routine wait2 simply checks the logic state of the two remaining key inputs on porta. Key #9 and key #10. if either of these keys is being held at logic 0 (low), then wait until the key is released. Hence:
Will simply loop until you release the keys.
Send The Key Data Out Serially:
The next routine is very simple, but serves several purposes. The pin assigned as baudin determines the actual baud rate that key data will be sent out. If this pin is at a logic 0, then data will be sent out N2400. If this pin is being pulled to a logic 1, then data is sent out faster at N9600.
This makes it simple to change the baud rate on-the-fly. By changing the logic state of the baudin pin you cause program execution to change, and send the serial data out with either of the two baud rates you need. Notice the goto x2. This prevents the key values from being sent out twice, at different baud rates. If the baudin pin was at 0, then program execution falls through to sending out the key data at N2400, and we need to make sure we then jump over the second routine to send out the key data at N9600.
Since the older basic stamp 1 will not do serial transfers higher than 2400, this makes the serial keypad compatible with older basic stamp 1 designs, and can really add some functionality to the severely limited I/O capacity of the basic stamp 1.
Put Things Back To Normal:
The next routine just resets the dgood (data available pin), clears the storage space holding key data, and returns to look for more key entry.
By carefully examining the code, you'll see just how simple the 10-key serial keypad really is. The simplified version of the code is slightly larger than our original version, but it offers the exact same options & flexibility of our original code.
Using PicBasic it's extremely simple to design cheap alternatives to buying expensive control ICs. Motor control ICs for servo/stepper motors, serial LCD controllers and, of course, the serial keypads are just the beginning of what you can create quickly & easily when using the PicBasic Compiler.
Many people just getting into programming microcontrollers are intimidated by the price of PicBasic, but even something as incredibly simple as this serial keypad can pay for the initial investment for the PicBasic Pro Compiler many times over in the first month alone.
The keypad consists of simple, normally-open, push-button switches. The design focus was on easily obtainable, and inexpensive components. Using ordinary push-button switches makes building the serial keypad easy for just about anyone since most people will have several of these type switches lying around collecting dust.
The huge expense of matrix type keypads quickly ruled-out using this type of switch. The additional complexity of wiring or routing for matrix keypads was also another lower design factor that ruled them out all together.
Figure 2 shows the simple switch arrangement for connecting the ten keys to the PIC to complete the serial keypad circuit. The 10K pull-up resistors ensure that when no keys are pressed, the input pins are always at a logic 1 (high).
While it's possible to eliminate these resistors altogether, it's a cheap way to keep external noise introduced into the keypad circuit from causing false key triggering. A 10K pull-up resistor on each input-pin can help eliminate outside noise. If you experiment a little (without) these resistors, you can see how touching the keypad in certain areas will cause the circuit to false-trigger and send key data even when no keys have actually been pressed. A lot of factors can cause this, but that's another complete article to cover this subject appropriately.
The 330-ohm resistor is simply to limit current into each input-pin when buttons are pressed. It's cheap insurance against shorting an I/O-pin directly to ground, and well worth the additional expense. You'll see a few PIC designs not using input protection, but it's much cheaper than replacing the PIC if your code goes haywire and brings the input-pin to a logic 1 (high). This will cause a dead-short to ground, and you'll be looking for a replacement PIC when the smoke clears....;o]
Download The Code:
The primary purpose of our PicBasic projects section is to support & teach people experimenting with, and just starting out with, the PicBasic Compiler. It's isn't our intention to give away pre-compiled code written with PicBasic. This is the reason we only supply the PicBasic code in its RAW, BASIC format.
If you don't own a copy of PicBasic, or just want a pre-programmed PIC16C620A for this project with the 4MHz ceramic resonator, we have these available at: http://www.rentron.com/Ser-Key.htm This page also shows considerably more detail on how Ser-Key functions complete with scope readings, sample BASIC Stamp code to accept serial key-data from Ser-Key and other information.
Did You Find This Project Useful..?
We look forward to your input on the free projects we post here, and rely on input from visitors to help us determine what type of free projects to post next. If you found this project useful, have a good idea for a new project, or would just like to say hello, click HERE to submit your feedback to us.
Until the next project; don't blow anything up, have fun -- and thanks for stopping by....;o]
Copyright © 1999-2008 Reynolds Electronics