Ioannis
- 26th March 2022, 20:30
This is a Stamp Basic code by Tracey Allen to read a 4x4 matrix keyboard with Finite State Machine technique.
I am trying to use this code in PBP but cannot understand how few commands work:
keyn var key0.nib0 ' address the first detection as nibble array
The above seems to alias variable keyn to key0 lowest nibble (this key0 is a word variable). Is that right?
Then, keyn(ix)=kin ' read the row inputs into nibbles of key0
seems to put in an array controlled by ix four values. Though the keyn was not defined as array. How does this work?
' KEY_FSM.BS2
' Tracy Allen, http://www.emesystems.com
' scans a 16 key (4x4) matrix keypad
' using state machine for debouncing, all keys in parallel
' The columns are connected to BS2 outputs of port C, P8 to P11
' The rows are connected to BS2 inputs of port D, P12 to P15
' with pull-up resistors to Vdd=+5 volts.
' This routine has two output variables, "keys" and "keyx"
' Bits in "keys" go low after the corresponding key is
' pressed and debounced.
' Bits in "keyx" go high for _one iteration only_ to signal
' a high to low transition (button pushed & debounced)
' of the corresponding key
' In all state variables, each bit corresponds to one key.
' One word is used for 16 keys, in a 4x4 array.
' This uses a lot of variables, but in many applications it is
' possible to reuse most of the variables outside the keyscan loop
' Note that the scan can detect key combinations.
' The decoding step can miss keys only if they are pressed at
' exactly the same instant.
kout var outC ' 4-bit keypad columns, state, if output
kdir var dirC ' 4-bit keypad columns, input or output
kin var inD ' inputs from keypad rows connected to port D
' bit low for key pressed
key0 var word ' state variable, first detection
key1 var word ' state variable, second detection
key2 var word ' state variable, third detection
keyn var key0.nib0 ' address the first detection as nibble array
keys var word ' debounced output, bit low for key pressed
keyz var word ' state variable, previous state of keys
keyx var word ' transition output, bit high one iteration for each press
ix var word ' index for array addressing
dirs=%0000111111111111 ' port D is input, all others output
outs=%0000000000000000 ' start with port C columns output low
' pins P0 to P7 are not used in this program
debug cls ' Clear screen
scanloop:
key2=key1 ' move the debounced states
key1=key0
for ix=0 to 3 ' scan 4 cols by bringing one col at a time low.
kdir = dcd ix ' 0001,0010,0100,1000 in succession
' this makes one column at a time output low
' while the other columns are inputs
keyn(ix)=kin ' read the row inputs into nibbles of key0
next
kdir = %1111 ' make all columns output (avoid floating inputs)
keys=key0&key1&key2|keys ' key bit 0->1 when all 3 are high
keys=key0|key1|key2&keys ' key bit 1->0 when all 3 are low
keyx=keys^keyz & keyz ' detect change 1->0 (active low keypress)
keyz=keys
' optional debug to visualize operation of the state machine
' slows down the operation tremendously
' debug home,bin16 key0,cr,bin16 key1,cr,bin16 key2,cr
' debug bin16 keys,32,bin16 keyx,home
' optional branch to decode keypress, note keyx is transient
if keyx>0 then decode
' pause 30 ' optional delay to slow the scanning
goto scanloop
decode:
code1 var byte ' code1 variable
code1 = ncd keyx-1 ' binary encode the most significant key
lookup code1,[10,7,4,1,0,8,5,2,11,9,6,3],code1 ' translate to code
dtmfout 7,[code1] ' send as touchtone
lookup code1,["0123456789*#"],code1 ' --> printable character
debug code1 ' print on screen
goto scanloop
Thanks,
Ioannis
I am trying to use this code in PBP but cannot understand how few commands work:
keyn var key0.nib0 ' address the first detection as nibble array
The above seems to alias variable keyn to key0 lowest nibble (this key0 is a word variable). Is that right?
Then, keyn(ix)=kin ' read the row inputs into nibbles of key0
seems to put in an array controlled by ix four values. Though the keyn was not defined as array. How does this work?
' KEY_FSM.BS2
' Tracy Allen, http://www.emesystems.com
' scans a 16 key (4x4) matrix keypad
' using state machine for debouncing, all keys in parallel
' The columns are connected to BS2 outputs of port C, P8 to P11
' The rows are connected to BS2 inputs of port D, P12 to P15
' with pull-up resistors to Vdd=+5 volts.
' This routine has two output variables, "keys" and "keyx"
' Bits in "keys" go low after the corresponding key is
' pressed and debounced.
' Bits in "keyx" go high for _one iteration only_ to signal
' a high to low transition (button pushed & debounced)
' of the corresponding key
' In all state variables, each bit corresponds to one key.
' One word is used for 16 keys, in a 4x4 array.
' This uses a lot of variables, but in many applications it is
' possible to reuse most of the variables outside the keyscan loop
' Note that the scan can detect key combinations.
' The decoding step can miss keys only if they are pressed at
' exactly the same instant.
kout var outC ' 4-bit keypad columns, state, if output
kdir var dirC ' 4-bit keypad columns, input or output
kin var inD ' inputs from keypad rows connected to port D
' bit low for key pressed
key0 var word ' state variable, first detection
key1 var word ' state variable, second detection
key2 var word ' state variable, third detection
keyn var key0.nib0 ' address the first detection as nibble array
keys var word ' debounced output, bit low for key pressed
keyz var word ' state variable, previous state of keys
keyx var word ' transition output, bit high one iteration for each press
ix var word ' index for array addressing
dirs=%0000111111111111 ' port D is input, all others output
outs=%0000000000000000 ' start with port C columns output low
' pins P0 to P7 are not used in this program
debug cls ' Clear screen
scanloop:
key2=key1 ' move the debounced states
key1=key0
for ix=0 to 3 ' scan 4 cols by bringing one col at a time low.
kdir = dcd ix ' 0001,0010,0100,1000 in succession
' this makes one column at a time output low
' while the other columns are inputs
keyn(ix)=kin ' read the row inputs into nibbles of key0
next
kdir = %1111 ' make all columns output (avoid floating inputs)
keys=key0&key1&key2|keys ' key bit 0->1 when all 3 are high
keys=key0|key1|key2&keys ' key bit 1->0 when all 3 are low
keyx=keys^keyz & keyz ' detect change 1->0 (active low keypress)
keyz=keys
' optional debug to visualize operation of the state machine
' slows down the operation tremendously
' debug home,bin16 key0,cr,bin16 key1,cr,bin16 key2,cr
' debug bin16 keys,32,bin16 keyx,home
' optional branch to decode keypress, note keyx is transient
if keyx>0 then decode
' pause 30 ' optional delay to slow the scanning
goto scanloop
decode:
code1 var byte ' code1 variable
code1 = ncd keyx-1 ' binary encode the most significant key
lookup code1,[10,7,4,1,0,8,5,2,11,9,6,3],code1 ' translate to code
dtmfout 7,[code1] ' send as touchtone
lookup code1,["0123456789*#"],code1 ' --> printable character
debug code1 ' print on screen
goto scanloop
Thanks,
Ioannis