Shop OBEX P1 Docs P2 Docs Learn Events
Virtual keypad decoding — Parallax Forums

Virtual keypad decoding

skylightskylight Posts: 1,915
edited 2013-04-25 09:22 in Propeller 1
I have created a virtual keypad using a QMP touchscreen, I need advice as to the concept of reading the keypresses and storing in a variable.

The keypad has numbered buttons 0-9 and an enter button

Each button has a unique keycode returned after pressing and then a repeat loop uses if statements to see which button was pressed

The keypad user will enter up to a three digit number which is in the form of hundreds,tens & units

I'm thinking that as the user types the number each digit drops into a variable array of three bytes byte[0], byte[1] and byte[2]

after entering the number be it a 1,2 or 3 digit number then byte[0] is multiplied by 1 or stays the same, byte[1] is then multiplied by 10 and byte[2] multiplied by 100. (see problem below)

If only one digit is entered then it is multiplied by 1 or stays the same, bytes [1] and [2] are zero values(nothing entered) so multiplying by 10 and 100 =0, respectively

same for two digits, digit 1*1 and digit 2*10 digit 3 =0*100 , and it goes on for three digits entered, you get the idea

thing is a one digit number will be a unit but the third digit entered will also be a unit (ie 123 where 3 is the unit) so does the unit digit go in array[0] or [2]?

I suppose a way around is to force the user to use leading zeros but I would prefer if they didn't have to

Is this the best method to use or is there an easier way? Does spin have a way of making this easier?.

Comments

  • Beau SchwabeBeau Schwabe Posts: 6,566
    edited 2013-04-24 07:15
    Just keep it in a LONG variable and multiply it by 16 (shift left by 4) prior to storing the next number. That way you can hold up to 8 keypad entries. When doing comparisons, just look at the entire long for a match.
  • skylightskylight Posts: 1,915
    edited 2013-04-24 07:24
    Hi Beau thanks for replying, I wonder if you can elaborate a little, I'm trying to get my head around what you are suggesting, are you saying that for instance if a 2 is entered first multiply that by 16 (result 32) then store that value to a long, next digit is say 5 so (result = 80) so add the values together (80+32) = 112? I'm not understanding fully here.

    How would comparisons be made?

    so that 2 and 5 = 25 entered

    would I do a Dec (long) to get the decimal value?
  • Beau SchwabeBeau Schwabe Posts: 6,566
    edited 2013-04-24 07:31
    Just a few steps...

    1) Initialize long variable to 0 at the beginning of the program

    2) Read the key (0-9; Enter; or other special character) <- as long as total number of unique characters can be mapped to a number less than 16
    3) Shift long variable left by 4
    4) Add Key value from #2 to long variable
    5) Check for a match against a hard coded long or one soft set by the user
    6) Repeat from step 2 only.
  • skylightskylight Posts: 1,915
    edited 2013-04-24 07:58
    ok think i've got it,

    store number 3 (0011) to long x
    x:=x<<4

    after shift

    x = 11110

    next number is 1 so user has entered 31 on keypad

    x+=1

    x now equals 11111 = 31
  • Mike GreenMike Green Posts: 23,101
    edited 2013-04-24 08:08
    Not quite. The shift is by 4 bits.
    %00000011 << 4 becomes %00110000 + 1 becomes %00110001 which is the same as $31
  • skylightskylight Posts: 1,915
    edited 2013-04-24 10:13
    That's decimal 49, so how can I end up with 011111 to equal decimal 31?
    shifting Binary(3) left by 4 only equals decimal 25 (011000) not 30 as expected so 5 short (000101)
    adding 011001 + 000101 = 30
    I'm missing something here but can't see where i'm going wrong

    btw the editor is stripping the % and some leading zeros from the above values
  • Beau SchwabeBeau Schwabe Posts: 6,566
    edited 2013-04-24 10:26
    It's HEXadecimal ... base16 rather than base 10 ... Shifting by 4 (or multiplying by 16) is analogous to multiplying by 10 in Decimal. It's just that shifting by 4 is easier in the computer world than multiplying by 10.
  • skylightskylight Posts: 1,915
    edited 2013-04-24 11:25
    trouble is I need the result in decimal, Do I need to make the keypress value for 3 into a hex value first? rather than a decimal value?

    I'm getting really confused at the moment
  • Beau SchwabeBeau Schwabe Posts: 6,566
    edited 2013-04-24 11:51
    "Do I need to make the keypress value for 3 into a hex value first? rather than a decimal value? " - No, not at all.

    Say you have your standard keys 0-9 already mapped to values 0-9 ... lets also say that...

    0 = 0
    1 = 1
    2 = 2
    3 = 3
    4 = 4
    5 = 5
    6 = 6
    7 = 7
    8 = 8
    9 = 9
    * = 10
    # = 11
    [enter] = 12

    You have room for 3 more as long as the mapped value does not exceed 15


    For example lets say that the code is 7542 and that password starts out as Zero

    First Key Press "7"
    {Shift Password left by 4}
    Password = %00000000000000000000000000000000
    KeyPress = 7 or %0111
    {Add KeyPress to Password}
    Password = %00000000000000000000000000000111
    

    Second Key Press "5"
    {Shift Password left by 4}
    Password = %00000000000000000000000001110000
    KeyPress = 5 or %0101
    {Add KeyPress to Password}
    Password = %00000000000000000000000001110101
    

    Third Key Press "4"
    {Shift Password left by 4}
    Password = %00000000000000000000011101010000
    KeyPress = 4 or %0100
    {Add KeyPress to Password}
    Password = %00000000000000000000011101010100
    

    Fourth Key Press "2"
    {Shift Password left by 4}
    Password = %00000000000000000111010101000000
    KeyPress = 2 or %0010
    {Add KeyPress to Password}
    Password = %00000000000000000111010101000010
    

    Now when you see a key press value of 12 (Enter) then you know to compare the Password value to a (predefined by you) fixed value, or one set by the user.
    If your looking at the 'stored' Password value as a decimal number it would be 30018 for this example, but if you look at it as a Hexadecimal value then the number is 7542.

    In software all you need to do is place a $ in front of the value if you want to hard-code it in Hexadecimal like this ....

    ValidCode := $7542

    If you leave off the $ and write it like this ...

    ValidCode := 7542

    ...it won't work ... you would have to enter 1D76 on the keypad with D equaling a mapped value of 13 for 7542 to work without the $
  • skylightskylight Posts: 1,915
    edited 2013-04-24 12:13
    Thanks Beau for your reply It shows how to add the binary values together at each stage and I understand now where to shift before adding the next keypress.

    The problem is it's not a password keypad, more like a calculators keypad so in the example above the final result would have to be in decimal
    "seven thousand five hundred and forty two" although it will never be more than three digits. I'm trying to create a DMX keypad so the max value entered would be 512

    I'm not creating a table to look up for comparison I just need the keypad to output to a variable the 1,2 and 3 digits as units or tens and units or hundreds and tens and units.

    does it mean I will have to do a comparison for all 512 possible entered values?

    I was originally thinking it was just a matter of adding the binary values together after they had been shifted.

    Sorry if i'm a bit slow to grasp this, i'm waiting for that eureka moment :smile:
  • Beau SchwabeBeau Schwabe Posts: 6,566
    edited 2013-04-24 12:35
    Hmm... Sorry I thought you were wanting this for password entries from a keypad for some reason.

    In that case it might be easier to multiply by 10 rather than shift left by 4. The same algorithm still applies. Instead of shifting by 4, just multiply by 10 (as you had originally indicated) prior to adding the new key press value. Sorry to add complexity to the original question.
  • skylightskylight Posts: 1,915
    edited 2013-04-24 12:45
    My fault I should have given more information originally but thanks anyway for your help it has opened my eyes to other possibilities and clarified some things I didn't understand before

    thanks also to Mike for helping

    There is still the problem of entering three digits and entering only one digit

    in entering three digits the last one entered is the units, with one digit it is the units, this makes it hard to know which value goes into which array ie I can't say that array[0] is the one to multiply by 1 and [2] is the one to multiply by 100 as that only applies to three digits having been entered.

    The only way I can see is to see first how many digits were entered then use a CASE to decide what array element is multiplied by what.


    EDIT: Thinking again if the array elements are loaded right to left as the digits would appear on screen I just need to shift the value from element to element as another digit is entered and when enter is pressed then do the multiplication.
  • tritoniumtritonium Posts: 543
    edited 2013-04-24 14:48
    Pseudo code
    result=0
    do
        temp=keyval
        if temp <> enter
             mult result by 10
             add temp to result
        endif
    loop until temp=enter
    

    this will work with any number of digits as long as result variable has enough bits


    Dave
  • skylightskylight Posts: 1,915
    edited 2013-04-25 09:22
    Thanks Dave, I'm getting all sorts of ideas on how to do this and will try to see which works out the best and most economical code wise.
Sign In or Register to comment.