a little help with keypad on 18f4520 please


Closed Thread
Results 1 to 18 of 18
  1. #1

    Default a little help with keypad on 18f4520 please

    Hi there

    I'm at wit's end ...

    I have been battling to get my matrix keypad(s) working, I have both a 4x3 and a 4x4 keypad.
    Two nights ago I stunbled across some postings and code in the forums which looked like they may be what I am looking for (with a few changes perhaps).

    After trying out both (namely the one from mister e and Steve) I still have not come right and can't understand what I am doing wrong.

    Please see my other posts on mister e's keypad code pages here
    http://www.picbasic.co.uk/forum/show...?t=3250&page=3
    as well as Steve's on this post(hope cross posting is ok):

    http://www.picbasic.co.uk/forum/show...0999#post80999.

    With Steve's implemetation I get only a "||" character on the LCD.

    Attached is my code.

    I am almost convinced I am not setting the registers correctly or calling a variable correctly :-( I was quite happy working with a 16f628 but now that I've re-kindled PIC's as hobby again I decided to go with an 18F series and it's taking some getting used to.

    If some kind soul would help me I would really appreciate it.
    Comments and suggestion or tips and tricks would be more than welcomed too.

    Kind regards

    Dennis
    Code:
    '*************************************
    'LCD code for 16 X 2  HD4x lcd
    '*************************************
    
    'Ocsillator selections here
    OSCCON = $70            'Int CLK 8MHz
    OSCTUNE.6 = 1           'PLL 4x
    ADCON1= %00001111       '$0F = disable A/D converter
    'END of oscillator selections
    
    
    'Port IO directions and presets for port pins begin here
    'TRISA = %11111111       'All pins are outputs
    'TRISB = %00000000           
    'for keypad
    '// Define port pins as inputs and outputs ...
       TRISA  = %00001000
       TRISB  = %00001101
    TRISC = %00000000
    TRISD = %00000000
    TRISE.0 = 0
    TRISE.1 = 0
    TRISE.2 = 0
    'End of Port IO directions and presets for port pins begin here
    
    'timer/oscillator defines 
    DEFINE OSC 32            '4x 8MHz
    'END of timer/oscillator defines
                          
    'variables begin here
    myvar var byte
    
    'LCD defines begin here   
    DEFINE LCD_BITS 4 	'defines the number of data interface lines (4 or 8) 
    DEFINE LCD_DREG PORTD 	'defines the port where data lines are connected to
    DEFINE LCD_DBIT 4 	'defines the position of data lines for 4-bit interface (0 or 4)
    DEFINE LCD_RSREG PORTD 	'defines the port where RS line is connected to
    DEFINE LCD_RSBIT 2 	'defines the pin where RS line is connected to 
    DEFINE LCD_EREG PORTD 	'defines the port where E line is connected to 
    DEFINE LCD_EBIT 3 	'defines the pin where E line is connected 
    DEFINE LCD_RWREG 0 	'defines the port where R/W line is connected to (set to 0 if not used)
    DEFINE LCD_RWBIT 0 	'defines the pin where R/W line is connected to (set to 0 if not used)
    DEFINE LCD_COMMANDUS 2000 	'defines the delay after LCDOUT statement 
    DEFINE LCD_DATAUS 200 		'delay in micro seconds
    'END of LCD DEFINES
    
    'keypad code here
     '// 3x3 Keypad - Rows as inputs, Cols as outputs...
       'Rows: RA3      Cols: RB1                     
       '      RB3            RA2                      
       '      RB2            RA4                      
       '      RB0                                     
       '//
       ' RB5: LED & Buzzer ...                            
       ' RA0: TX to PC's Serial Port                  
            
                        
       '// Declare Variables...
       Col_A     VAR PORTB.1
       Col_B     VAR PORTA.2
       Col_C     VAR PORTA.4
       
       Row_A     VAR PORTA.3
       Row_B     VAR PORTB.3
       Row_C     VAR PORTB.2
       Row_D     VAR PORTB.0
      
       Buzzer    VAR PORTB.5
       RX_To_PC  VAR PORTA.0
        
       Scan_Col  VAR BYTE       ' Counter - denoting current col in scan 
       Key_Press VAR BYTE       ' Contains value of key (0-9) & * + #
       Key_Down  VAR BYTE       ' Flag set true when key is depressed
       Allow_Key VAR BYTE       ' Flag - disallow multiple keys being pressed
       I         VAR byte       ' General working var
        
       Scan_Keypad:
       
       '// Scan cols 
          @ incf _Scan_Col, 1   ' Inc col pos...
        
          SELECT CASE Scan_Col  ' Col (1-3)
                 
                 CASE 1
                      Col_A = 0 ' Switch on col (active low)    
                      Col_B = 1 ' Col off    
                      Col_C = 1 ' Col off   
                               
                      '// 3 Key
                               IF Row_A = 0 THEN        ' Key down? ... 
                                  IF Allow_Key = 0 THEN ' Any other key down?
                                     Key_Press = 3      ' Load var w/value of key           
                                     Allow_Key = 1      ' Disallow other keys
                                  ENDIF   
                               ENDIF                          
                      '// 6 Key
                               IF Row_B = 0 THEN
                                  IF Allow_Key = 0 THEN 
                                     Key_Press = 6                 
                                     Allow_Key = 1
                                  ENDIF   
                               ENDIF
                      '// 9 Key
                               IF Row_C = 0 THEN
                                  IF Allow_Key = 0 THEN 
                                     Key_Press = 9                 
                                     Allow_Key = 1
                                  ENDIF   
                               ENDIF
                      '// # Key
                               IF Row_D = 0 THEN
                                  IF Allow_Key = 0 THEN 
                                     Key_Press = 35                 
                                     Allow_Key = 1
                                  ENDIF   
                               ENDIF
                      
                 CASE 2
                      Col_A = 1    
                      Col_B = 0    
                      Col_C = 1    
                               
                      '// 2 Key
                               IF Row_A = 0 THEN
                                  IF Allow_Key = 0 THEN 
                                     Key_Press = 2                 
                                     Allow_Key = 1
                                  ENDIF   
                               ENDIF
                      '// 5 Key
                               IF Row_B = 0 THEN
                                  IF Allow_Key = 0 THEN 
                                     Key_Press = 5                 
                                     Allow_Key = 1
                                  ENDIF   
                               ENDIF
                      '// 8 Key 
                               IF Row_C = 0 THEN
                                  IF Allow_Key = 0 THEN 
                                     Key_Press = 8                 
                                     Allow_Key = 1
                                  ENDIF   
                               ENDIF
                      '// 0 Key
                               IF Row_D = 0 THEN
                                  IF Allow_Key = 0 THEN 
                                     Key_Press = 0                 
                                     Allow_Key = 1
                                  ENDIF   
                               ENDIF
    
                 CASE 3
                      Col_A = 1     
                      Col_B = 1     
                      Col_C = 0
    
                      '// 1 Key
                               IF Row_A = 0 THEN
                                  IF Allow_Key = 0 THEN 
                                     Key_Press = 1                 
                                     Allow_Key = 1
                                  ENDIF   
                               ENDIF
                      '// 4 Key
                               IF Row_B = 0 THEN
                                  IF Allow_Key = 0 THEN 
                                     Key_Press = 4                 
                                     Allow_Key = 1
                                  ENDIF   
                               ENDIF
                       '// 7 Key
                              IF Row_C = 0 THEN
                                  IF Allow_Key = 0 THEN 
                                     Key_Press = 7                 
                                     Allow_Key = 1
                                  ENDIF   
                               ENDIF
                      '// * Key
                               IF Row_D = 0 THEN
                                  IF Allow_Key = 0 THEN 
                                     Key_Press = 42                 
                                     Allow_Key = 1
                                  ENDIF   
                               ENDIF
                           end select
    'end keypad code
    
    '*********************Includes******
    
    'Includes end here
    
    
    
    
       Pause 500       ' Wait for LCD to startup
    
    'loop1:   
     '  Lcdout $fe, 1   ' Clear LCD screen
      '  Lcdout "Hello"  ' Display Hello
       'Pause 1000       ' Wait .5 second
       'Lcdout $fe, $C0   ' Clear LCD screen
       'Lcdout "World"
       'pAUSE 1000
       'Lcdout $fe, 1   ' Clear LCD screen
       
       'Pause 1000       ' Wait .5 second
    
     'Goto loop1       ' Do it forever
     
    'start:
    '@ READKEYPAD _myvar
    'lcdout $fe, 1
    lcdout Key_Press
    'goto start

  2. #2


    Did you find this post helpful? Yes | No

    Default

    OKay I have even tried this example
    http://www.rentron.com/serkey16.htm
    and still get || on my lcd but the display does hange to things like ||| when I press some keys.

    I really can't see where I am messing up ... please please could someone help me with this

  3. #3
    Join Date
    May 2008
    Location
    Italy
    Posts
    825


    Did you find this post helpful? Yes | No

    Default

    Tray to use LCDout Dec Key_Press and see if you get the correct ascii value.

    Al.
    Last edited by aratti; - 20th November 2009 at 15:30.
    All progress began with an idea

  4. #4


    Did you find this post helpful? Yes | No

    Default

    Thanks Al

    I now see numbers and not ||

    OK so this is how I am now setup ...
    http://www.rentron.com/serkey16.htm
    notice there are no pull-ups on the rows.

    I have series resistors on for the columns (100 OHM)
    In other words KEYPAD >> RESISTOR >> PIC (PortB4-7)
    Aah at least I am now seeing characters
    When Idle the LCD just displays 4 8 12 and the 16 and then it repeats :-(
    What's wrong :-(

    My wishlist
    A schematic( where to wire the pull-ups and where to wire the pull downs.
    I would prefer not to use Port.B since I have the pickit 2 setup for ICSP on PortB.6 and B.7.
    So which ports are advisable to use ? How should I TRIS each ?

    Some code shows keypad ports as input tohers as output ... some show pull-ups others show no pull-ups ?

    This is getting mega confusing

    Should I just stick with dipswitches and give up on the dream of using a keypad for input ?

    Any more help or comments would be seriously appreciated

  5. #5
    Join Date
    May 2008
    Location
    Italy
    Posts
    825


    Did you find this post helpful? Yes | No

    Default

    OK so this is how I am now setup ...
    http://www.rentron.com/serkey16.htm
    notice there are no pull-ups on the rows.
    You don't see any pullup because they are using internal pullup on portB

    See the instruction that activate the weak pullup in the code.

    OPTION_REG.7 = 0 ' Enable PORTB pull-ups

    If you use different port then you have to use external resistors.

    Al.
    All progress began with an idea

  6. #6


    Did you find this post helpful? Yes | No

    Default

    Hi again Al

    Thank you again for the reply :-)

    Adding OPTION_REG.7 = 0 ' Enable PORTB pull-ups
    Shows a compile error in Microstudio
    Does not compile
    I am using an 18F4520

    So I am back to square one

    Any suggestions

  7. #7
    Join Date
    Dec 2007
    Location
    Finland
    Posts
    191


    Did you find this post helpful? Yes | No

    Post

    Code:
    INTCON2.7 = 0     'switch pull-ups ON
    "Each of the PORTB pins has a weak internal pull-up. A single control bit can turn on all the pull-ups. This is performed by clearing bit, RBPU (INTCON2<7>). The weak pull-up is automatically turned off when the port pin is configured as an output. The pull-ups are disabled on a Power-on Reset."
    (Page 96 on PIC18F4520 manual)

    BR,
    -Gusse-
    Last edited by Gusse; - 20th November 2009 at 19:08.

  8. #8
    Join Date
    May 2008
    Location
    Italy
    Posts
    825


    Did you find this post helpful? Yes | No

    Default

    Adding OPTION_REG.7 = 0 ' Enable PORTB pull-ups
    Shows a compile error in Microstudio
    Does not compile
    I am using an 18F4520
    Dennis not all pic has the internal pullup, could be that your mcu has not pullup.
    (Check the datasheet).



    Since you will need the pullups (otherwise the keypad will not work), so add four external 10K resistors.

    Al.

    Edit:

    Gusse has read the datasheet for you: Replace OPTION_REG.7 = 0 with INTCON2.7 = 0
    Last edited by aratti; - 20th November 2009 at 19:16.
    All progress began with an idea

  9. #9


    Did you find this post helpful? Yes | No

    Post Thank you

    Al, Gusse
    Thank you both I implemented mister e's keypad using the whole of port B as an input had to perform some pin swaps on row and column order and it's working .
    I have two more questions :

    1.How do I set the keys to display the correct characters as per the keypad
    my matrix key's are labeled is as follows:

    1 2 3 A
    4 5 6 B
    7 8 9 C
    * 0 # D

    but when I press the keys for example 1,2,3,A
    My readout is 1,2,3,4

    Would I have to do a lookup or re-assignment ?

    2. How do i capture a number ending with a hash for example

    The reason I am asking is because I would like to type in a number for example 135 end it with a # to signify an enter and then store and send the number (TX).

    Any further help would be appreciated

  10. #10
    Join Date
    May 2008
    Location
    Italy
    Posts
    825


    Did you find this post helpful? Yes | No

    Default

    1 2 3 A
    4 5 6 B
    7 8 9 C
    * 0 # D

    but when I press the keys for example 1,2,3,A
    My readout is 1,2,3,4

    Would I have to do a lookup or re-assignment ?
    I am not familiar with mister e's keypad program, but if you get the sequence from 1 to 16, then use an array to code out what you need.

    Code:
    Kp_Array    var byte [17]
    
    
    Kp_Array[1] = "1"
    Kp_Array[1] = "2"
    .
    .
    .
    Kp_Array[15] = "#"
    Kp_Array[16] = "D"
    2. How do i capture a number ending with a hash for example
    If Kp_Array[keypress] = "#" then ........


    Al.
    All progress began with an idea

  11. #11


    Did you find this post helpful? Yes | No

    Default

    Thanks again for the tip Al :-)

    I was thinking along the same lines although I don't think this is exactly what I'm after.
    You see the keypad code only allows for a single keypress at a time at the moment.
    So the largest number you can type in is 16 (the highest key on the keypad)
    I want to be able to type in a number like 124 and end it with a #
    So this number (the actual number 124) can be transmitted.
    If you could imagine a cellphone or cordless landline...
    As you type in the numbers on the keypad you can see them on the screen and then you press dial or possibly C(clear or *) to backspace one digit.
    And when you are happy with the number on screen you press dial (in my case #) then your number is dialled (in my case TX'd)

    Does this make sense ?

    Kind regards
    Dennis

  12. #12
    Join Date
    May 2008
    Location
    Italy
    Posts
    825


    Did you find this post helpful? Yes | No

    Default

    I want to be able to type in a number like 124 and end it with a #
    So this number (the actual number 124) can be transmitted.
    If you could imagine a cellphone or cordless landline...
    As you type in the numbers on the keypad you can see them on the screen and then you press dial or possibly C(clear or *) to backspace one digit.
    And when you are happy with the number on screen you press dial (in my case #) then your number is dialled (in my case TX'd)
    So that means that now the keypad works correctly, and when you press the wanted key you obtain the correct caracter.

    To acheive what you want, you will need an additional array and a few variables:

    The array will retain the numbers you key in and a variable should keep track of the number of time you have pressed the keys.

    Here a snippet



    Code:
    Ratain         var byte
    Ret_Char     var byte [10]
    Ret_Count   var byte
    Ret_Prnt      var byte
    Ret_Clst       var byte
    
    Ret:Prnt = "#"
    Ret_Clst = "*"
    
    Loop:
    Ret_Char[Ret_Count]=Key_Char ' here you transfer the char of the key pressed
    
    If Retain = 0 then ' Retain is a flag then if set will do your job 
    Hserout [Ret_Char[Ret_Count]]
    else
    
    If Ret_Char[Ret_Count] = Ret_Clst then ' if key = "*" then step-back counter
    Ret_Count = Ret_Count - 1
    goto Clear_Count
    endif
    
    If  Ret_Char[Ret_Count] = Ret_Prnt then ' if key = "#" then send string
    Hserout [str Ret_Char \ Ret_count-1]
    RetCount = 0
    goto Clear_Count
    endif
    Ret_Count = Ret_Count + 1
    Clear_Count:
    endif
    return
    I set the array Ret_Char to 10 elements, if you need more then adjiust it for your need. The snippet is not tested so some adjustment could be necessary.

    Al.
    Last edited by aratti; - 21st November 2009 at 20:02.
    All progress began with an idea

  13. #13


    Did you find this post helpful? Yes | No

    Default almost spot on !!

    Al

    :-)
    WOW thank you ... wasn't expecting you to code it for me :-)

    The array idea is perfect for capturing the keypresses and also the option to loop until we see a # or *

    The code snippet raises a few questions though....

    On receipt of a # it sends off a string of characters (those encountered before the #..not so ?
    For example I key in 134#
    First keypress to first variable in the array [1]
    Second to the second variable [3]
    Third to third variable [4]

    Then the # is encountered and we do an hserout

    Will we send a total of a 3 character string using hserout (in other words 24bits)

    Apologies if I have the workings of the code wrong ...I am not clued up on the workings of hserout yet but I am reading up.

    Once again any suggestions or guidance would be appreciated.

    Kind regards

    Dennis

  14. #14
    Join Date
    May 2008
    Location
    Italy
    Posts
    825


    Did you find this post helpful? Yes | No

    Default

    Then the # is encountered and we do an hserout

    Will we send a total of a 3 character string using hserout (in other words 24bits)

    Hserout [str Ret_Char \ Ret_count-1], will send out a string of Ret_count-1 bytes, so "#" will not be sent

    You could use SEROUT2

    SEROUT2,pin,baud,[str Ret_Char \ Ret_count-1]

    or you could use SEROUT

    For A0 = 1 to Ret_count-1
    Serout pin,baud,[Ret_Char [A0]]
    NEXT A0



    Al.
    Last edited by aratti; - 21st November 2009 at 20:05.
    All progress began with an idea

  15. #15


    Did you find this post helpful? Yes | No

    Default Thanks again ...

    Thanks for hserout clairfying the code and the option for serout2.

    Let me re-phrase that last question
    "Then the # is encountered and we do an hserout

    Will we send a total of a 3 character string using hserout (in other words 24bits)"

    So it will be 24 bits ... 134 (0000001 11000000 01000000) as opposed to the 8 bit number 134 (10000110)

    I am after a single 8 bit number , at the end of the key capture
    (or more depending on whether the number keyed in is larger than 255- perhaps I should cap it at 255).

    So perhaps I need to do a little math in the array, perhaps (+) OR-ing ?

  16. #16


    Did you find this post helpful? Yes | No

    Default not compiling and not sure why ?

    Hi Al

    How are you ?

    I am experimenting with your code snippet .. here's what I have so far.
    Code:
    'keypad variables for array keypress capture begin here 
            Retain         var byte
            Ret_Char     var byte [10]
            Ret_Count   var byte
            Ret_Prnt      var byte
            Ret_Clst       var byte
            Ret_Prnt = "#"
            Ret_Clst = "*"
            'keypad capture code begins here
            Ret_Char[Ret_Count]=datatx ' here you transfer the char of the key pressed
    
            If Retain = 0 then ' Retain is a flag then if set will do your job 
            For A0 = 1 to Ret_count -1
            Serout portc.6,T2400,baud,[Ret_Char [A0]]
            NEXT A0
    
            lcdout datatx 'display the variable on the LCD
            pause 1000
            lcdout $fe,1          'clear lcd screen
            else
    
            If Ret_Char[Ret_Count] = Ret_Clst then ' if key = "*" then step-back counter
            Ret_Count = Ret_Count - 1
            goto Clear_Count
            endif
    
            If  Ret_Char[Ret_Count] = Ret_Prnt then ' if key = "#" then send string
            For A0 = 1 to Ret_count -1
            Serout portc.6,T2400,[Ret_Char [A0]]
            NEXT A0
    
            lcdout datatx 'display the variable on the LCD
            pause 1000
            lcdout $fe,1          'clear lcd screen
            RetCount = 0
            goto Clear_Count
            endif
            Ret_Count = Ret_Count + 1
            Clear_Count:
            endif
    goto start
    As i try to compile I encounter an error here
    For A0 = 1 to Ret_count -1

    Not quite sure why ?

    Do you think I could attain the same thing with either a case select statement or a do...while loop ?
    So if I were using a do ... while (or while wend) for example
    do
    keep allowing keypress
    While
    key_press_variable is not equal to '#" 'until we see #

    then serout

    Kind regards
    Dennis

  17. #17
    Join Date
    May 2008
    Location
    Italy
    Posts
    825


    Did you find this post helpful? Yes | No

    Default

    ...... As i try to compile I encounter an error here
    For A0 = 1 to Ret_count -1
    Not quite sure why ?
    Simply because variable A0 has not been declared! Add A0 var Byte to your code.

    While wend loop could work as well, if properly structured.

    Remember you should place two limits: Ret_Count cannot be greater then the array dimension and # command should be ignored if Ret_Count = 0.

    Al.
    Last edited by aratti; - 24th November 2009 at 08:02.
    All progress began with an idea

  18. #18


    Did you find this post helpful? Yes | No

    Default haha

    Al

    I feel a little stupid for missing that obvious one :-)

    Will make the change and feedback asap :-)

    Stay tuned :-)

    And once again thanks for the reply and help :-)

    Kind regards
    Dennis

Similar Threads

  1. 4x4 keypad Help
    By aaliyah1 in forum mel PIC BASIC Pro
    Replies: 6
    Last Post: - 5th October 2010, 16:34
  2. Universal Keypad System
    By aratti in forum Code Examples
    Replies: 3
    Last Post: - 18th January 2009, 13:06
  3. Keypad input test
    By Kalind in forum mel PIC BASIC Pro
    Replies: 9
    Last Post: - 8th October 2008, 04:00
  4. Need help in matrix keypad coding
    By rano_zen06 in forum mel PIC BASIC Pro
    Replies: 15
    Last Post: - 24th May 2008, 13:16
  5. Inconsistent output on a 4x4 matrix keypad
    By markcadcam in forum mel PIC BASIC Pro
    Replies: 12
    Last Post: - 24th November 2006, 03:54

Members who have read this thread : 0

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts