Searching \ for '[PIC] Matrix Keyboard Philosophy' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/microchip/devices.htm?key=pic
Search entire site for: 'Matrix Keyboard Philosophy'.

Exact match. Not showing close matches.
PICList Thread
'[PIC] Matrix Keyboard Philosophy'
2005\04\09@120315 by Josh Koffman

face picon face
I'm going to be starting a project coming up using a preexisting
keyboard assembly. It has a non symmetrical matrix though - it's not
4x4, it's 3x8 (if memory serves...it's not right in front of me at the
moment). With a 4x4, it's easy to drive 4 of the pins and scan the
other 4. But with a non symmetrical keyboard, would it be more
efficient to drive the 3 pins or the 8 pins? My thoughts are that if I
drove the 8 pins and watched the 3 pins, I'd need less pullup
resistors (useful as board space is limited). I'll sacrifice code
simplicity though, and it'd take 8 scans to read the whole keyboard.
But I only have to watch 3 pins which might be easier.

Any thoughts on the matter?

Also, I'm looking to implement a debouncing routine so that eventually
I will be able to trigger a command on the key down and the key up. My
idea so far has been to read the keyboard, and shift the result for
each key into a temp register, then look for patterns (ie 11110000 is
a keypress, 00001111 is a key release...we discussed this a few months
ago). This requires two steps though, reading the keyboard, then
comparing all the temp registers to the patterns. Anyone have a better
way?

Thanks!

Josh
--
A common mistake that people make when trying to design something
completely foolproof is to underestimate the ingenuity of complete
fools.
       -Douglas Adams

2005\04\09@131925 by Bob Axtell

face picon face
Hi, Josh,

This has been covered extensively in the archives. But here's how I do it:

I make my routine operate in the background. I set my timer-driven interrupt
to scan the keys every 10mS. I simply copy the 3 8-bit readings (3 bytes) by
setting the enables, etc. I then compare to the last two  readings. If  
all three
are the same, I then see if a bit is  set  LOW or HI, dependent on how the
switch inputs are biased. I then create a KEY VALUE which is composed of
the ENABLE bit on (0,1, or 2) and the port BIT (0..7)  and  create a 5-bit
unique key number.

Because you are waiting to accept a key only after 3 10ms- interval readings
are the same, debouncing is done automatically.

It takes only a few instructions and is errorfree.

--Bob

Josh Koffman wrote:

{Quote hidden}

--
Note: To protect our network,
attachments must be sent to
spam_OUTattachTakeThisOuTspamengineer.cotse.net .
1-866-263-5745 USA/Canada
http://beam.to/azengineer

2005\04\11@153324 by Mark Scoville

flavicon
face
Hi Josh, For debouncing see
http://www.dattalo.com/technical/software/pic/vertcnt.html ... This has got
to be the best way to debounce switches I have ever seen - ingenious. Works
great. (Thanks Scott!) For 20 years I used to do the "take 3 samples and
compare - when they all match you are debounced". Scott's way is far more
elegant and faster. I now use a 2-bit vertical counter updated every 10mS to
debounce 8 inputs at a time. Works great.

Can you use a I/O port with internal pullups? Any way you slice it you will
need 11 I/O lines (or more external hardware). I would lean toward driving
one of 3 pins (in turn) and reading in 8 switches at a time. Others may
point out valid reasons for doing something different though.

-Mark

> {Original Message removed}

2005\04\11@161302 by Mike Hord

picon face
> Can you use a I/O port with internal pullups? Any way you slice it you will
> need 11 I/O lines (or more external hardware).

Not entirely true.  It would be possible to do this 8x3 with one pin (tough)
or 3 pins (easier), IF you pick the right pin(s); I guess this DOES fall under
"more external hardware", although that hardware is just resistors.

By using a pullup resistor on the columns and a pulldown on the rows (or
vice-versa), you can create a voltage divider which will produce a different
voltage depending on the button pressed.  Use a different resistance for
each row.  Now you can poll each of three ADC pins and, if the value is
in the right range, you know a valid button press has occured.

Not necessarily the best possible way, from a CPU overhead/software
simplicity point of view, but it's pretty easy on the pin count.

Mike H.

2005\04\11@164853 by Mark Scoville

flavicon
face
1-pin? Ok fine. I dare you... Let's see you do it with 0 pins! :)

That's why I put the "more external hardware" qualifier. Resistors are
external hardware. I'll have to think about the 1-pin solution. Seems like
it would be a challenge to be able to detect multiple keys pressed at the
same time. Gee Whiz, Thanks a lot Mike. Now I gotta think about this all
night :)

-Mark

> {Original Message removed}

2005\04\11@175800 by Mike Hord

picon face
> 1-pin? Ok fine. I dare you... Let's see you do it with 0 pins! :)
>
> That's why I put the "more external hardware" qualifier. Resistors are
> external hardware. I'll have to think about the 1-pin solution. Seems like
> it would be a challenge to be able to detect multiple keys pressed at the
> same time. Gee Whiz, Thanks a lot Mike. Now I gotta think about this all
> night :)

One pin is a sub case of 3 pins.  Detecting multiple key presses
becomes more complicated the fewer pins you try to use, and
error catching becomes more difficult.

For example, 8 keys per pin means 8 discrete values between, say, 0-5V
(we'll be easy on ourselves for this example ;-).  That means we should
pick our resistors such that the 0th key on the row is 0 volts, the 1st key
is .625V, and so on, with no key at all being 5V.  Figure out your error
tolerance (due to temperature variations, resistor tolerance, phases of
the moon (resistor tolerance will probably swallow the others in most
cases)), and any measured resistance outside of the acceptable error
is ignored as a multiple key press.

Go to all 24 keys on one pin and it becomes increasingly difficult to
catch those "out-of-range" errors, since the acceptable values get to
being quite close to one another.  Still doable.

I originally hit upon this method trying to put a keyboard and an LCD
onto an 18-pin PIC (the dreaded 18F1320, in fact), along with some
other stuff.  This was the only way I could figure to do it, and it has
worked like a champ.

It's also suggested in the Microchip "Tips 'n Tricks" pdf.  I forget the
actual title, but that phrase sums it up nicely.

Mike H.

2005\04\11@184500 by Jose Da Silva

flavicon
face
On April 11, 2005 02:57 pm, Mike Hord wrote:
> > 1-pin? Ok fine. I dare you... Let's see you do it with 0 pins! :)
> >
> > That's why I put the "more external hardware" qualifier. Resistors
> > are external hardware. I'll have to think about the 1-pin solution.
> > Seems like it would be a challenge to be able to detect multiple
> > keys pressed at the same time. Gee Whiz, Thanks a lot Mike. Now I
> > gotta think about this all night :)

Yup, you can read multiple keys, but you can't quite do it in the manner
Mike is suggesting. Mike is close, but has to change his resistor
ladder to R, 2R, 4R.... to catch multiple keypresses and I wouldn't
recommend going more than 5 buttons on a plain PIC pin (using the
method kRC = T), or 7 buttons on an analog input since by the 7th
button you're at 64R (getting close to 1% tolerance values) .

2005\04\11@190638 by Harold Hallikainen

face picon face


> Yup, you can read multiple keys, but you can't quite do it in the manner
> Mike is suggesting. Mike is close, but has to change his resistor
> ladder to R, 2R, 4R.... to catch multiple keypresses and I wouldn't
> recommend going more than 5 buttons on a plain PIC pin (using the
> method kRC = T), or 7 buttons on an analog input since by the 7th
> button you're at 64R (getting close to 1% tolerance values) .


How about just going R, 2R like an R-2R D/A? It's simplest if your
switches are SPDT and switching between +5 and ground. You could use
resistor networks where the matching between resistors is much better than
the absolute tolernance.

Harold


--
FCC Rules Updated Daily at http://www.hallikainen.com

2005\04\11@190727 by Mike Hord

picon face
> Yup, you can read multiple keys, but you can't quite do it in the manner
> Mike is suggesting. Mike is close, but has to change his resistor
> ladder to R, 2R, 4R.... to catch multiple keypresses and I wouldn't
> recommend going more than 5 buttons on a plain PIC pin (using the
> method kRC = T), or 7 buttons on an analog input since by the 7th
> button you're at 64R (getting close to 1% tolerance values) .

I didn't specify any values, actually, because I wanted that to be an
exercise for the original poster, if he chose to use that method.

Mike H.

2005\04\11@191426 by Bob Axtell

face picon face
I just wanted to add that this is being used heavily in many expensive
surveillance cameras
Uses a single input pin to handle a host of switch inputs. They publish
the R values to be
used at each switch. Since the unswitched value is 5V, and there are
about 8 switches, it
works out that each diffferent level is only about 0.7V.

I used a CD4051 and 1% Rs to control the camera with me PIC. Very nice.

--Bob

Harold Hallikainen wrote:

{Quote hidden}

--
Note: To protect our network,
attachments must be sent to
.....attachKILLspamspam@spam@engineer.cotse.net .
1-866-263-5745 USA/Canada
http://beam.to/azengineer

2005\04\11@194430 by Jose Da Silva

flavicon
face
On April 11, 2005 04:06 pm, Harold Hallikainen wrote:
> > Yup, you can read multiple keys, but you can't quite do it in the
> > manner Mike is suggesting. Mike is close, but has to change his
> > resistor ladder to R, 2R, 4R.... to catch multiple keypresses and I
> > wouldn't recommend going more than 5 buttons on a plain PIC pin
> > (using the method kRC = T), or 7 buttons on an analog input since
> > by the 7th button you're at 64R (getting close to 1% tolerance
> > values) .
>
> How about just going R, 2R like an R-2R D/A? It's simplest if your
> switches are SPDT and switching between +5 and ground. You could use
> resistor networks where the matching between resistors is much better
> than the absolute tolernance.

The resistor network is a good idea, but you wouldn't want to use 8
buttons on an 8bit analog input. Step back to 7 or 6 buttons unless you
use a higher res analog input.
>From a manufacturing point of view, I don't like having both power lines
on the same leg of a switch, but yes, the SPDT 0v/5v idea works if you
can use SPDT.

2005\04\12@025604 by Jose Da Silva

flavicon
face
On April 11, 2005 04:07 pm, Mike Hord wrote:
> > Yup, you can read multiple keys, but you can't quite do it in the
> > manner Mike is suggesting. Mike is close, but has to change his
> > resistor ladder to R, 2R, 4R.... to catch multiple keypresses and I
> > wouldn't recommend going more than 5 buttons on a plain PIC pin
> > (using the method kRC = T), or 7 buttons on an analog input since
> > by the 7th button you're at 64R (getting close to 1% tolerance
> > values) .
>
> I didn't specify any values, actually, because I wanted that to be an
> exercise for the original poster

might help to specify it's homework next time.  :-(

2005\04\12@103945 by Robert Rolf

picon face
Harold Hallikainen wrote:
>
>>Yup, you can read multiple keys, but you can't quite do it in the manner
>>Mike is suggesting. Mike is close, but has to change his resistor
>>ladder to R, 2R, 4R.... to catch multiple keypresses and I wouldn't
>>recommend going more than 5 buttons on a plain PIC pin (using the
>>method kRC = T), or 7 buttons on an analog input since by the 7th
>>button you're at 64R (getting close to 1% tolerance values) .
>
> How about just going R, 2R like an R-2R D/A? It's simplest if your
> switches are SPDT and switching between +5 and ground. You could use
> resistor networks where the matching between resistors is much better than
> the absolute tolernance.

So why not use a cheap 8 bit D/A if you have on one
10 bit A/D PIC pin available? Use pullup/pulldown and you can get
away with just SPST switches.

R

2005\04\12@150521 by Jose Da Silva

flavicon
face
On April 12, 2005 07:39 am, Robert Rolf wrote:
> Harold Hallikainen wrote:
> >>Yup, you can read multiple keys, but you can't quite do it in the
> >> manner Mike is suggesting. Mike is close, but has to change his
> >> resistor ladder to R, 2R, 4R.... to catch multiple keypresses and
> >> I wouldn't recommend going more than 5 buttons on a plain PIC pin
> >> (using the method kRC = T), or 7 buttons on an analog input since
> >> by the 7th button you're at 64R (getting close to 1% tolerance
> >> values) .
> >
> > How about just going R, 2R like an R-2R D/A? It's simplest if your
> > switches are SPDT and switching between +5 and ground. You could
> > use resistor networks where the matching between resistors is much
> > better than the absolute tolernance.
>
> So why not use a cheap 8 bit D/A if you have on one
> 10 bit A/D PIC pin available? Use pullup/pulldown and you can get
> away with just SPST switches.

That is basically what the last reply describes except you are proposing
what I think is an electronic solution (allowing you to use SPST) while
the previous uses passive components (which requires SPDT).

Personally, I think it would be easier to supply a passive resistor
ladder, versus an electronic D/A which may possibly be sourced by only
a few vendors.

My suggestion was an kRC=T spinoff of this idea:
ww1.microchip.com/downloads/en/AppNotes/00512e.pdf
in which you vary R, but the latter idea of using SPDT between 0v/5v has
the advantage of not having to wait for C to charge to a crossing-point
but requires that the input pin has to be A/D to read the value.

There are other ideas in the archives....
Basically, if your idea works and fits your needs, then it's right for
you.

2005\04\12@181351 by Josh Koffman
face picon face
OK, thanks for all the ideas guys. The analog trick is neat (though
this wasn't the first time I'd seen it), however I have spare I/O, my
priority is getting parts count down. I have to cram this circuit into
an existing case, and I'd like to try and do this surface mount single
sided (etching the boards myself)...so...extra resistors, etc...well,
not so welcome. Maybe I will use the internal pullups on portb, then
just scan the three row lines. I had originally nixed that idea so I
could keep programming lines free for ICSP, but if they're only
connected to a switch, and the switch is normally open...they are free
as along as I'm not pressing a switch. Bonus! I will check out Scott's
vertical counters...I remember it from awhile back, but I can't
remember if I understood it enough to use it. On my way there now!

Josh
--
A common mistake that people make when trying to design something
completely foolproof is to underestimate the ingenuity of complete
fools.
       -Douglas Adams

2005\04\12@230430 by Harold Hallikainen

face picon face
The "analog trick" is interesting. Where only one switch at a time is
closed, I've used a resistor network to make a voltage divider with
several taps. I then use SPDT switches to tap off the voltage divider to
the A/D input on the PIC. The signal is "looped through" the NC contacts
of the other switches so we end up with a sort of priority encoding. This
prevents an invalid input if more than one switch is pressed. Instead,
just the switch "closest" to the PIC is recognized.

I've used a similar technique to "encode" 15 momentary switches on a pair
of wires that are across the room somewhere. Multiple sets of boxes can be
put across the same pair of wires to put several switch sets in a room.

As a previous poster mentioned, I also like to TRY to leave RB6 and RB7
free for the ICD-2 for debugging. Of course, you can connect switches or
other I/O to these pins as long as they don't interfere with the ICD. My
luck (or lack of luck) has been that the part of code that needs the most
debugging is, of course, the stuff on RB6 and RB7.

Finally, on scanning matrix keyboards, I've generally set the column lines
high, then put them low one at a time and watch the row lines. If the user
presses enough keys simultaneously, you end up with two columns shorted
together, shorting a high output to a low output on the PIC. Not real
good... I should probably add some current limit resistors in series with
these lines, but that's more parts!

Harold

--
FCC Rules Updated Daily at http://www.hallikainen.com

2005\04\13@054851 by ThePicMan

flavicon
face
At 20.04 2005.04.12 -0700, you wrote:
{Quote hidden}

Or e.g. a 1N4148 diode for each key and the problem is completely solved.

2005\04\13@054914 by Gerhard Fiedler

picon face
Harold Hallikainen wrote:

> Finally, on scanning matrix keyboards, I've generally set the column lines
> high, then put them low one at a time and watch the row lines. If the user
> presses enough keys simultaneously, you end up with two columns shorted
> together, shorting a high output to a low output on the PIC. Not real
> good... I should probably add some current limit resistors in series with
> these lines, but that's more parts!

Why don't you tri-state the output lines that you don't read? No need for
extra parts, and no chance of connecting two outputs together.

Gerhard

2005\04\13@115725 by Harold Hallikainen

face picon face

> Harold Hallikainen wrote:
>
>> Finally, on scanning matrix keyboards, I've generally set the column
>> lines
>> high, then put them low one at a time and watch the row lines. If the
>> user
>> presses enough keys simultaneously, you end up with two columns shorted
>> together, shorting a high output to a low output on the PIC. Not real
>> good... I should probably add some current limit resistors in series
>> with
>> these lines, but that's more parts!
>
> Why don't you tri-state the output lines that you don't read? No need for
> extra parts, and no chance of connecting two outputs together.
>
> Gerhard


Excellent idea! Just write to the TRIS instead of LAT! And, it takes no
parts!

Thanks!

Harold
"The ideal design has zero parts."


--
FCC Rules Updated Daily at http://www.hallikainen.com

2005\04\14@082948 by Gerhard Fiedler

picon face
Harold Hallikainen wrote:

>> Why don't you tri-state the output lines that you don't read? No need for
>> extra parts, and no chance of connecting two outputs together.

> Excellent idea! Just write to the TRIS instead of LAT! And, it takes no
> parts!

Just don't forget that these "outputs" are now usually floating inputs
while tri-stated. So you should make sure that they never stay long in that
state. This usually is given, as you usually poll quickly and cyclically
through all drive lines.

The "proper" approach would be pull-ups on the output lines. But that's
extra parts, and equal in parts count to your approach of series resistors
in the output lines.

Gerhard

2005\04\14@083817 by Michael Rigby-Jones

picon face


{Quote hidden}

Or use PORTB with it's internal pullups.

Regards

Mike

=======================================================================
This e-mail is intended for the person it is addressed to only. The
information contained in it may be confidential and/or protected by
law. If you are not the intended recipient of this message, you must
not make any use of this information, or copy or show it to any
person. Please contact us immediately to tell us that you have
received this e-mail, and return the original to us. Any use,
forwarding, printing or copying of this message is strictly prohibited.
No part of this message can be considered a request for goods or
services.
=======================================================================

2005\04\14@120440 by Harold Hallikainen

face picon face

>>
>>The "proper" approach would be pull-ups on the output lines.
>>But that's extra parts, and equal in parts count to your
>>approach of series resistors in the output lines.
>
> Or use PORTB with it's internal pullups.
>

I agree that we should be able to do it with no external resistors. If we
drive the cols and read the rows, the cols could have the latch register
holding 0x00 and TRIS holding 0xff. As each col is to be driven the
appropriate bit of the TRIS would be set low, causing that col output to
be pulled low. We'd then read the row on a portb input with internal
pull-up. If a key is down, we detect the row of the key on portb and the
col based on which TRIS bit we set low. If multiple keys are down, we
could have trouble figuring out which ones they are, but could throw out
multiple keys as invalid. Also, if keys in a couple cols are low, the use
of TRIS prevents us from getting an output high to output low short. Of
course we DO have floating inputs on the col lines that are not being
pulsed low at the time, but I expect that with a typical scan rate the
lines would tend to stay low based on their last being driven low. This
should prevent excess power dissipation due to an intermediate level on a
PIC digital input.

So, use of TRIS to simulate an open drain output (pull low, but not pull
high) is interesting.

Harold



--
FCC Rules Updated Daily at http://www.hallikainen.com

2005\04\14@130526 by Alvaro Deibe Diaz

picon face
> >>The "proper" approach would be pull-ups on the output lines.
> >>But that's extra parts, and equal in parts count to your
> approach of
> >>series resistors in the output lines.
> >
> > Or use PORTB with it's internal pullups.

I think we had problems with switches in pins with pull-ups. The PIC
pull-ups were a little on the weak side, and the environmet was very noisy
(big AC machines switching on and off in the nearby). This was IIRC with a
PIC12CE674. Watch the noise.

No problem with matrix keyboards and PIC pull-ups in other projects,
thought.


More... (looser matching)
- Last day of these posts
- In 2005 , 2006 only
- Today
- New search...