Status
Not open for further replies.

#### be80be

##### Well-Known Member
I been trying to get a keypad to work on porta because I need portb for pwm. The reading of the keys work. But I've been trying to save how many keys was pressed and can't for the life of me get it to. What I'm trying to do
is count to see if key8 was pressed 4 times in a row. thanks for any help
Code:
Device = 18F1220
Clock = 8
Config OSC = INTIO2
Config MCLRE = OFF
Include "INTOSC8.bas"
Dim counter As Word
Dim key1 As Bit
Dim key2 As Bit
Dim key3 As Bit
Dim key4 As Bit
Dim key5 As Bit
Dim key6 As Bit
Dim key7 As Bit
Dim key8 As Bit
Dim key9 As Bit
Dim key10 As Bit
Dim key11 As Bit
Dim key12 As Bit
Dim col1 As PORTA.0
Dim col2 As PORTA.1
Dim col3 As PORTA.2
Dim roll1 As PORTA.3
Dim roll2 As PORTA.4
Dim roll3 As PORTA.6
Dim roll4 As PORTA.7
Dim out0 As PORTB.0
Dim out1 As PORTB.1
SetAllDigital
Input (roll1)
Input (roll2)
Input (roll3)
Input (roll4)
Output (col1)
Output (col2)
Output (col3)
Output (PORTB.1)
Output (PORTB.0)

counter = 0
While true
High (col1) Low (col2) Low (col3)      // col 1       this scans keys
If col1 = 1 And col2 =0 And col3 = 0 And roll1 = 1 Then
key1 = 1
Else
key1 =0
EndIf
High (col1) Low (col2) Low (col3)
If col1 = 1 And col2 =0 And col3 = 0 And roll2 = 1 Then
key2 = 1
Else
key2 = 0
EndIf
High (col1) Low (col2) Low (col3)
If col1 = 1 And col2 =0 And col3 = 0 And roll3 = 1 Then
key3 = 1
Else
key3 = 0
EndIf
High (col1) Low (col2) Low (col3)
If col1 = 1 And col2 =0 And col3 = 0 And roll4 = 1 Then
key4 = 1
Else
key4 = 0
EndIf
Low (col1) High (col2) Low (col3)         // col 2
If col2 = 1 And col1 =0 And col3 = 0 And roll1 = 1 Then
key5 = 1
Else
key5 = 0
EndIf
Low (col1) High (col2) Low (col3)
If col2 = 1 And col1 =0 And col3 = 0 And roll2 = 1 Then
key6 = 1
Else
key6 = 0
EndIf
Low (col1) High (col2) Low (col3)
If col2 = 1 And col1 =0 And col3 = 0 And roll3 = 1 Then
key7 = 1
Else
key7 =0
EndIf
Low (col1) High (col2) Low (col3)
If col2 = 1 And col1 = 0 And col3 = 0 And roll4 = 1 Then
key8 = 1
Else
key8 = 0
EndIf
Low (col1) Low(col2) High (col3)         // col 3
If col3 = 1 And col1 =0 And col1 = 0 And roll1 = 1 Then
key9 = 1
Else
key9 = 0
EndIf
Low (col1) Low (col2) High (col3)
If col3 = 1 And col2 =0 And col1 = 0 And roll2 = 1 Then
key10 = 1
Else
key10 = 0
EndIf
Low (col1) Low (col2) High (col3)
If col3 = 1 And col2 =0 And col1 = 0 And roll3 = 1 Then
key11 = 1
Else
key11 = 0
EndIf
Low (col1) Low (col2) High (col3)
If col3 = 1 And col2 =0 And col1 = 0 And roll4 = 1 Then
key12 = 1
Else
key12 = 0
EndIf
Low (out1)
Low (out0)
If key8 = 1 Then        // lights a led if key8 is pressed
Toggle (out0)       //
EndIf
If key8 = 1 And out0 = 1 And counter < 0 Then     // this is what I can't get to work
Inc (counter)          // the counter dosn't change value
EndIf
If counter = 4 Then         // should hit 4 and turn on the led
High (out1)
EndIf
Wend

#### Pommie

##### Well-Known Member
I can't see how counter could ever get less than zero.

Code:
If key8 = 1 And out0 = 1 And [COLOR="Red"]counter < 0 [/COLOR]Then
Mike.

#### be80be

##### Well-Known Member
I tried it like this it still don't count the presses
Code:
    Low (out1)
Low (out0)
If key8 = 1 Then        // lights a led if key8 is pressed
Toggle (out0)       //
EndIf
If key8 = 1 And out0 = 1 And counter < 4 Then     // this is what I can't get to work
Inc (counter)          // the counter dosn't change value
DelayMS(10)
While key8 = 1 Wend

EndIf
If counter = 4 Then         // should hit 4 and turn on the led
High (out1)
EndIf
Wend
The funny thing here is I can toggle and with any of the 12 keys but can't count just one key to see how many times it was pressed and if that one key and only that key got pressed four times in a row it lights led out1

Last edited:

#### mister_e

##### New Member
You will run into problem if you don't disable the ADCs on PORTA.

Be careful with 18F, you want to write to LAT instead of PORT.

#### blueroomelectronics

##### Well-Known Member
SetAllDigital turns off the A/D, it's already in be80be's code.

#### mister_e

##### New Member
Well yes, but no INCLUDE "Utils.bas".. has to be a copy/paste mistake then

Code:
Low (col1) Low (col2) High (col3)
ok this compile, you have quite a few in your code, but does it really work as expected?

I figure the compiler could use only the first High/Low, then discard the other.

#### be80be

##### Well-Known Member
I have
INCLUDE "Utils.bas"
I remove some of the include i had in it. that where commented out and removed it too The code works find if you just want it to read a a key. I can set it so that any key pressed is a 1 and it will count the key presses. But if I want to count just one key it will not count and it's on porta which it hard to do any way. Because no pullups on porta. I even use it to output the binary
number of the key to portB and all 12 work find. I don't get it it should count the key going high.

#### be80be

##### Well-Known Member
I got to thinking about what you where saying and change it to this still don't work with the counting is there a easy way to do this
Code:
  keypress = (key1)Or(key2)Or(key3)Or(key4)Or(key5)Or(key6)Or(key7)Or(key8)Or(key9)Or(key10)Or(key11)Or(key12)
Code:
Device = 18F1220
Clock = 8
Config OSC = INTIO2
Config MCLRE = OFF
Include "INTOSC8.bas"
Include "Utils.bas"
Dim keypress As Bit
Dim counter As Byte
Dim key1 As Bit
Dim key2 As Bit
Dim key3 As Bit
Dim key4 As Bit
Dim key5 As Bit
Dim key6 As Bit
Dim key7 As Bit
Dim key8 As Bit
Dim key9 As Bit
Dim key10 As Bit
Dim key11 As Bit
Dim key12 As Bit
Dim col1 As PORTA.0
Dim col2 As PORTA.1
Dim col3 As PORTA.2
Dim roll1 As PORTA.3
Dim roll2 As PORTA.4
Dim roll3 As PORTA.6
Dim roll4 As PORTA.7
Dim out0 As PORTB.0
Dim out1 As PORTB.1
SetAllDigital
Input (roll1)
Input (roll2)
Input (roll3)
Input (roll4)
Output (col1)
Output (col2)
Output (col3)
Output (PORTB.1)
Output (PORTB.0)
keypress = 0
counter = 0
While true
High (col1) Low (col2) Low (col3)      // col 1       this scans keys
If col1 = 1 And col2 =0 And col3 = 0 And roll1 = 1 Then
key1 = 1
Else
key1 =0
EndIf

If col1 = 1 And col2 =0 And col3 = 0 And roll2 = 1 Then
key2 = 1
Else
key2 = 0
EndIf

If col1 = 1 And col2 =0 And col3 = 0 And roll3 = 1 Then
key3 = 1
Else
key3 = 0
EndIf

If col1 = 1 And col2 =0 And col3 = 0 And roll4 = 1 Then
key4 = 1
Else
key4 = 0
EndIf
Low (col1) High (col2) Low (col3)         // col 2
If col2 = 1 And col1 =0 And col3 = 0 And roll1 = 1 Then
key5 = 1
Else
key5 = 0
EndIf

If col2 = 1 And col1 =0 And col3 = 0 And roll2 = 1 Then
key6 = 1
Else
key6 = 0
EndIf

If col2 = 1 And col1 =0 And col3 = 0 And roll3 = 1 Then
key7 = 1
Else
key7 =0
EndIf

If col2 = 1 And col1 = 0 And col3 = 0 And roll4 = 1 Then
key8 = 1
Else
key8 = 0
EndIf
Low (col1) Low(col2) High (col3)         // col 3
If col3 = 1 And col1 =0 And col1 = 0 And roll1 = 1 Then
key9 = 1
Else
key9 = 0
EndIf

If col3 = 1 And col2 =0 And col1 = 0 And roll2 = 1 Then
key10 = 1
Else
key10 = 0
EndIf

If col3 = 1 And col2 =0 And col1 = 0 And roll3 = 1 Then
key11 = 1
Else
key11 = 0
EndIf

If col3 = 1 And col2 =0 And col1 = 0 And roll4 = 1 Then
key12 = 1
Else
key12 = 0
EndIf
Low (out1)
Low (out0)
If keypress = 1 Then        // lights a led if key8 is pressed
Toggle (out0)       //
EndIf
keypress = (key1)Or(key2)Or(key3)Or(key4)Or(key5)Or(key6)Or(key7)Or(key8)Or(key9)Or(key10)Or(key11)Or(key12)
If keypress = 1 And out0 = 1 And counter < 4 Then     // this is what I can't get to work
Inc (counter)          // the counter dosn't change value
DelayMS(10)

EndIf
If counter = 4 Then         // should hit 4 and turn on the led
High (out1)
EndIf
Wend

#### Pommie

##### Well-Known Member
Your code is hard to follow,
Why do you test out0, try changing the line to
Code:
If keypress = 1 And counter < 4 Then
However, counter will get to 4 very quickly as you don't test for no key pressed.

Mike.

#### be80be

##### Well-Known Member
I can't see why it is not counting it still jumps to 4
And I have tried every thing I can think of .
I thought I was
you don't test for no key pressed
Code:
 If keypress = 1 And counter < 4 Then     // this is what I can't get to work
delayms(20)
high (out0)
Inc (counter)
elseif keypress = 0 then
low (out0)
EndIf

If counter = 4 Then         // should hit 4 and turn on the led
High (out1)
EndIf
Is there a easy way to do this
Code:
keypress = (key1)Or(key2)Or(key3)Or(key4)Or(key5)Or(key6)Or(key7)Or(key8)Or(key9)Or(key10)Or(key11)Or(key12)
Thanks mike I would use the swordfish keypad module but it don't work on PORTA.
P.S would you show me how to stop if from jumping to four you no I'm dum as coal bucket.

I was thinking this was doing the no keypress checking
Code:
If col3 = 1 And roll4 = 1 Then
key12 = 1
Else
key12 = 0

Last edited:

#### Pommie

##### Well-Known Member
I think I can see what you were trying to do with out0.

To use out0 as a flag you could do,

Code:
    If keypress = 1 And out0=0 Then     // this is what I can't get to work
delayms(20)
high (out0)
if counter < 4 then
Inc (counter)
endif
elseif keypress = 0 and out0=1 then
delayms(20)
low (out0)
EndIf
It's not very elegant but should work.

Mike.

#### be80be

##### Well-Known Member
I was trying to count the led when it went high I had it working like that but my video card went bad and the computer turn off and I lost what I had done. Now I can't get it to count at all I tried that code.
with the delay's it takes to long to read the key I removed them and it blinks led out0
and turns on out1 all most as fast as I pressed the key. whats a good way to count
a event like the port pin going high
Code:
If led0 = 1 and count<4 then   // This should test led0 for high and see what count is
inc (count)      // this should inc by one value in count
low (led0)      // this should turn off the led0
endif
If count = 4 then   // this should test count for 4
high (led1)
endif

#### Pommie

##### Well-Known Member
with the delay's it takes to long to read the key I removed them and it blinks led out0 and turns on out1 all most as fast as I pressed the key.
If the delay is too long then your oscillator isn't running at the right speed. Try adding OSCCON=$72 to the init code. Mike. #### be80be ##### Well-Known Member Porta isn't for a keypad I don't think I had a keyscan code that I didn't post maybe you can see what I'm missing with it Code: Function KeyValue() As Byte Result = 0 For Counter = 0 To 2 setkeypad = %11111000 //sets tris inputs and outputs keypad = %00000000 //sets all pins low porta = keypad trisa = setkeypad keypad.Bits(Counter) = 1 If porta.3 = 0 And PORTB.4 = 0 And PORTB.6 = 0 And PORTB.7 = 0 Then // Check if any Rows are "High" ColData = Counter If keypad.3 = 1 Then RowData = 1 ElseIf keypad.4 = 1 Then RowData = 4 ElseIf keypad.6 = 1 Then RowData = 7 ElseIf keypad.7 = 1 Then RowData = 10 EndIf Result = ColData + RowData Break EndIf Next End Function while true portb = KeyValue wend end Last edited: #### be80be ##### Well-Known Member I got the keyscan code to work I didn't have mclr off was why it would read wrong Code: Device = 18F1220 Clock = 8 Config OSC = INTIO2 Config MCLRE = OFF Include "INTOSC8.bas" Include "Utils.bas" // local duty variable... #option KEYPAD_PORT = PORTA Include "Keypad12.bas" Dim Key As Byte SetAllDigital trisb =%00000000 portb =%00000000 While True // wait for a key to be pressed, then send it via uart Key = 0 While Key = 0 Key = Keypad12.Value Wend PORTB = Key // wait for the user to release the key Keypad12.Debounce Wend Last edited: #### be80be ##### Well-Known Member I was trying to save the first 4 key presses I have the keypad module working on PortA It works find I put 8 leds on PortB and the value of the led is output to PortB It give the value 1 to 12 just like It should This is the thing if I test to see if the key is say a 1 I get a 1 with out pressing the key one. Maybe you can tell me what I'm doing wrong Code: Dim a AS Byte // to save four key presses Dim b AS Byte Dim c AS Byte Dim d AS Byte If key >0 Then // test to see if a key was pressed a = key // should make a have the value of key and put it in a EndIF If key >0 Then // test to see if a key was pressed b = key // should make a have the value of key and put it in b EndIF If key >0 Then // test to see if a key was pressed c = key // should make a have the value of key and put it inc EndIF If key >0 Then // test to see if a key was pressed d = key // should make a have the value of key and put it d EndIF This put the same value in all not what I want. Maybe some way to put four new key presses in a,b,c,d I hope so. I done this 100 ways and no go LOL. thanks Last edited: #### be80be ##### Well-Known Member How do you get the value from a array 1 at a time Code: Device = 18F1220 Clock = 8 Config OSC = INTIO2 Config MCLRE = OFF Include "INTOSC8.bas" Include "Utils.bas" // local duty variable... Include "Keypad12.bas" Dim Key(4) As Byte Dim Counter As Byte SetAllDigital TRISB =%00000000 PORTB =%00000000 While True Counter = 0 For Counter = 0 To 3 // loop 4 times While Keypad12.Value = 0 // wait for key press Wend Key(Counter) = Keypad12.Value // grab key value Keypad12.Debounce // debounce the key Next Counter = 0 For Counter = 0 To 3 // this out put the Binary value to portB PORTB = Key(Counter) delayms (500) Next Wend I have tryed evey thing in the book all i want to do is save 4 key press so I can check them to see if there right #### Pommie ##### Well-Known Member Most Helpful Member Can you post the keypad12.bas file? As a quick guess you may need, Code: Repeat Key(Counter) = Keypad12.Value // grab key value until Key(Counter)<>0 However, I don't see how this calls the key scan routine unless it is interrupt driven. Mike. #### be80be ##### Well-Known Member The keypad12 module works with the code I posted And digital-diy wrote the code to use it with USART. But if I try to get the value of the saved keys I can't but I can output it to portb like in my code and it lights the leds with the Binary value for what key I have pressed one at a time for the 4 that it saved. See I need to no what four keys have been pressed and that only four have been pressed here the keypad module Code: Module Keypad12 { Column1 = PORTX.0 Column2 = PORTX.1 Column3 = PORTX.2 PORTX.3 NC Row1 = PORTX.4 Row2 = PORTX.5 Row3 = PORTX.6 Row4 = PORTX.7 } // validate data port... #option KEYPAD_PORT = PORTA #if IsOption(KEYPAD_PORT) #if Not IsValidPort(KEYPAD_PORT) #error KEYPAD_PORT, "Invalid option. Keypad must be connected to a valid port name." #endif #option _KEYPAD_PORT_TRIS = GetTRIS(KEYPAD_PORT) #endif // bring PORT and TRIS options into the module Dim FKeyPort As KEYPAD_PORT, FKeyPortTris As _KEYPAD_PORT_TRIS Public Function Value() As Byte Dim Counter As Byte Dim RowData As Byte Dim ColData As Byte Result = 0 For Counter = 0 To 2 // FKeyPortTris =$FF              // Make all pins inputs
FKeyPortTris.Bits(Counter) = 0  // Make a single Column an output
FKeyPort.Bits(Counter) = 1      //  and set it high

If (FKeyPort >> 4) <> 0 Then    // Check if any Rows are "High"
Coldata = Counter
If FKeyPort.4 = 1 Then
RowData = 1
ElseIf FKeyPort.5 = 1 Then
RowData = 4
ElseIf FKeyPort.6 = 1 Then
RowData = 7
ElseIf FKeyPort.7 = 1 Then
RowData = 10
EndIf
Result = Coldata + RowData
Break
EndIf
Next
End Function

Public Sub Debounce()

While Keypad12.Value <> 0           // Check if key is pressed
DelayMS(10)                     // Wait for 10mS
Wend

End Sub

FKeyPortTris = \$FF              // Make all pins inputs

End

#### Pommie

##### Well-Known Member
So, what you are saying is the code you posted earlier works and some other code doesn't.

Could I suggest that you post the code that doesn't work.

Mike.

Status
Not open for further replies.