Working with hex and decimal
Kivisto
Posts: 17
Hi guys,
I am currently working with the following code. It is the generic 4x4 matrix keypad software that was printed in Nuts & Volts Column 22, but I have edited it to not only read the keypad, but store the last 3 digits pressed by hitting the # key. The program runs perfectly on my BS2, but my problem lies in the fact that the keypad input is in Hexadecimal format.
I will be adding functionality, which is listed in the second code listing, to subtract 1 from the stored number any time a specific pin on the BS2 goes high. Like I said, this code has been tested and functions exactly how I need it to, with the exception that I need to be working strictly in decimal. As the code stands the number stored is having 1 subtracted every time Pin 4 goes HIGH. However, the 3-digit number being stored in 'code' is a Hexadecimal value. I need to make this happen in decimal for this to be functioning according to specification.
This seems like it could be really simple to fix, but my Basic skills aren't up to snuff. Any suggestions or fixes would be greatly appreciated. Thanks!
I am currently working with the following code. It is the generic 4x4 matrix keypad software that was printed in Nuts & Volts Column 22, but I have edited it to not only read the keypad, but store the last 3 digits pressed by hitting the # key. The program runs perfectly on my BS2, but my problem lies in the fact that the keypad input is in Hexadecimal format.
I will be adding functionality, which is listed in the second code listing, to subtract 1 from the stored number any time a specific pin on the BS2 goes high. Like I said, this code has been tested and functions exactly how I need it to, with the exception that I need to be working strictly in decimal. As the code stands the number stored is having 1 subtracted every time Pin 4 goes HIGH. However, the 3-digit number being stored in 'code' is a Hexadecimal value. I need to make this happen in decimal for this to be functioning according to specification.
This seems like it could be really simple to fix, but my Basic skills aren't up to snuff. Any suggestions or fixes would be greatly appreciated. Thanks!
DIRS = %100000000000000 code VAR WORD 'The input code is stored in this variable key_index VAR NIB 'Keeps track of the number of keypresses debounce VAR BIT i VAR NIB l VAR NIB m VAR NIB t VAR NIB time VAR BYTE index VAR WORD bit_index VAR NIB key_press VAR BIT key VAR NIB row VAR NIB 'Control lines columns VAR INC 'Sense lines init: key_index = 0 FOR i = 0 TO 15 'Intially set the keycode to 000 code.LOWBIT(i) = 0 time = 0 NEXT start: 'Program starts here GOSUB search_key IF key_press = 0 THEN start DEBUG "key pressed = ", HEX key,CR key_press = 0 GOTO start search_key: 'Scan the keypad for keypresses FOR row = 0 TO 3 'Send the control lines low, one at a time LOW row key = ~columns 'Check the sense lines (all at once) for key presses key = NCD key IF key <> 0 THEN push 'If key = 0 then no key was pressed time = time + 1 INPUT row 'Send the control line high NEXT debounce = 0 IF (time > 10200) THEN times_up 'If no key has been pressed within the last 30 sec the code will be cleared back: RETURN push: IF debounce = 1 THEN done 'Prevent debouncing debounce = 1 key_press = 1 key = (key-1) + (row*4) LOOKUP key,[noparse][[/noparse]14,0,15,13,7,8,9,12,4,5,6,11,1,2,3,10],key 'Find which key was pressed IF (key = 12) THEN clear 'Clear was pressed IF (key = 15) AND (key_index <= 2) THEN no_action 'Enter has been pushed but three digits have not been entered. 'Go back and search for more inputs. IF (key_index >= 3) AND (key = 15) THEN countdown 'three digits and enter have been pushed so send the data to countdown IF (key_index >= 3) THEN shift 'If more than three keys have been pressed need to store the last three entered. IF (key = 10) THEN no_action 'A has been pressed - ignore IF (key = 11) THEN no_action 'B has been pressed - ignore IF (key = 13) THEN no_action 'D has been pressed - ignore code.LOWNIB(2-key_index) = key 'Store the entered key key_index = key_index + 1 'Keep track of how many keys have been entered done: INPUT row 'Disconnect output on row RETURN clear: FOR l = 0 TO 15 'Clear the keycode code.LOWBIT(l) = 0 NEXT FOR m = 0 TO 3 code.LOWNIB(m) = 0 NEXT key_press = 0 key_index = 0 index=0 PAUSE 100 GOTO search_key 'Shift is a subroutine making sure that the last three keypresses are stored shift: code = (code >> 4) 'Delete the first key entered code.LOWNIB(3) = key 'Store the last key entered key_index = key_index + 1 GOTO done times_up: DEBUG "Time is up - Code will be cleared",CR time = 0 FOR t=0 TO 3 code.LOWNIB(t) = 0 DEBUG? code.LOWNIB(t) key_index = 0 NEXT GOTO back no_action: key_press = 0 GOTO search_key send_data: DEBUG "keys stored: ", HEX code, CR GOTO countdown
countdown: IF (IN4=1) THEN startcountdown GOTO countdown startcountdown: code = (code - 1) DEBUG "count: ", HEX code, CR IF (code=0) THEN complete DO UNTIL IN4=0 LOOP GOTO countdown Complete: OUT15 =1 DEBUG "COMPLETE", CR END
Comments
Hex and decimal are a way of formatting those 1's and 0's for display in a way that makes it easier for us to interpret or formatted in a way that some peripheral device may require.
Displaying the value you need should be as simple as changing the line DEBUG·"count:·",·HEX·code,·CR to DEBUG·"count:·",·DEC·code,·CR.
If that does not produce the expected result then the variable "code" has not been stored in the correct manner.
Jeff T.
Say I input 123 on the keypad and store it.
Instead, the application counts down from 291, which is the decimal equivalent of 123 in HEX.
I need to be able to input 123, and then countdown from 123 in decimal. Any suggestions? I'm really
pressed to get this thing working.
Thanks again!
Post Edited (Kivisto) : 11/25/2008 8:34:10 AM GMT
What is 123 ? It's 1 x 10^2 + 2 x 10^1 + 3 X 10^0. Get the picture?
Regards,
Bruce Bates
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When all else fails, try inserting a new battery.
But I'm sorry, I'm still just not seeing what I need to do specifically to
make my code do what I need it to do.
I apparently misunderstood what the problem was. In any case, that is the method to change 3 single, ordered digits into a 3 digit number. Apparently that was not what was needed - sorry for the confusion.
Regards,
Bruce Bates
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When all else fails, try inserting a new battery.
Right before you start the countdown do something like this:
code = (code.LOWNIB(2) * 100) + (code.LOWNIB(1) * 10) + (code.LOWNIB(0))
You can call the system that the keypad uses anything you want, but the fact remains that you have a 16 KEY pad. If the keys were numbers, how many could one account for? Yup, 0-9 and six more = 16. Thus the keypad manufacturers (many do it this way) number the keys as follows:
0-9 are as they appear, but 11 = A, 12 = B, 13 = C, 14 = D, 15 = E and last but not least 16 = F.
Rather unfortunately, those LOOK like "HEX numbers", so you MUST look at them merely as CHARACTERS. So, you have the characters 0-9 and the characters A-F. Make sense now?
It's CERTAINLY confusing the first time you get involved with a 4 X 4 keypad. I should add that even a 3 X 4 or 4 X 3 keypad often has the same arrangement in terms of CHARACTERS vs. numbers, but that goes from 0-9, and then A, and B.
Regards,
Bruce Bates
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When all else fails, try inserting a new battery.
Post Edited (Bruce Bates) : 11/25/2008 3:36:54 PM GMT
To make the conversion, insert the following just after capturing the number:
·· code = code.nib0 + 10*code.nib1 + 100*code.nib2
and your problem is solved.· My question is, why didn't these other guys just tell you that?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
· -- Carl, nn5i@arrl.net
Post Edited (Carl Hayes) : 11/25/2008 4:33:30 PM GMT
Thank you for that. I wasn't going to be quite as diplomatic as you were. These snide asides are starting to really get to me.
Regards,
Bruce Bates
whose name is readily apparent
at the end of every post!
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When all else fails, try inserting a new battery.
···· Code = 0
Keyloop:····
····· (capture a single keystroke in key)
····· IF·· key = (value that represents the pound sign) THEN Keyloopexit
···· Code = 10*code + key
···· goto Keyloop
Keyloopexit:
··· (whatever)
The first time through the loop, Code is 0 and you enter "1", so Code now becomes 10*0 + 1 = 1
The second time through the loop, Code is 1 and you enter "2", so Code now becomes 10*1 + 2 = 12
The third time through the loop, Code is 12 and you enter "3", so Code now becomes 10*12 + 3 = 123
The fourth time through the loop, Code is 123 and you enter "#", so·you exit the loop, Code stays 123, and you have a big grin.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
· -- Carl, nn5i@arrl.net
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
· -- Carl, nn5i@arrl.net
or with (),
not code = code.nib0 + 10*code.nib1 + 100*code.nib2
because code.nib2 is not your most significant, and because the Stamp will execute that expression strictly left to right, that is, add 10 to code.nib0, then multiply that total times code.nib1, then add 100 to that, then multiply time code.nib2, which is nonsensical.
This could be done as part of the key scanning, starting with code=0,
'code.LOWNIB(2-key_index) = key 'Store the entered key
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Tracy Allen
www.emesystems.com
Post Edited (Tracy Allen) : 11/25/2008 6:27:44 PM GMT
·· Let's remember why we're all here.· This is a support forum and·members who are trying to help are doing just that.· They're not getting paid for this, they just do it because they like to help people.· Statements like the one above are not very friendly to the family environment we're going for here.· If you have something to contribute, please do.· But please do it without pointing out what you perceive to be a lack of help from someone else.· Everyone tries to help in their own way.
·· I can tell you first hand that generally speaking we don't generally supply exact answers to questions in some cases.· This is because if you just give someone the answer, they don't learn from it.· The typical way is to help them help themselves.· This can sometimes take a little longer, but we find that members learn from the steps taken to arrive at the final solution.· That's not to say that is the situation here, I am just saying sometimes members will pace their information.· And of course everyone has their own way of working things out.· Let's try to respect this please so we can all benefit from what the forums have to offer.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Chris Savage
Parallax Engineering
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
· -- Carl, nn5i@arrl.net
Tracy, I have tried using your suggested code in various places. I'm still not getting it to work out right.
Can someone suggest a specific location to place that code, or does anyone see something that may need to be changed?
·
code = (code.LOWNIB(2) * 100) + (code.LOWNIB(1) * 10) + (code.LOWNIB(0))
The ()'s take care of the order of operations and the LOWNIB indexes nibbles in a word from right to left. HIGHNIB indexes nibbles from left to right.
At least according to the "Memory Organization and Variables" section of the PBASIC help file.
As far as where this line of code needs to go in the program, in keeping with the spirit of Chris Savage's post....it needs to go somewhere in your program after the key entry is complete and before you start ticking down the count.
I'd also like to point out that the method of doing the math at key entry, with "Code = 10*code + key" in the loop also works well.
Check out the DIG operator for converting a binary value to binary coded decimal. It is pretty handy.
Another way to write it (with nib2 as most significant) is
code = code.nib2*10 + code.nib1 *10 + code.nib0
That is just to show that there are different ways to do the same thing. That would go in as the first instruction in the countdown routine.
As an alternative, I would replace the line,
with
If you do it that way, you can also replace the lines
with
That is, if the user presses only 1 or two keys and then ENTER, the routine can branch right to countdown and the value in code will still be correct. So 57 ENTER would be the same as 057 ENTER
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Tracy Allen
www.emesystems.com
Doesn't matter in which order you give the operands, because addition is perfectly commutative (and so is multiplication).
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
· -- Carl, nn5i@arrl.net