PDA

View Full Version : Storm 1000 Keypad PIC Interface help please



digilord
- 29th December 2005, 21:33
Hello All,
I have a Storm 1000 12 key keypad. It's setup as a matrix. I setup my PIC (16F88) with port A as 3 outputs and 4 inputs. Here is my code:



'************************************************* ***************
'* Name : Keypad.BAS *
'* Author : Daniel Morrigan *
'* Notice : Copyright (c) 2005 Daniel Morrigan *
'* : All Rights Reserved *
'* Date : 12/29/2005 *
'* Version : 1.0 *
'* Notes : *
'* : *
'************************************************* ***************
' Boot loader is used
DEFINE LOADER_USED 1

' Oscilator timing is set for 8Mhz
DEFINE OSC 8

' Set Baud Rate
DEFINE HSER_BAUD 9600

' Clear UART overflow error
DEFINE HSER_CLROERR 1

' Enable transmit and receive
DEFINE HSER_RCSTA 90h
DEFINE HSER_TXSTA 20h

' Set port A for digital inputs & outputs
ANSEL=0
CMCON=0
trisa.2=1
trisa.3=1
trisa.4=1
trisa.0=0
trisa.1=0
trisa.6=0
trisb.0=0

' Setup Rows & Cols for the keypad reader
C1 VAR porta.4
C2 VAR porta.3
C3 VAR porta.2

RA VAR porta.0
RB VAR portb.0
RC VAR porta.6
RD VAR porta.1

' Setup a var to store the value of the key pressed
key var word
' Set the columns to be low
Low c1
low C2
Low C3

Pause 500

loop:
High C1 ' Bring col 1 high & look for each key
pause 100
IF RA then key="7"
if RB then key="4"
if RC then key="1"
if RD then key="*"
Low c1
hserout [key]
High C2 ' Bring col 2 high & look for each key
pause 100
IF RA then key="8"
if RB then key="5"
if RC then key="2"
if RD then key="0"
Low c2
hserout [key]
pause 100
High C3 ' Bring col 3 high & look for each key
IF RA then key="9"
if RB then key="6"
if RC then key="3"
if RD then key="#"
Low c3
hserout [key]
hserout [10,13]
gosub blink ' Blink to let me know we went through an interation
goto loop
end

blink:
High PORTB.3 ' Turn on LED connected to PORTB.3
Pause 1000 ' Delay for 1 seconds


Low PORTB.3 ' Turn off LED connected to PORTB.3
Pause 1000
return


I am not getting what I expected in the output. I am getting random keys. I looked for a similar solution here thinking someone else may have done this in the past.

The rows and cols are setup to interface directly to the buttons.

Any insights?

Darrel Taylor
- 29th December 2005, 22:59
digilord,

That's a very dangerous way to try to read the keypad.

Since you start with all columns having a LOW output, then set the column you're looking at HIGH. If the user presses 2 buttons at the same time, it can create a short between the HIGH and LOW outputs. It'll be a Pretty plume of smoke, but it only does it once.

It's better to have Pull-Up resistors on the ROW's, start with all columns set to INPUT, and then set the column you're looking at LOW. Or that can be reversed ... Pull-Down resistors, start with all columns set to INPUT, and then set the column you're looking at HIGH.

The reason you're getting random results, is due to the lack of Pull-Up's. With the switches open, the ROW input's are floating, and could read either high or low at anytime.
<br>

Bruce
- 30th December 2005, 18:37
I noticed a couple of potential show stoppers.

CMCON = 0 is not disabling the onboard comparators. Use CMCON = 7.

You are setting the 3 column pins up as inputs;

trisa.2=1
trisa.3=1
trisa.4=1
C1 VAR porta.4
C2 VAR porta.3
C3 VAR porta.2

Then immediately flipping them back around to outputs & taking them to ground;

Low C1
Low C2
Low C3

This leaves all 3 column pins set to outputs, and at logic 0.

Then you make all of the row pins outputs;

trisa.0=0
trisa.1=0
trisa.6=0
trisb.0=0

These will now output whatever random values are in the port latches.

Now you have all pins configured as outputs with your 3 column pins at ground, and random logic values on all row outputs.

What probably saved the day was having pins associated with the analog comparators configured as analog inputs due to the wrong value in CMCON.

Try something like this. It isn't anywhere near optimum, but should help get started. It's un tested, but should work.


'************************************************* ***************
'* Name : Keypad.BAS *
'* Author : Daniel Morrigan *
'* Notice : Copyright (c) 2005 Daniel Morrigan *
'* : All Rights Reserved *
'* Date : 12/29/2005 *
'* Version : 1.0 *
'* Notes : *
'* : *
'************************************************* ***************
' Boot loader is used
DEFINE LOADER_USED 1

' Oscilator timing is set for 8Mhz
DEFINE OSC 8

' Set Baud Rate
DEFINE HSER_BAUD 9600

' Clear UART overflow error
DEFINE HSER_CLROERR 1

' Enable transmit and receive
DEFINE HSER_RCSTA 90h
DEFINE HSER_TXSTA 20h

' Setup a var to store the value of the key pressed
key var byte

' Define input & output values for tris regs
IN_PUT CON 1
OUT_PUT CON 0

' Set port A for digital inputs
ANSEL=0 ' disable A/D
CMCON=7 ' disable comparators, pins used for digital I/O

' NOTE: row inputs have 10K pull-ups & sense ground as keypress
trisa.0=1 ' make row pins inputs
trisa.1=1
trisa.6=1
trisb.0=1

' Setup Rows for the keypad reader
C1 VAR porta.4 ' alias C1 pin
C2 VAR porta.3 ' alias C2 pin
C3 VAR porta.2 ' alias C3 pin
C1DIR VAR TRISA.4 ' alias tris for C1 pin
C2DIR VAR TRISA.3 ' alias tris for C2 pin
C3DIR VAR TRISA.2 ' alias tris for C3 pin

' Setup Cols for the keypad reader
RA VAR porta.0
RB VAR portb.0
RC VAR porta.6
RD VAR porta.1

' Set all columns to inputs until key reads.
C1 = 0 ' set all column port latches low
C2 = 0
C3 = 0
C1DIR = IN_PUT ' set all column pins to inputs
C2DIR = IN_PUT ' until keypad scan
C3DIR = IN_PUT

Pause 500

loop:
Key = 0 ' clear key value before scan

' make 1 column at a time output ground.
C1DIR = OUT_PUT ' col1 pin at ground, scan keys
pause 100
IF !RA then key="7" ' test each row for ground
if !RB then key="4"
if !RC then key="1"
if !RD then key="*"
C1DIR = IN_PUT ' col1 pin to high impedance
IF Key THEN GOSUB SendKey ' display only if a key was pressed

C2DIR = OUT_PUT ' col2 pin at ground, scan keys
pause 100
IF !RA then key="8"
if !RB then key="5"
if !RC then key="2"
if !RD then key="0"
C2DIR = IN_PUT ' col2 pin to high impedance
IF Key THEN GOSUB SendKey

pause 100
C3DIR = OUT_PUT ' col3 pin at ground, scan keys
IF !RA then key="9"
if !RB then key="6"
if !RC then key="3"
if !RD then key="#"
C3DIR = IN_PUT ' col3 pin to high impedance
IF Key THEN GOSUB SendKey

gosub blink ' Blink to let me know we went through an interation
goto loop

SendKey:
hserout [key,13,10] ' display key val, cr, lf
Key = 0 ' clear last key value before return
RETURN

blink:
High PORTB.3 ' Turn on LED connected to PORTB.3
Pause 1000 ' Delay for 1 seconds
Low PORTB.3 ' Turn off LED connected to PORTB.3
Pause 1000
return

end
One potential problem is when someone presses more than one key, but you can sort that one out...;o}