Shop OBEX P1 Docs P2 Docs Learn Events
First ever object: 3x4 Matrix keypad decoder — Parallax Forums

First ever object: 3x4 Matrix keypad decoder

M.EarnshawM.Earnshaw Posts: 6
edited 2009-09-11 03:33 in Propeller 1
Howdy all,

Not sure if this is of any use to anyone, but I couldn't find a 3x4 matrix keypad driver that would work with the keypad I had.
So, I wrote one. smile.gif

I have put lots of comments into the code, mainly to help me out while I was coding it.
It is also my first object with the propeller, which I got only 2 weeks ago.
I haven't done any MCU coding before, but I have to say I love writing code for the prop cool.gif
Reminds me of VB / Gambas

Just finishing off a 20x4 4bit LCD driver that I have found, polished up, cleaned up and added a few methods too.
When it's done, I'll post that up as well.

Comments

  • StefanL38StefanL38 Posts: 2,292
    edited 2009-09-09 18:53
    Hello and welcome Martyn to the Propeller-forum !

    I've donwloaded your code and took a look inside.
    Your documentation is very detailed. I wish every object would be documented like that.

    Good work !

    best regards

    Stefan
  • M.EarnshawM.Earnshaw Posts: 6
    edited 2009-09-09 19:07
    Thanks for your comments smile.gif
    I always try to include lots of details with my code, makes life a lot easier in the long run.

    Thanks again.
  • JRetSapDoogJRetSapDoog Posts: 954
    edited 2009-09-09 19:43
    Yes, beautiful documentation!· Thanks for the post.· It's interesting and instructive.

    I noticed that the introductory documentation mentions the following possible future plan, "At the minute, only 1 button can be scanned at a time.· When I have more time, I will try and implement a way to accept and screen multiple different key presses at the same time."

    I'm curious about what you have in mind in saying that even though you may have just been speculating.· I believe preventing false key presses (ghosting?) when the keys in the matrix form a rectangle would require the use of diodes at every key junction·(not just rows and/or columns).· However, the keyboard probably doesn't come with those and you likely won't be opening it up to install them.

    As such, you're probably talking about something software-related and perhaps with certain limitations.· So, do you mean checking for multiple key presses in the same column, that is for simultaneous key-press combinations that don't form a rectangle?· Or do you have an alternative way of scanning the keys in mind that differs from the traditional way, such as scanning both the rows and the columns (I think I read a post here once about such a possibility linking to a cookbook with the circuit, but the details elude me).

    Anyway, no·need to respond, particularly·as you're still in the development stage.· Thanks again for the post.· It's interesting to see the number of twists that exists on keyboard (matrix) input.· Oh, and I found your comments about debounce and capacitance build-up interesting, even though I wasn't aware of the latter as a potential problem (though I can now see that it might need to be considered (perhaps others have thoughts)).
  • M.EarnshawM.Earnshaw Posts: 6
    edited 2009-09-09 20:33
    Thanks for the comments JRetSapDoog, thought I'd reply anyway smile.gif

    My comment regarding multiple key-presses was indeed regarding the software side of it .
    The private method ScanColumn already can recognise multiple key-presses on the same column.
    When read in binary, the buttons pressed will appear in the 4bit string, I was originally using this method to read off each column and dump it to my LCD.
    I have a few idea's floating about regrading implementing it, perhaps with an array output containing the last 5 or 6 keys, or perhaps a long string separated by 0's. Not sure yet.

    When I first started toying with the keypad, I used the 4x4 keypad object that comes with the Propeller tool.
    I didn't have much success with that sad.gif
    Kept on getting weird values, so I tried my own approach using the same idea - Direct connection to the propeller, but this time with the rows and columns in order to make things easier.
    I found that when I was scanning all 3 columns, residual charge would still be on the IO pins / keypad / breadboard and would cause false positives.
    I could hold key 4, and the output would vary, it's easier to see shown in 4 bit binary.
    The 4x4 keypad object makes use of this approach as a detection mechanism, but for my keypad it seemed to complicate things.
    So, I applied the pull down resistors to each row and the keypad started to behave nicely.
  • JRetSapDoogJRetSapDoog Posts: 954
    edited 2009-09-10 09:54
    Thanks, M.E., for the update (of the work in progress). Yeah, I don't need to be telling people what they "don't" need to do, lol. The more comments, the merrier!

    I hadn't scrutenized your private method; thanks for the info. Also, again, the details about the "residual charge" are interesting. Thanks for the further explanation.

    I'm looking at building a 4x4 or 4x6 "keypad" from scratch, wherein I want to be able to read all the keys simultaneously. In order to save I/O pins, I'm considering using scanning, but I'll need diodes on the keys to prevent ghosting or blocking. Although your keypad functions differently, it's interesting to read the interfacing details to possibly anticipate problems (those unexpected "gotcha's"). It's instructive to see code from others, too, to improve one's skills. Thanks again for sharing/updating.

    I wonder what the nature of that "residual charge" is, something involving the Propeller's internal pullup/pull-down circuitry in conjuction with the scanning and keys? Hmm...I'll bet if there was no propeller and keyboard, there'd be no residual charge, lol. Anyway, whatever is causing it, you seem to have dealt with it effectively by using the resistors. That's the kind of thing that might have stumped me. Good to know.
  • Beau SchwabeBeau Schwabe Posts: 6,568
    edited 2009-09-10 13:40
    JRetSapDoog,

    The "residual charge" is the basis for how the 4x4 keypad object that comes with the Propeller tool operates and I'm sure it would have worked for M.Earnshaw if he arranged all of the ROWS together followed by all of the COLUMNS or vise versa. His keypad looks to alternate the ROWS and COLUMNS.

    The way that the "residual charge" approach is supposed to work, is that you discharge all of the I/O pins. Each pin has a small amount of capacitance (a few pico Farads) ... discharge all of the I/O's by making them all OUTPUT and all LOW. Now make all of the I/O's an INPUT with the exception of one pin, make it an OUTPUT and HIGH. By reading the remainder of the I/O's, if there is a "1" present, then a button has been pressed. The pin that you make HIGH corresponds to a ROW or COLUMN and through a few passes of discharging and making the next pin in the ROW or the COLUMN HIGH you can detect exactly which keys are pressed. The time between discharging all of the IO's and then reading them back must be in a tight loop and happen very quickly.

    Another note: The leads from the I/O's to the Keypad must also be kept very short.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Beau Schwabe

    IC Layout Engineer
    Parallax, Inc.

    Post Edited (Beau Schwabe (Parallax)) : 9/10/2009 2:03:00 PM GMT
  • JRetSapDoogJRetSapDoog Posts: 954
    edited 2009-09-10 15:53
    Oh, okay, now I'm starting to see the light, Mr. Schwabe. Thanks for the explanation. I should have taken a look at your object and its documentation prior to commenting (as found in the included files with the Propeller Tool), as the capacitive approach is mentioned and explained there. I had been (incorrectly) assuming that at least one of the methods (yours or Mr. Earnshaw's) used a traditional scanning approach. Sorry, I was still in the "Newtonian" world of switches and resistors and hadn't moved up to the "Quantum" world of capacitance at an instant.

    As I read about the capacitive approach, I was trying to ascertain the advantages of the approach compared to traditional scanning (other than just the technical knowledge of another way to do things and the nice example of manipulating the I/O pins). Apparently, one of the advantages is not requiring other discrete components (resistors and capacitors). The code also seems straight forward (if not elegant), and you mention the advantage of "no danger of any physcial or electrical damage" using the method, which I presume refers to maybe the possibility of "shorting" an output set high to ground (or possibly to an input, though I don't know if that could be a problem) and likely (if not definitely) causing damage to the chip. Anyway, so the convenience of the method and simple hardware required (keypad only) are advantages.

    It's also nice that your method can basically read the whole keyboard in one go/call (except in the case of "BOX-entry combinations). However, in my case, wherein I need to be able to read the keys without the possibility of certain simultaneous key combinations causing misreads, I think I'll still need to go with a homebrew design with diodes at each key/switch in order to avoid the "BOX entry" limitation that you mentioned as being associated with the capacitive approach. Also, my matrix rows (or columns) will actually be spread out from one another, so I won't be going with a standard keypad. And my circuit or trace lengths will be somewhat longer than recommened for the capacitive approach (perhaps increasing capacitance too much to drain off using the method of the 4x4 object).

    Regarding the design not needing discrete capacitors, with my rudimentary knowledge, I wouldn't know what to do with them anyway. Perhaps they're useful for suppressing switchbounce or something. I was thinking that I might be able to deal with switchbounce in software based on time, although that'll add coding complexity. And regarding resistors, I'm still not even sure about the necessity of resistors on columns and/or rows in the traditional scanning approach (though I plan to start out that way; I just haven't decided if they'll be inline or pull-up/pull-down).

    In the simplest case, suppose I have one pin set for output (and for the sake of learning let's assume that it's constantly set high instead of scanning/toggling), and I feed it directly into a Prop pin configured for input without either an inline resistor to limit current or a pull-down resistor to ground. Is that a short waiting to happen with the output high? Or would the pin configured for input provide high impedence and allow such a direct connection? And if such a direct connection is viable, are there other disadvantages (I'm guessing the current would be low if high-z but maybe still a waste)? I realize that your capacitive approach basically connects a high output column directly to 4 input pins of a row (assuming the corresponding keys are pressed) without any resistors. However, you're only powering the column output for a row for approximately a microsecond (3 or 4 SPIN instructions), so perhaps that wouldn't overload anything even if the inputs weren't high-z.

    I know it's a simple question, but it might be helpful for others as well looking for ways to potentially blow up their Prop or avoid doing so (see, perhaps with that diode protection in the Prop, some of us have to work a little harder than others to fry our Props, J/K). Or from another angle, let's say the output pin goes low, is that a "solid enough" low that the input pin would see it as such and not floating? I don't know. One can often connect, for example, outputs of the CMOS 4000 series to inputs of other chips or to the same chip without any resistors. Just wondering about the situation with the Prop. But perhaps there could be some problems on power-up or power-down of the system that I'm not aware of. Anyway, I think I read an entry on this forum that one can do inter-COG communication using such a pair of pins (one-way, or perhaps turning it around for half-duplex (if just one pair)) and thus avoid using the hub, but I don't recall if there was a resistor involved.

    I know this is all pretty-much Ohm's-Law basic stuff, but I've been away from electronics for too long for these matters to be obvious to me. Guess I need to break out the manual and see how basic switches are typically connected, but for the case above, I need outputs to go to inputs (for scanning), not just the voltage potential of a switch to an input. Anyway, I've been feasting on the convenience of the built-in switches and an LCD display of my "off-the-shelf" (Rayman's shelf) Prop unit for too many weeks.
  • Beau SchwabeBeau Schwabe Posts: 6,568
    edited 2009-09-10 16:54
    As long as the voltage level to an INPUT pin does not exceed 3.3V or go below GND (negative voltages) you should not have a problem.

    The problem arises when the Pin is made an OUTPUT and the state of the pin (HIGH or LOW) disagrees with an external voltage on that pin. In this situation the scenario becomes a short. For this is it a good practice to place current limiting resistors on the I/O's so that the energy from the short can be dissipated within the resistor instead of the Propeller. The 4x4 Keypad object makes sure that by making either all pins LOW, or all but one pin an INPUT that there is not a chance for a disagreement to happen.

    If you are programming and you run into a similar circumstance in writing your own code, then it is the responsibility of the programmer to make certain due to any programming error that this scenario does not happen.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Beau Schwabe

    IC Layout Engineer
    Parallax, Inc.
  • JRetSapDoogJRetSapDoog Posts: 954
    edited 2009-09-11 03:33
    Thanks, again, Mr. Schwabe. Based on that, it sounds like I wouldn't be too reckless in directly connecting outputs to inputs in a scanned keyboard scenario. I'll have to try it, though it'll probably be a week or so before I can play/work with it much (even though it's simple). I presume the Propeller won't output more than 3.3V or go below GND on its own outputs, as those are it "rails." I won't have any external voltages or direct grounds attached to the OUTPUTs, as my OUTPUTs would only be connected to INPUTs. I guess I just need to make sure my diodes don't drop me below the logic level threshold of the INPUTs, but just one diode in any particular path shouldn't do that. Incidentally, I spent several minutes looking for that inter-COG communication post to resurrect for any that might be interested, but couldn't track it down. But I think your kind reply covers the same ground: if one can connect an output to an input directly, then, of course, one can do inter-COG communication that way and bypass the HUB (but one should be careful when connecting an OUTPUT to external circuitry). Also, any exploding Prop refs. were made mostly in jest. Thanks, again. --Jim, currently in Taiwan.
Sign In or Register to comment.