• Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Keypad on porta 18f1220

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
:confused:
 

Pommie

Well-Known Member
Most Helpful 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.
 

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
Most Helpful 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
Most Helpful 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
Most Helpful 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
Most Helpful 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.:D

Mike.
 
Status
Not open for further replies.

Latest threads

EE World Online Articles

Loading
Top