News:

PROTON pic BASIC Compilers for PIC, PIC24, dsPIC33

Main Menu

Converting numeric keypad entries into a value

Started by top204, Feb 23, 2022, 12:39 PM

Previous topic - Next topic

top204

As has been shown on the forum in the past, there are many ways to convert the key presses from a keypad into a value, so here are a couple of my ideas that I've just thrown together. It also shows the flexability, and ease of understanding, of the Positron compilers, when a fully working and usable program can be created in approx 30 minutes:

'
'   /\\\\\\\\\
'  /\\\///////\\\
'  \/\\\     \/\\\                                                 /\\\          /\\\
'   \/\\\\\\\\\\\/        /\\\\\     /\\\\\\\\\\     /\\\\\\\\   /\\\\\\\\\\\  /\\\\\\\\\\\  /\\\\\\\\\
'    \/\\\//////\\\      /\\\///\\\  \/\\\//////    /\\\/////\\\ \////\\\////  \////\\\////  \////////\\\
'     \/\\\    \//\\\    /\\\  \//\\\ \/\\\\\\\\\\  /\\\\\\\\\\\     \/\\\         \/\\\        /\\\\\\\\\\
'      \/\\\     \//\\\  \//\\\  /\\\  \////////\\\ \//\\///////      \/\\\ /\\     \/\\\ /\\   /\\\/////\\\
'       \/\\\      \//\\\  \///\\\\\/    /\\\\\\\\\\  \//\\\\\\\\\\    \//\\\\\      \//\\\\\   \//\\\\\\\\/\\
'        \///        \///     \/////     \//////////    \//////////      \/////        \/////     \////////\//
'                                  Let's find out together what makes a PIC Tick!
'
' Read a 4x3 keypad and convert the digits into an integer or floating point value, depending on which procedure is called
' Written for the Positron8 compiler by Les Johnson
'
    Device = 18F25K20                                       ' Use an 18F device
    Declare Xtal = 16                                       ' Tell the compiler what frequency the device is running at
    Declare Float_Display_Type = Fast                       ' Use the faster, more accurate, floating point display library routine
'
' Setup USART1
'   
    Declare Hserial_Baud = 9600
    Declare HRSOut1_Pin = PORTC.6
'
' Setup the keypad's Port
'   
    Declare Keypad_Port PORTB
   
    Include "Strings.inc"                                   ' Load the "Strings.inc" library into the code for the StrToFloat procedure
'
' Create some variabes for the demo
'   
    Dim dValue As Dword                                     ' Holds the result of the integer keypad routine
    Dim fValue As dValue.Float                              ' Aliased to hold the result of the floating point keypad routine
   
'--------------------------------------------------------------------
' The main program starts here
' Get value entries from the keypad and transmit the ASCII result to a serial terminal
'
Main:
    Do                                                      ' Create a loop
        HRSOutLn "\rType a Floating Point value on the keypad\r",
                 "* key is the decimal point, # is the exit key"       
        fValue = fKeyPad()                                  ' Convert a floating point value from the keypad     
        HRSOutLn "Value typed is ", Dec2 fValue             ' Transmit the ASCII value to a serial terminal
       
       
        HRSOutLn "\rType an Integer value on the keypad\r",
                 "# is the exit key"
        dValue = iKeyPad()                                  ' Convert an integer value from the keypad
        HRSOutLn "Value typed is ", Dec dValue              ' Transmit the ASCII value to a serial terminal
    Loop                                                    ' Do it forever

'--------------------------------------------------------------------
' Read a 4x3 keypad and return the integer value typed on it when the # key is pressed
' Input     : None
' Output    : Returns the integer value typed into the keypad
' Notes     : Exits the procedure when the # key is pressed
'
Proc iKeyPad(), Dword
    Dim bPrevKey As Byte = 16                               ' Create a variable to hold the previous key pressed
    Dim bIndex As Byte = 0                                  ' Create a variable to hold the index of ValString
    Dim ValString As String * 10 Heap                       ' Create a string variable to hold the ASCII keypress values
    Dim bKey As Byte                                        ' Holds the value from the keypad

    Clear ValString                                         ' Clear the string before entering the loop   
    Do                                                      ' Create a loop
        bKey = InKey                                        ' Read the keypad
        DelayMS 100                                         ' A small debounce delay
        bKey = LookUp bKey, ["1", "2", "3", 16,             ' \
                             "4", "5", "6", 16,             ' |
                             "7", "8", "9", 16,             ' | Convert the keypad layout to relative ASCII values
                             16,  "0", 13,  16]             ' /
        If bKey <> bPrevKey Then                            ' Is the current key press the same as the last key press?
            If bKey <> 16 Then                              ' No. So is the keypad value 16 (no key pressed)?
                If bKey = 13 Then                           ' No. So is the # key pressed?
                    Result = Val(ValString, Dec)            ' Yes. So convert the ASCII value held in ValString into an integer
                    Repeat : Until InKey = 16               ' Wait for the keypad to be free of presses
                    ExitProc                                ' Exit the procedure
                EndIf
                If bIndex < SizeOf(ValString) Then          ' Is the String's index within its size limit?
                    ValString[bIndex] = bKey                ' Yes. So add the ASCII digit to the String
                    Inc bIndex                              ' Increment up the String
                EndIf
            EndIf
        EndIf
        bPrevKey = bKey                                     ' Keep a record of the key pressed       
    Loop                                                    ' Loop until the # key is pressed
EndProc

'--------------------------------------------------------------------
' Read a 4x3 keypad and return the floating point value typed on it when the # key is pressed
' Input     : None
' Output    : Returns the float value typed into the keypad
' Notes     : The * key is the decimal point
'           : Exits the procedure when the # key is pressed
'
Proc fKeyPad(), Float
    Dim bPrevKey As Byte = 16                               ' Create a variable to hold the previous key pressed
    Dim bIndex As Byte = 0                                  ' Create a variable to hold the index of ValString
    Dim ValString As String * 10 Heap                       ' Create a string variable to hold the ASCII keypress values
    Dim bKey As Byte                                        ' Holds the value from the keypad

    Clear ValString                                         ' Clear the string before entering the loop   
    Do                                                      ' Create a loop
        bKey = InKey                                        ' Read the keypad
        DelayMS 100                                         ' A small debounce delay
        bKey = LookUp bKey, ["1", "2", "3", 16,             ' \
                             "4", "5", "6", 16,             ' |
                             "7", "8", "9", 16,             ' | Convert the keypad layout to relative ASCII values, including the decimal point
                             ".", "0", 13,  16]             ' /
        If bKey <> bPrevKey Then                            ' Is the current key press the same as the last key press?                 
            If bKey <> 16 Then                              ' No. So is the keypad value 16 (no key pressed)?
                If bKey = 13 Then                           ' No. So is the # key pressed?
                    Result = StrToFloat(ValString)          ' Yes. So convert the ASCII value held in ValString into a floating point value
                    Repeat : Until InKey = 16               ' Wait for the keypad to be free of presses
                    ExitProc                                ' Exit the procedure
                EndIf
                If bIndex < SizeOf(ValString) Then          ' Is the String's index within its size limit?
                    ValString[bIndex] = bKey                ' Yes. So add the ASCII value to the String
                    Inc bIndex                              ' Increment up the String
                EndIf
            EndIf
        EndIf
        bPrevKey = bKey                                     ' Keep a record of the key pressed       
    Loop                                                    ' Loop until the # key is pressed
EndProc   

With the keypad used in the circuit, the "*" pad is the decimal point, and the "#" pad is the enter key to finish the conversion. With some changes to the mechanisms used in the above program, the keypad entry system can also be made to work within the flow of a program, instead of its own loop.

Below is the above program running in a simulator:
Keypad Entry.jpg

basiclover

Thanks a lot LES for your code

It will take me several days to fully understand your code and simultaneously reading the manual for things I'm not yet familiar with. That keeps my old brain alive.....