Tim Vukman
New Member
The code below is for a "simple" clock that I wish to use a keypad to provide settings for.
Some of it seems to work great on it's own (displaying the digits if manually set) and fetching the hex values from the keypad, but I seem to have no consistent results when I try to put it together.
In this latest version (I'm too embarrassed to number them) I will capture the high on input to to fire the interrupt and I will get a result on the first run through the scan_keys. On the second run through scan_keys it may or may not recognize that a key is pressed.
Ideally I would like it to stop on interrupt, take four key presses and then process the information when I press "settime"; while echoing it to the display digits. I haven't started on the echo part yet as I can't seem to find a way to work through getting the four digits.
My keypad is returning what I expect although the scan_keys doesn't always start at the beginning.
I have single stepped my way through this and I'm not seeing the problem.
Any advice would be greatly appreciated.
Thanks
TimV
' picaxe 28x at 4mhz
' clock base code
' keypad wired with four rows attached to 28X outputs
' and four columns attached to inputs
' four input wires are tied low with 10k
' inputs also have diode leaving each of the four and joined at bar end
' from bar end of 4 diodes a single wire goes to Input Pin2
' which is also tied low with 10k
' set each output high and then interrupt for pin2 high meaning key press has happened
i2cslave %11010000, i2cslow, i2cbyte 'initialize rtc
pause 100
' ********output definitions***********
symbol dataout = 7 'output pin to 4 74LS595 latches
symbol clk = 6 'output pin to clock output to latches
symbol latchout = 5 'output pin to release latches
' ********variable definitions*********
symbol temp = b0
symbol key_pressed = b1
symbol bitcounter = b2 'used in display routine to count bits
symbol outbit = b3 'used to isolate bit in display routine
symbol outbyte = b4 'used to carry byte to latch
symbol outnibl = b5 'used to isolate value from rtc
symbol key_val = b6 'used to get hex value of key pressed
symbol minutes = b7 'used to represent minutes in program and rtc
symbol hours = b8 'used to represent hours in program and rtc
symbol temp2 = b9
symbol setnibl = b10 'used to hold hex value of key pressed
'symbol control = %00010000 'used for rtc if needed
symbol scans = b11 'used as counter in keypad scan module
main: 'start of program
minutes = $25 'arbitrary value used for BCD into rtc
hours = $01 'arbitrary value used for BCD into rtc
writei2c 1,(minutes) 'writes BCD Minutes value to rtc
writei2c 2,(hours) 'writes BCD Hours value to rtc
pause 2000 'gives rtc time to settle
loop:
setint %00000100, %00000100 'input pin2 will go high on key pressed
if Pin2 = 1 then Interrupt 'go to the interrupt routine (want next 4 keypresses)
pins = %00000010 'sets row 3 (top) high
pins = %00000100 'sets row 2 high
pins = %00001000 'sets row 1 high
pins = %00010000 'sets row 0 (bottom) high
scan_keys: 'called from interrupt rountine to read keys
key_pressed = 0 'starting point for row3
pins = %00000010 'set output 1 high to provide voltage to keypad col3
gosub key_test 'test the input pins for which column keypress is in
if key_pressed = 1 then Key_Value
if key_pressed = 2 then Key_Value
if key_pressed = 3 then Key_Value
if key_pressed = 4 then Key_Value
key_pressed = 4 'starting point for row2
pins = %00000100 'set output 2 high to provide voltage to keypad col2
gosub key_test 'test the input pins for which column keypress is in
if key_pressed = 5 then Key_Value
if key_pressed = 6 then Key_Value
if key_pressed = 7 then Key_Value
if key_pressed = 8 then Key_Value
key_pressed = 8
pins = %00001000 'set output 3 high to provide voltage to keypad col1
gosub key_test
if key_pressed = 9 then Key_Value
if key_pressed = 10 then Key_Value
if key_pressed = 11 then Key_Value
if key_pressed = 12 then Key_Value
key_pressed = 12
pins = %00010000 'set output 4 high to provide voltage to keypad col0
gosub key_test
if key_pressed = 13 then Key_Value
if key_pressed = 14 then Key_Value
if key_pressed = 15 then Key_Value
if key_pressed = 16 then Key_Value
if scans = 1 then hour10
if scans = 2 then hour01
if scans = 3 then minute10
if scans = 4 then minute01
setint %00000100, %00000100
return 'closes gosub to scan count from "setint" routine
key_test:
if pin1 = 1 then add1 ' to input for row3
if pin5 = 1 then add2 ' to input for row2
if pin6 = 1 then add3 ' to input for row1
if pin7 = 1 then add4 ' to input for row0
goto scan_keys
add4: key_pressed = key_pressed + 1 'id keys 13, 14, 15, 16
add3: key_pressed = key_pressed + 1 'id keys 9, 10, 11, 12
add2: key_pressed = key_pressed + 1 'id keys 5, 6, 7, 8
add1: key_pressed = key_pressed + 1 'id keys 1, 2, 3, 4
Key_Value: 'picks up hex value of key pressed
lookup key_pressed, ($00, $01, $02, $03, $04, $05, $06, $07, $08, $09, $0A, $0B, $0C, $0D, $0E, $0F, $10), key_val
if key_val = $04 then settime 'special function key
if key_val = $08 then settime 'special function key
if key_val = $0C then alarmon 'special function key
if key_val = $0E OR key_val = $10 then snooze ' special function key
return 'closes gosub from interrupt: to key_value: via scan_keys:
settime: 'not written write time to rtc
High 7
return 'closes gosub from interrupt: to key_value: via scan_keys:
setalarm: 'not written hold alarm time to compare to rtc
Low 7
High 6
return 'closes gosub from interrupt: to key_value: via scan_keys:
alarmon: 'not written turn buzzer on / off
low 7
low 6
high 5
return 'closes gosub from interrupt: to key_value: via scan_keys:
snooze: 'not written add 9 minutes to alarm time but don't over write
High 7
return 'closes gosub from interrupt: to key_value: via scan_keys:
hour10:
temp = key_val
return 'closes gosub from interrupt: to key_value: scan loop
hour01:
temp2 = key_val 'b9 = b6
setnibl = temp & $000F 'b10 = b0 & $000F
hours = setnibl * $10 + temp2 'b7 = b1 * $10 + b9
return 'closes gosub from interrupt: to key_value: scan loop
minute10:
return 'closes gosub from interrupt: to key_value: scan loop
minute01:
return 'closes gosub from interrupt: to key_value: scan loop
readi2c 1,(b7) 'confirms value written to rtc from keypad
readi2c 2,(b8) 'same but for hours (minutes line above)
outnibl = b7 & $000F 'isolates right bit of minutes
gosub outdigit 'sends right bit to output routine
outnibl = b7 & $00F0 / 16 'isolates left bit of minutes
gosub outdigit 'sends left bit to output routine
outnibl = b8 & $000F 'isolate right bit of hours
gosub outdigit 'sends right bit to output routine
outnibl = b8 & $00F0 / 16 'isolates left bit of hours
gosub outdigit 'sends left bit to output routine
pulsout latchout, 1
goto loop
outdigit: 'handles getting four digits out in order
lookup outnibl, ($BE, $82, $DC, $D6, $E2, $76, $7E, $92, $FE, $F2, $FA, $6E, $3C, $DE, $7C, $78), outbyte
for bitcounter = 0 to 7
outbit = outbyte & 1
if outbit = 1 then outhi
low dataout
goto clkout
outhi: high dataout
clkout: pulsout clk, 1
outbyte = outbyte / 2
next bitcounter
goto loop 'closes gosub to outdigit: from loop:
Interrupt:
for scans = 0 to 4 'hoping to loop for four key presses
gosub scan_keys
next scans
return
Some of it seems to work great on it's own (displaying the digits if manually set) and fetching the hex values from the keypad, but I seem to have no consistent results when I try to put it together.
In this latest version (I'm too embarrassed to number them) I will capture the high on input to to fire the interrupt and I will get a result on the first run through the scan_keys. On the second run through scan_keys it may or may not recognize that a key is pressed.
Ideally I would like it to stop on interrupt, take four key presses and then process the information when I press "settime"; while echoing it to the display digits. I haven't started on the echo part yet as I can't seem to find a way to work through getting the four digits.
My keypad is returning what I expect although the scan_keys doesn't always start at the beginning.
I have single stepped my way through this and I'm not seeing the problem.
Any advice would be greatly appreciated.
Thanks
TimV
' picaxe 28x at 4mhz
' clock base code
' keypad wired with four rows attached to 28X outputs
' and four columns attached to inputs
' four input wires are tied low with 10k
' inputs also have diode leaving each of the four and joined at bar end
' from bar end of 4 diodes a single wire goes to Input Pin2
' which is also tied low with 10k
' set each output high and then interrupt for pin2 high meaning key press has happened
i2cslave %11010000, i2cslow, i2cbyte 'initialize rtc
pause 100
' ********output definitions***********
symbol dataout = 7 'output pin to 4 74LS595 latches
symbol clk = 6 'output pin to clock output to latches
symbol latchout = 5 'output pin to release latches
' ********variable definitions*********
symbol temp = b0
symbol key_pressed = b1
symbol bitcounter = b2 'used in display routine to count bits
symbol outbit = b3 'used to isolate bit in display routine
symbol outbyte = b4 'used to carry byte to latch
symbol outnibl = b5 'used to isolate value from rtc
symbol key_val = b6 'used to get hex value of key pressed
symbol minutes = b7 'used to represent minutes in program and rtc
symbol hours = b8 'used to represent hours in program and rtc
symbol temp2 = b9
symbol setnibl = b10 'used to hold hex value of key pressed
'symbol control = %00010000 'used for rtc if needed
symbol scans = b11 'used as counter in keypad scan module
main: 'start of program
minutes = $25 'arbitrary value used for BCD into rtc
hours = $01 'arbitrary value used for BCD into rtc
writei2c 1,(minutes) 'writes BCD Minutes value to rtc
writei2c 2,(hours) 'writes BCD Hours value to rtc
pause 2000 'gives rtc time to settle
loop:
setint %00000100, %00000100 'input pin2 will go high on key pressed
if Pin2 = 1 then Interrupt 'go to the interrupt routine (want next 4 keypresses)
pins = %00000010 'sets row 3 (top) high
pins = %00000100 'sets row 2 high
pins = %00001000 'sets row 1 high
pins = %00010000 'sets row 0 (bottom) high
scan_keys: 'called from interrupt rountine to read keys
key_pressed = 0 'starting point for row3
pins = %00000010 'set output 1 high to provide voltage to keypad col3
gosub key_test 'test the input pins for which column keypress is in
if key_pressed = 1 then Key_Value
if key_pressed = 2 then Key_Value
if key_pressed = 3 then Key_Value
if key_pressed = 4 then Key_Value
key_pressed = 4 'starting point for row2
pins = %00000100 'set output 2 high to provide voltage to keypad col2
gosub key_test 'test the input pins for which column keypress is in
if key_pressed = 5 then Key_Value
if key_pressed = 6 then Key_Value
if key_pressed = 7 then Key_Value
if key_pressed = 8 then Key_Value
key_pressed = 8
pins = %00001000 'set output 3 high to provide voltage to keypad col1
gosub key_test
if key_pressed = 9 then Key_Value
if key_pressed = 10 then Key_Value
if key_pressed = 11 then Key_Value
if key_pressed = 12 then Key_Value
key_pressed = 12
pins = %00010000 'set output 4 high to provide voltage to keypad col0
gosub key_test
if key_pressed = 13 then Key_Value
if key_pressed = 14 then Key_Value
if key_pressed = 15 then Key_Value
if key_pressed = 16 then Key_Value
if scans = 1 then hour10
if scans = 2 then hour01
if scans = 3 then minute10
if scans = 4 then minute01
setint %00000100, %00000100
return 'closes gosub to scan count from "setint" routine
key_test:
if pin1 = 1 then add1 ' to input for row3
if pin5 = 1 then add2 ' to input for row2
if pin6 = 1 then add3 ' to input for row1
if pin7 = 1 then add4 ' to input for row0
goto scan_keys
add4: key_pressed = key_pressed + 1 'id keys 13, 14, 15, 16
add3: key_pressed = key_pressed + 1 'id keys 9, 10, 11, 12
add2: key_pressed = key_pressed + 1 'id keys 5, 6, 7, 8
add1: key_pressed = key_pressed + 1 'id keys 1, 2, 3, 4
Key_Value: 'picks up hex value of key pressed
lookup key_pressed, ($00, $01, $02, $03, $04, $05, $06, $07, $08, $09, $0A, $0B, $0C, $0D, $0E, $0F, $10), key_val
if key_val = $04 then settime 'special function key
if key_val = $08 then settime 'special function key
if key_val = $0C then alarmon 'special function key
if key_val = $0E OR key_val = $10 then snooze ' special function key
return 'closes gosub from interrupt: to key_value: via scan_keys:
settime: 'not written write time to rtc
High 7
return 'closes gosub from interrupt: to key_value: via scan_keys:
setalarm: 'not written hold alarm time to compare to rtc
Low 7
High 6
return 'closes gosub from interrupt: to key_value: via scan_keys:
alarmon: 'not written turn buzzer on / off
low 7
low 6
high 5
return 'closes gosub from interrupt: to key_value: via scan_keys:
snooze: 'not written add 9 minutes to alarm time but don't over write
High 7
return 'closes gosub from interrupt: to key_value: via scan_keys:
hour10:
temp = key_val
return 'closes gosub from interrupt: to key_value: scan loop
hour01:
temp2 = key_val 'b9 = b6
setnibl = temp & $000F 'b10 = b0 & $000F
hours = setnibl * $10 + temp2 'b7 = b1 * $10 + b9
return 'closes gosub from interrupt: to key_value: scan loop
minute10:
return 'closes gosub from interrupt: to key_value: scan loop
minute01:
return 'closes gosub from interrupt: to key_value: scan loop
readi2c 1,(b7) 'confirms value written to rtc from keypad
readi2c 2,(b8) 'same but for hours (minutes line above)
outnibl = b7 & $000F 'isolates right bit of minutes
gosub outdigit 'sends right bit to output routine
outnibl = b7 & $00F0 / 16 'isolates left bit of minutes
gosub outdigit 'sends left bit to output routine
outnibl = b8 & $000F 'isolate right bit of hours
gosub outdigit 'sends right bit to output routine
outnibl = b8 & $00F0 / 16 'isolates left bit of hours
gosub outdigit 'sends left bit to output routine
pulsout latchout, 1
goto loop
outdigit: 'handles getting four digits out in order
lookup outnibl, ($BE, $82, $DC, $D6, $E2, $76, $7E, $92, $FE, $F2, $FA, $6E, $3C, $DE, $7C, $78), outbyte
for bitcounter = 0 to 7
outbit = outbyte & 1
if outbit = 1 then outhi
low dataout
goto clkout
outhi: high dataout
clkout: pulsout clk, 1
outbyte = outbyte / 2
next bitcounter
goto loop 'closes gosub to outdigit: from loop:
Interrupt:
for scans = 0 to 4 'hoping to loop for four key presses
gosub scan_keys
next scans
return