Keypad.bas issue

General discussion relating to the library modules supplied with the compiler

Moderators: David Barker, Jerry Messina

Post Reply
gramo
Registered User
Registered User
Posts: 200
Joined: Tue Mar 20, 2007 6:55 am
Location: Australia
Contact:

Keypad.bas issue

Post by gramo » Sun Sep 06, 2009 12:42 pm

It's getting a little late here but I've found the culprit for an error in my program. While the program it came from was quite large, I've stripped and simplified the code to make it a little easier to read;

Code: Select all

Device = 18F2520
Clock = 32
Config OSC = INTIO67

Dim KeyVal, Counter As Byte

#option KEYPAD_PORT = PORTB
#option LCD_DATA = PORTC.4
#option LCD_RS = PORTC.2
#option LCD_EN = PORTC.3
Include "IntOSC8PLL.bas"
Include "Keypad.bas"
Include "LCD.bas"
Include "Convert.bas"

OSCTUNE.6 = 1
DelayMS(200)

LCD.Cls
LCD.WriteAt(1,1,"Test Begin")
Counter = 0

While True
    Repeat 
        KeyVal = Keypad.Value
    until KeyVal = 16
    
    inc(Counter)
    LCD.WriteAt(2,1,"Key: ",DecToStr(KeyVal,2), " Cnt: ",DecToStr(Counter,2))
    
    DelayMS(10)
    Repeat
    Until Keypad.Value = 0
Wend
The above program should simply loop until key 16 is pressed. In reality however; the program will erroneously return 16 from Keypad.Value even if another number is physically pressed (ie, 4, 5, or 6).

I can confirm this behaviour with both Proteus and with a real life circuit.

A counter (as shown above) was added to help confirm that the problem does in fact exist. As it turns out, the error occurs on every 2-3rd key press. Here's a video of the simulation with the circuit and code; note that key 16 is button "+" on that particular model in ISIS.


Am I missing something simple here, or is there a bug with the library? :(
Last edited by gramo on Sun Sep 06, 2009 12:45 pm, edited 1 time in total.
digital-diy.com - Hobby microcontroller projects and tutorials. Assembly, PICBasic and C examples.

Australian distributor for the Swordfish Compiler

gramo
Registered User
Registered User
Posts: 200
Joined: Tue Mar 20, 2007 6:55 am
Location: Australia
Contact:

Post by gramo » Sun Sep 06, 2009 12:43 pm

I should point out that the user library IntOSC8PLL.bas contains the following code;

Code: Select all

Module IntOSC8

OSCCON = %01111100     // Sets up the internal oscillator
digital-diy.com - Hobby microcontroller projects and tutorials. Assembly, PICBasic and C examples.

Australian distributor for the Swordfish Compiler

gramo
Registered User
Registered User
Posts: 200
Joined: Tue Mar 20, 2007 6:55 am
Location: Australia
Contact:

Post by gramo » Wed Oct 07, 2009 10:29 am

Unable to pin down the problem (no pun intended!), so I made my own user module should someone run into the same issue with the SF Keypad Library.

Note you can use it on any port, however, by specifying PORTB it will enable internal pullups and external resistors are not required.

Connections/wiring to keypad are detailed in the comments.

Use:

Code: Select all

Device = 18F452
Clock = 20

Dim Key As Byte

#option KEYPAD_PORT = PORTB
Include "Keypad16Pullup.bas"
Include "USART.bas"
Include "convert.bas"

SetBaudrate(br19200)

While True
    Repeat
        Key = Keypad16.Value
    Until Key <> 0
    
    USART.Write(DecToStr(Key),13,10)
Wend

Code: Select all

Module Keypad16
// For use with PORTB and internal pullup resistors
// Note: Can be used with other ports, with pullup resistors on Row pins

{
Column1 = PORTB.0
Column2 = PORTB.1
Column3 = PORTB.2
Column4 = PORTB.3
Row1 = PORTB.4
Row2 = PORTB.5
Row3 = PORTB.6
Row4 = PORTB.7
}

// validate data port...
#option KEYPAD_PORT = PORTB
#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 3                //
        FKeyPortTris = $FF              // Make all pins inputs
        FKeyPortTris.Bits(Counter) = 0  // Make a single Column an output
        FKeyPort.Bits(Counter) = 0      //  and set it low
        
        If (FKeyPort >> 4) <> %00001111 Then    // Check if any Rows are "Low"
            Coldata = Counter
            If FKeyPort.4 = 0 Then
                RowData = 1
            ElseIf FKeyPort.5 = 0 Then
                RowData = 5
            ElseIf FKeyPort.6 = 0 Then
                RowData = 9
            ElseIf FKeyPort.7 = 0 Then
                RowData = 13                
            EndIf            
            Result = Coldata + RowData
            Break          
        EndIf  
    Next
End Function

Public Sub Debounce()
    While Keypad16.Value <> 0           // Check if key is pressed
        DelayMS(10)                     // Wait for 10mS
    Wend  
End Sub

#if KEYPAD_PORT in (PORTB)
   INTCON2.7 = 0
#endif 

FKeyPortTris = $FF              // Make all pins inputs

End
Have not experienced the issue since using my own library
digital-diy.com - Hobby microcontroller projects and tutorials. Assembly, PICBasic and C examples.

Australian distributor for the Swordfish Compiler

Post Reply