Better way to read key matrix?

jledger

New Member
I've worked out the hardware for my 28x 8x8 matrix, but I seem to have hit on some real issues in the software.

Below is a copy of my current code. To solve issues of too many keys when a key was pressed, I've added the PAUSES. For some reason, I'm getting alot of false readings when a key is held too long. (Hence the remarked keys)

Is there a better way I should approach this?
(Sorry about the length in advance..)

loop:

low 0
low 1
low 2
low 3
low 4
low 5
low 6
low 7



start:
pause 5
high 0
if pin0=1 then show1
if pin1=1 then show2
if pin2=1 then show3
if pin3=1 then show4
if pin4=1 then show5
if pin5=1 then show6
if pin6=1 then show7
if pin7=1 then show8
low 0

pause 5
high 1
if pin0=1 then show9
if pin1=1 then show10
if pin2=1 then show11
if pin3=1 then show12
if pin4=1 then show13
if pin5=1 then show14
if pin6=1 then show15
if pin7=1 then show16
low 1

pause 5
high 2
if pin0=1 then show17
if pin1=1 then show18
if pin2=1 then show19
if pin3=1 then show20
if pin4=1 then show21
if pin5=1 then show22
if pin6=1 then show23
if pin7=1 then show24
low 2

pause 5
high 3
if pin0=1 then show25
if pin1=1 then show26
if pin2=1 then show27
if pin3=1 then show28
if pin4=1 then show29
if pin5=1 then show30
if pin6=1 then show31
if pin7=1 then show32
low 3

pause 5
high 4
if pin0=1 then show33
if pin1=1 then show34
if pin2=1 then show35
if pin3=1 then show36
if pin4=1 then show37
if pin5=1 then show38
if pin6=1 then show39
if pin7=1 then show40
low 4

pause 5
high 5
if pin0=1 then show41
if pin1=1 then show42
if pin2=1 then show43
if pin3=1 then show44
if pin4=1 then show45
if pin5=1 then show46
if pin6=1 then show47
if pin7=1 then show48
low 5

pause 5
high 6
if pin0=1 then show49
if pin1=1 then show50
if pin2=1 then show51
if pin3=1 then show52
if pin4=1 then show53
if pin5=1 then show54
if pin6=1 then show55
if pin7=1 then show56
low 6

pause 5
high 7
if pin0=1 then show57
if pin1=1 then show58
if pin2=1 then show59
if pin3=1 then show60
if pin4=1 then show61
if pin5=1 then show62
if pin6=1 then show63
if pin7=1 then show64
low 7


goto start

show1:
pause 100
sertxd("2")
goto start

show2:
pause 100
sertxd("q")
goto start

show3:
'pause 100
'sertxd("C=")
goto start

show4:
pause 100
sertxd(" ")
goto start

show5:
pause 100
sertxd("1")
goto start


show6:
pause 100
sertxd(27)
goto start


show7:
'pause 100
'sertxd("CTRL")
goto start


show8:
'pause 100
'sertxd("Run/Stop")
goto start

show9:
pause 100
sertxd("4")
goto start

show10:
pause 100
sertxd("e")
goto start

show11:
pause 100
sertxd("s")
goto start

show12:
pause 100
sertxd("z")
goto start

show13:
pause 100
sertxd("3")
goto start

show14:
pause 100
sertxd("w")
goto start

show15:
pause 100
sertxd("a")
goto start

show16:
pause 100
sertxd("Lshift")
goto start


show17:
pause 100
sertxd("6")
goto start

show18:
pause 100
sertxd("t")
goto start

show19:
pause 100
sertxd("f")
goto start

show20:
pause 100
sertxd("c")
goto start

show21:
pause 100
sertxd("5")
goto start

show22:
pause 100
sertxd("r")
goto start

show23:
pause 100
sertxd("d")
goto start

show24:
pause 100
sertxd("x")
goto start


show25:
pause 100
sertxd("8")
goto start

show26:
pause 100
sertxd("u")
goto start

show27:
pause 100
sertxd("h")
goto start

show28:
pause 100
sertxd("b")
goto start

show29:
pause 100
sertxd("7")
goto start

show30:
pause 100
sertxd("y")
goto start

show31:
pause 100
sertxd("g")
goto start

show32:
pause 100
sertxd("v")
goto start



show33:
pause 100
sertxd("0")
goto start

show34:
pause 100
sertxd("o")
goto start

show35:
pause 100
sertxd("k")
goto start

show36:
pause 100
sertxd("m")
goto start

show37:
pause 100
sertxd("9")
goto start

show38:
pause 100
sertxd("i")
goto start

show39:
pause 100
sertxd("j")
goto start

show40:
pause 100
sertxd("n")
goto start


show41:
pause 100
sertxd("-")
goto start

show42:
pause 100
sertxd("@")
goto start

show43:
pause 100
sertxd(":")
goto start

show44:
pause 100
sertxd(".")
goto start

show45:
pause 100
sertxd("+")
goto start

show46:
pause 100
sertxd("p")
goto start

show47:
pause 100
sertxd("l")
goto start

show48:
pause 100
sertxd(",")
goto start

show49:
pause 100
sertxd("Clr")
goto start

show50:
pause 100
sertxd("^")
goto start

show51:
pause 100
sertxd("=")
goto start

show52:
pause 100
sertxd("Rshift")
goto start

show53:
pause 100
sertxd("?")
goto start

show54:
pause 100
sertxd("*")
goto start

show55:
pause 100
sertxd(";")
goto start

show56:
pause 100
sertxd("/")
goto start

show57:
pause 100
sertxd("F7")
goto start

show58:
pause 100
sertxd("F5")
goto start

show59:
pause 100
sertxd("F3")
goto start

show60:
pause 100
sertxd("F1")
goto start

show61:
pause 100
sertxd(27)
goto start

show62:
pause 100
sertxd(13)
sertxd(10)
goto start

show63:
pause 100
sertxd("L/E")
goto start

show64:
pause 100
sertxd("U/D")
goto start






 

hippy

Ex-Staff (retired)
The more efficient way to do it would be to cycle through the output driving pins one at a time, read the entire pins input, then cycle through those looking for any bit set, then, knowing which output was set and which bit was set, use a lookup table to determine what to send to the PC.

That's effectively what you have, but rolled up into a tighter program. That can be considered an improvement so can be put to one side for now.

The problem I think you have is that once you've set an ouput, detected a pin input, you simply handle it, clear the strobe and start again. You are not checking the button pushed is actually released,nor waiting until it is. You'll see multiple button pushes detected every time you pass through the program loop.

If you are seeing false button pushes when no buttons are held, have you got pull-downs on the inputs ? Floating inputs can behave very strangely at times.

Also, although it doesn't affect your code, have you included diodes in series with the outputs ? If you don't have them, pushing multiple butons on the keypad can short a high output to a low output which can potentially damage the PICAXE.
 

hippy

Ex-Staff (retired)
<code><pre><font size=2 face='Courier'>Symbol keypadBits = b0 ' This must be b0 because of the bitX's used in LookDown
Symbol row = b1
Symbol keyPressed = b2

Do
For row = 0 To 7
LookUp row,(1,2,4,8,16,32,64,128),pins
keypadBits = pins
If keypadBits &lt;&gt; 0 Then
LookDown 1,(bit0,bit1,bit2,bit3,bit4,bit5,bit6,bit7),keyPressed
keyPressed = row*8 + keyPressed
SerTxd(&quot;Key Number &quot;,#keyPressed,CR,LF)
Do While pins &lt;&gt; 0 : Loop
End If
Next
Loop </font></pre></code>

Edited by - hippy on 05/04/2007 04:31:11
 

jledger

New Member
hippy,

the Do command fails the syntax checker on mine. I'm set at 28x at 4 Mhz.

if I replace the Do/Loop with a goto loop, it fails on the &quot;If keypadBits &lt;&gt; 0 Then&quot; -- Did I miss a major update somewhere?

Oldbit
 

hippy

Ex-Staff (retired)
Plus ensure Enhanced Compiler and Colour Syntax is on, View-&gt;Options-&gt;EDitor
 

jledger

New Member
hippy, you're a freakn' genius.

Looks like I've got to catch up on some new commands for programming the PICAXE, as I've missed a few things..

The code worked perfectly, it was quickly modified to output the correct ASCII codes on each key. Very nice!

Don't suppose they've added the ability to change the baud rate of SerTxd while I was gone did they? (I ran out of pins)

Jeff
 

inglewoodpete

Senior Member
Baudrate changes. That depends on what you mean. The baudrate within the PICAXE is switchable between 8 different values 0 - 7: refer to the SerOut command.
 

hippy

Ex-Staff (retired)
SETXD is fixed for whatever crystal frequency you use - 4800 @ 4MHz, 9600 @ 8MHz, 19200 @ 16MHz. The easiest way to increase it is to increase the crystal frequency ( use SETFREQ M8 on 08M, 14M, 18A and 18X ).

If you want it slower you have to use SEROUT. There is a trick which can be used, even if you've run out of output lines, and should work here.

You can take one of your row strobe outputs to keypad and also to PC RX, diode mix it with Serial Out to send data down the download cable.

When you set that output high, make sure it always stays high for a while ( longer then the time it takes to send a character ). Then when you come to do SEROUT, set the ouput low for that same time, do the SEROUT then return the output high if you need to ( you do here to re-sample pins after transmitting ).

The long high will be seen as a 'break' which the PC should ignore. You may also receive some null ($00) characters which the PC should also ignore but you may have to strip them out in your PC receiving program.

In my code example, the two main tricks used are using LOOKUP to write directly to 'pins' output rather than using an intermmediate variable, and LOOKDOWN to find the number of the first bit which has been set. LOOKDOWN is probably my least used PICAXE command, but it can be very useful at times.
 

hippy

Ex-Staff (retired)
This should allow SEROUT to be used from any pin at any baud rate ...<code><pre><font size=2 face='Courier'>Symbol keypadBits = b0 ' This must be b0 because of the bitX's used in LookDown
Symbol row = b1
Symbol keyPressed = b2
<b>Symbol strobePins = b3 </b>

Do
For row = 0 To 7
LookUp row,(1,2,4,8,16,32,64,128),<b>strobePins </b>
<b>pins = strobePins </b>
<b>Pause 10 </b>
keypadBits = pins
If keypadBits &lt;&gt; 0 Then
LookDown 1,(bit0,bit1,bit2,bit3,bit4,bit5,bit6,bit7),keyPressed
keyPressed = row*8 + keyPressed
<b>pins = 0 </b>
<b>Pause 10 </b>
<b>SerOut 0,N2400,(&quot;Key Number </b> &quot;,#keyPressed,CR,LF)
<b>pins = strobePins </b>
Do While pins &lt;&gt; 0 : Loop
End If
Next
Loop </font></pre></code>
 
Top