News:

;) This forum is the property of Proton software developers

Main Menu

mystery in keypad procedure-help please

Started by basiclover, Jun 20, 2022, 11:44 AM

Previous topic - Next topic

basiclover

don't understand why (see penultimate line)
Print At 4,5,Dec0 PrevKeyValue
always displays 16 instead of the ASCII value of the last keypress i.e. 35 or 42

''****************************************************************
'*  Name    : 16F877A 3x4 Keypad test on PORT D et VAL()-convert *
'*            into n digits floating numerical value.BAS         *                       
'*  Author  : basiclover with keypad demo from LES               *
'*  Notice  : Copyright (c) 2022 [select VIEW...EDITOR OPTIONS]  *
'*          : All Rights Reserved                                *
'*  Date    : 6/20/2022                                          *
'*  Note    : PROCEDURE enter frequency                          *                    
'*          : ver 1                                              *
'*                                                               *
'*****************************************************************

;-------------------------------------------------------------------------------
;**** Added by Fuse Configurator ****
; Use the Fuse Configurator plug-in to change these settings

'Device = 16F877A

Config FOSC_HS, WDTE_OFF, PWRTE_OFF, BOREN_ON, LVP_OFF, CPD_OFF, WRT_OFF, DEBUG_OFF, CP_OFF

;**** End of Fuse Configurator Settings ****

'--------------------------------------------------------------------------------------------------------------
'demo inkey from LES
'You must place pull-up resistors on all four of the pins used for the column lines of the keypad, otherwise the Inkey routine will see floating pins and sometimes exit the routine early with invalid values.

'To test it, I created the simple demo program below, using PORTD for the keypad's pins:
'Code Select Expand
'
'   /\\\\\\\\\
'  /\\\///////\\\
'  \/\\\     \/\\\                                                 /\\\          /\\\
'   \/\\\\\\\\\\\/        /\\\\\     /\\\\\\\\\\     /\\\\\\\\   /\\\\\\\\\\\  /\\\\\\\\\\\  /\\\\\\\\\
'    \/\\\//////\\\      /\\\///\\\  \/\\\//////    /\\\/////\\\ \////\\\////  \////\\\////  \////////\\\
'     \/\\\    \//\\\    /\\\  \//\\\ \/\\\\\\\\\\  /\\\\\\\\\\\     \/\\\         \/\\\        /\\\\\\\\\\
'      \/\\\     \//\\\  \//\\\  /\\\  \////////\\\ \//\\///////      \/\\\ /\\     \/\\\ /\\   /\\\/////\\\
'       \/\\\      \//\\\  \///\\\\\/    /\\\\\\\\\\  \//\\\\\\\\\\    \//\\\\\      \//\\\\\   \//\\\\\\\\/\\
'        \///        \///     \/////     \//////////    \//////////      \/////        \/////     \////////\//
'                                  Let's find out together what makes a PIC Tick!
'
' Inkey demo using PORTD for the keypad.
' Make sure there are pull-up resistors on PORTD.4 to PORTD.7(columns)
' Otherwise, the keypad will fail to return a valid value because it will see floating pins.
'
' Written for the Positron8 compiler
'
    Device = 16F877                             ' Tell the compiler what device is being compiled for
    Declare Xtal = 20                           ' changed 10 to 20-Tell the compiler what speed the device will be operating at
'
    Declare Float_Display_Type = Fast           ' Use the faster, more accurate, but larger, floating point display library routine
'
' Setup the alphanumeric LCD
    Declare LCD_Type = 0       'HITACHI HD44780 controller
    Declare LCD_DTPin = PORTB.4  '4 pin config, data on 4 top pins(PortB4 to B7) of port B
    Declare LCD_RSPin = PORTB.3
    Declare LCD_ENPin = PORTB.2
    Declare LCD_Lines = 4
    Declare LCD_DataUs 75     'LCD time to wait beween data sent(microsec)for some older 16x2 44780 compatible displays (default = 50)
' Setup USART1
'  
    Declare Hserial_Baud = 9600
    Declare HRSOut_Pin = PORTC.6
'
' Set the port to use for the keypad
'
    Declare Keypad_Port = PORTD
'

'------------------------------------------------------------------
' convert a keypress from ASCII to numerical float value-test for n digits /see (1)
'EXIT procedure And confirm On key press * / key press # = enter new frequency
 'Create some variables
    Dim bKeyValue As Byte                       ' Holds the key pressed value
    Dim PrevKeyValue As Byte = 255              ' Holds the previous key press value
    Dim MyArray[2] As Byte  'create 2 elements array
   
    Dim MyValue As Byte    'holds numerical value of key press
    Dim PreviousMyValue As Byte    'holds numerical value of kprevious key press          
    Dim Frequency As Float        '(1)  numerical n digits output
    Dim PreviousFrequency As Float
    Dim FreqSelect As Float
           
    PreviousFrequency=0  
 
    Cls
    Frequency=0
   
    Proc GetFrequency()
    MyValue=0
    Do                                                          ' Create a loop
        bKeyValue = InKey                                       ' Read the keypad
        If bKeyValue <> 16 Then                                 ' Is the keypad value 16. i.e. No key pressed?
            bKeyValue = LookUpL bKeyValue, [16, "1", "2", "3",  ' \
                                            16, "4", "5", "6",  ' |
                                            16, "7", "8", "9",  ' | No. So convert the value into keypad character
                                            16, "*", "0", "#"]  ' /               
            If bKeyValue <> PrevKeyValue Then
                If bKeyValue= 42 Or bKeyValue=35 Then Return                  ' EXIT procedure on key press * or #
               
            MyArray[0]=bKeyValue  
            MyArray[1]= 0
           Print At 3,10,Dec0 PreviousFrequency          ' OK    'enter 568/after 5 display 0 /after 6 display 5 /after 8 display 56
           MyValue=Val(MyArray,Dec)
           Frequency= (PreviousFrequency*10)+MyValue      '
          
           Print At 1,1,Dec MyValue                       ' OK   'enter 568/after 5 display 5 /after 6 display 6 /after 8 display 58
           Print At 1,5,Dec PreviousMyValue               ' OK    'enter 568/after 5 display 0 /after 5 display 5 /after 8 display 6
           Print At 1,10,Dec bKeyValue
           Print At 2,1,Dec (MyValue*5)                   ' OK   'enter 568/after 5 display 25/after 6 display 30/after 8 display 40
           Print At 3,1,Dec0 Frequency '    'displays     ' OK   'enter 568/after 5 display 5 /after 6 display 56 /after 8 display 568
          
                                                                
            EndIf          
        EndIf
       
        PrevKeyValue = bKeyValue                                ' Keep a copy of the previous key press value
        PreviousMyValue=MyValue
        PreviousFrequency=Frequency
       
        DelayMS 100                                             ' A delay for debouncing
    Loop
    EndProc 

Main:
    Cls
    Frequency=0
    GetFrequency()
    Print At 4,1,Dec0 Frequency       ' entering successively 5,6,8 then on exit procedure displays 568 = OK
    Print At 4,5,Dec0 PrevKeyValue    'exiting procedure with * or # always displays 16  instead of ASCII valies 42 or 35 ????
    Print At 4,10,Dec0 PreviousMyValue

Yasin

The problem is because you exit the Procedure with "If bKeyValue= 42 Or bKeyValue=35 Then Return" before "PrevKeyValue = bKeyValue" happens.

basiclover

thanks YASIN, I should have seen that