calculator input?!
im trying to use a matrix keypad for user input for a calculator using a basic stamp 2 micro controller. I am having issues getting my code to store the button pressed and then putting them all together. So lets say someone wanted to enter the number 25. the program has to store the 2 and the 5 as variables and then multiply the 2 by 10 and add 5. pretty strait forward but looping this is difficult since the keypad outputs what seems to be zero when nothing is pressed. so my variables just become zeros >____< I only need to get a max 3 digits since this is going to be used for an 8 bit calculator...
I believe I just have to use some if then statements and some do loop statements... anyone have any ideas? ive googled this too but to no avail.
this is what im trying to use but it keeps going to the gosub compile.... without a or b being pressed..... :[
I believe I just have to use some if then statements and some do loop statements... anyone have any ideas? ive googled this too but to no avail.
' {$STAMP BS2}
' {$PBASIC 2.5}
row VAR Nib ' Variable space for row counting
column VAR Nib ' Variable space for column counting
keypad VAR Word ' Variable space to store keypad output
keypadOld VAR Word ' Variable space to store old keypad output
temp VAR Nib ' Variable space for polling column states
keynum VAR Word ' Variable for keystroke
placeholder VAR Nib ' Variable for keeping track of digit placement
ks1 VAR Nib ' variable for 1st keystroke
ks2 VAR Nib ' variable for 2nd keystroke
ks3 VAR Nib ' variable for 3rd keystroke
finalnum VAR Nib ' variable for final number output
placeholder = 0
DO
GOSUB readkeypad
GOSUB display
IF keypad <> keypadold THEN
GOSUB placedigit
ENDIF
IF keynum = "A" OR "B" THEN
GOSUB compile
ENDIF
LOOP
' -----[ Subroutine - compile ]-------------------------------------------------
compile:
IF placeholder = 0 THEN finalnum = ks1
IF placeholder = 1 THEN finalnum = ks1 * 10 + ks2
IF placeholder = 2 THEN finalnum = ks1 * 100 + ks2 * 10 + ks3
DEBUG DEC ? finalnum, CR
DEBUG BIN ? finalnum, CR
RETURN
' -----[ Subroutine - Placedigit ]-------------------------------------------------
placedigit:
IF placeholder = 2 THEN ks3 = keynum
IF placeholder = 1 THEN
ks2 = keynum
placeholder = 2
ENDIF
IF placeholder = 0 THEN
ks1 = keynum
placeholder = 1
ENDIF
RETURN
' -----[ Subroutine - ReadKeypad ]-------------------------------------------------
' Read keypad button states
readkeypad:
keypad = 0
OUTL = 000000 ' Initialize IO
DIRL = 000000
FOR row = 0 TO 3
DIRB = 11 ' Set columns (P7-P4) as outputs
OUTB = 00 ' Pull columns low (act as pull down)
OUTA = 1 << Row ' Set rows high one by one
DIRA = 1 << Row
temp = 0 ' Reset temp variable to 0
FOR column = 0 TO 3
INPUT (column + 4) ' Set columns as inputs one by one
temp = temp | (INB & (1 << column)) ' Poll column state and store in temp
NEXT
keypad = keypad << 4 | (Temp REV 4) ' Store keypad value
NEXT
RETURN
' -----[ Subroutine - Display ]----------------------------------------------------
' sets numbers
display:
IF Keypad.bit15 THEN keynum = 1
IF Keypad.BIT14 THEN keynum = 2
IF Keypad.BIT13 THEN keynum = 3
IF Keypad.BIT12 THEN keynum = "A"
IF Keypad.BIT11 THEN keynum = 4
IF Keypad.BIT10 THEN keynum = 5
IF Keypad.BIT9 THEN keynum = 6
IF Keypad.BIT8 THEN keynum = "B"
IF Keypad.Bit7 THEN keynum = 7
IF Keypad.Bit6 THEN keynum = 8
IF Keypad.Bit5 THEN keynum = 9
IF Keypad.Bit4 THEN keynum = "C"
IF Keypad.Bit3 THEN keynum = "*"
IF Keypad.Bit2 THEN keynum = 0
IF Keypad.BIT1 THEN keynum = "#"
IF Keypad.Bit0 THEN keynum = "D"
RETURN
this is what im trying to use but it keeps going to the gosub compile.... without a or b being pressed..... :[

Comments
accumulator = accumulator * 10 + keynum
keynum is a value from 0 to 9 representing the numeric key just pressed.
If you want a backspace or remove digit command key, you'd do:
accumulator = accumulator / 10
In your "display" routine, what's the value of keynum if Keypad is all zero bits.
accumulator = accumulator * 10 + keynum
keynum is a value from 0 to 9 representing the numeric key just pressed.
If you want a backspace or remove digit command key, you'd do:
accumulator = accumulator / 10
In your "display" routine, what's the value of keynum if Keypad is all zero bits?
IMO, writing a calculator program is a great coding exercise. I thoroughly enjoyed programming a simple talking calculator using a computer keyboard and integer math on "another processor": http://www.youtube.com/watch?v=624cmIr5qBs&feature=player_detailpage#t=28s
Later, I found this nifty talking calculator on Ebay for $9 and just had to have it: http://www.ebay.com/itm/250976474687
wow i knew there was an easier way to do it! i have much better code now but i am having an issue with that its doing the accumulator thing twice....
here is the code i am now using
' {$STAMP BS2} ' {$PBASIC 2.5} row VAR Nib ' Variable space for row counting column VAR Nib ' Variable space for column counting keypad VAR Word ' Variable space to store keypad output keypadOld VAR Word ' Variable space to store old keypad output temp VAR Nib ' Variable space for polling column states keynum VAR Word ' Variable for keystroke accumulator VAR Word DO GOSUB readkeypad IF keypad <> keypadold THEN GOSUB display IF keynum <> "C" THEN accumulator = accumulator * 10 + keynum keypadold = keypad DEBUG DEC accumulator, CR PAUSE 500 ELSE DEBUG CLS ENDIF ENDIF LOOP ' -----[ Subroutine - ReadKeypad ]------------------------------------------------- ' Read keypad button states readkeypad: keypad = 0 OUTL = %00000000 ' Initialize IO DIRL = %00000000 FOR row = 0 TO 3 DIRB = %1111 ' Set columns (P7-P4) as outputs OUTB = %0000 ' Pull columns low (act as pull down) OUTA = 1 << Row ' Set rows high one by one DIRA = 1 << Row temp = 0 ' Reset temp variable to 0 FOR column = 0 TO 3 INPUT (column + 4) ' Set columns as inputs one by one temp = temp | (INB & (1 << column)) ' Poll column state and store in temp NEXT keypad = keypad << 4 | (Temp REV 4) ' Store keypad value NEXT RETURN ' -----[ Subroutine - Display ]---------------------------------------------------- ' sets numbers display: IF Keypad.BIT15 THEN keynum = 1 IF Keypad.BIT14 THEN keynum = 2 IF Keypad.BIT13 THEN keynum = 3 IF Keypad.BIT12 THEN keynum = "A" IF Keypad.BIT11 THEN keynum = 4 IF Keypad.BIT10 THEN keynum = 5 IF Keypad.BIT9 THEN keynum = 6 IF Keypad.BIT8 THEN keynum = "B" IF Keypad.BIT7 THEN keynum = 7 IF Keypad.BIT6 THEN keynum = 8 IF Keypad.BIT5 THEN keynum = 9 IF Keypad.BIT4 THEN keynum = "C" IF Keypad.BIT3 THEN keynum = "*" IF Keypad.BIT2 THEN keynum = 0 IF Keypad.BIT1 THEN keynum = "#" IF Keypad.BIT0 THEN keynum = "D" RETURNand the debug terminal gives me
i put that pause in attempt to debounce it but that obviously isnt working. why is keypadold not equal to keypad? that must be the issue since it is doing it twice... but why does it stop after just doing it one extra time? no idea......
edit:
thank you so much sapphire that worked great!
and thanks again mike green for getting me started in the right direction!