42 Key Keypad on 5 wires (Complete)
mikeologist
Posts: 337
This all started here in this thread.
I was having issues adding an extension to the standard 4X4 keypad in an effort to expand it with more keys. Even with the inline and pull-down resistors prescribed I was still getting cross-chatter.
The conclusion that I came to was that I needed to abandon the keypad and make a completely new one that uses diodes to prevent cross-chatter.
Several users helped and a couple of them really pushed me with new subjects to read and understand. I'm grateful for their contributions.
This is the result.
I arranged it in a 12X4 array. Thanks to VIRAND I will use a CD4040B ripple counter for the 12 input pins. I will run this with a single clock pin and no reset. Effecting a 5 pin bus that needs no resistors and suffers no power loss. Resistance is futile.
Each switch receives power from an input pin through a 1N4148 diode and passes the signal of another switch. This create a 4 bit output bus.
Each 4 switch row is read sequentially, one at a time buy pulsing the clock pin on the 4040 ic.
The spin software should be a bit simpler than the 4X4 software as it does not have to increment though input pin numbers. This will make it a single, simple loop and eliminate the frame references from multiple methods.
Due to a poorly written advertisement, my 4040s are delayed until Friday evening. So now I have to wait.
Shout-Out to Cluso99, WBA Consulting, and VIRAND for all their help.
Any comments, questions?
I was having issues adding an extension to the standard 4X4 keypad in an effort to expand it with more keys. Even with the inline and pull-down resistors prescribed I was still getting cross-chatter.
The conclusion that I came to was that I needed to abandon the keypad and make a completely new one that uses diodes to prevent cross-chatter.
Several users helped and a couple of them really pushed me with new subjects to read and understand. I'm grateful for their contributions.
This is the result.
I arranged it in a 12X4 array. Thanks to VIRAND I will use a CD4040B ripple counter for the 12 input pins. I will run this with a single clock pin and no reset. Effecting a 5 pin bus that needs no resistors and suffers no power loss. Resistance is futile.
Each switch receives power from an input pin through a 1N4148 diode and passes the signal of another switch. This create a 4 bit output bus.
Each 4 switch row is read sequentially, one at a time buy pulsing the clock pin on the 4040 ic.
The spin software should be a bit simpler than the 4X4 software as it does not have to increment though input pin numbers. This will make it a single, simple loop and eliminate the frame references from multiple methods.
Due to a poorly written advertisement, my 4040s are delayed until Friday evening. So now I have to wait.
Shout-Out to Cluso99, WBA Consulting, and VIRAND for all their help.
Any comments, questions?
Comments
The 4040 is not going to work as you describe it. It may be that I am not understanding what you posted, but I do not think so. A wiring diagram would clear that up. Main problem is that the '4040 does not change one pin at a time like the '4017 does. Some of the pins of the '4040 will be high and others low at most times.
Hmmmm. I see my mistake now. Thanks a bunch.
The 4017 only has 11 outputs. Shoot.
I've got some more reading to do :depressed:
I've got a 4017 and a 4022 on hand. Think it's possible to get a resetting 12 count out of the two?
Ok, looking into this video now. Should do it if I can stop it at the right spot.
Is only one key presses at a time?, if so google charlieplexing keypad. 7*(7-1) = 42keys.
Other way I probably would use 5 daisy chained parallel-to-serial IC's (40keys), just to keep it simple.
https://www.mouser.com/ProductDetail/Nexperia/74LV165AD-Q100J/?qs=sGAEpiMZZMtsbn1GaJyslypZg741RneR%2b1wT%2bc6bXC8=
With Schmitt-trigger, allows you to put 0.1uF cap on all keys, to eliminate pesky switch bounce.
They make key scan IC, this one is 0.65mm, many others are 0.50mm and not hobby friendly:
https://www.mouser.com/ProductDetail/ON-Semiconductor/LC75700T-TLM-E/?qs=sGAEpiMZZMuleuVm2ofeX7XEavfHLEzz
Not a fan of charlieplexing because of the extreme number of clocks and I want multi-touch.
I like that solution, nice and simple. But I'm not a fan of serial because of the unnecessary software decoding; again, just limiting the number of clocks.
I tested it on my flip, using all 16 pins and it worked flawlessly; the diodes eliminated all the chatter.
Switch Bounce:
Since my switches are mechanical they absolutely have switch bounce.
I'm using the same method that Parallax provides for the 4X4 keypad; It's a capacitive read approach. All 5 pins are set low (discharge), then all pins are set to input, the first pin(out for prop, in for keypad) is set to high. If a button is pressed it will change the capacitor state of any of the 4 read pins, rinse, repeat.
It's important to note that I only plan on reading from the keyboard 7 or 8 full read cycles per second, so I can manually time-slice it into a background task cog program.
Since this is not an interrupt circuit and since it is not edge triggered, and all the ICs are upstream from the switches, it is my opinion that switch bounce is not an issue in this circuit.
If I do find it to be an issue I will use 2X MAX6817s to apply debounce to each of the 4 output pins.
I would love to hear other analysis of these statements.
I appreciate the tips. They're great, just not what I need for my specific application.
What I'm doing is using a flip-flop(4013 maybe) to suppress/enable/reset a 4017 and a 4022, this will allow me to get nine steps from the 4017 and the last 3 from the 4022. Haven't figured it all out yet but I'm certain I can drive it with a single clock pin. Then, I'll use the 4 output pins in parallel to read and decode the keys with multi-touch and return an array of the first 5 keys captured in under 120 clocks. That's the project goal anyway. Hope I can hit it.
For my application it can't be i2c, but I see how that would work nicely and reduce pins very well.
For me must be parallel or I'll spend forever downloading and decoding the keys, relatively speaking. I'm trying to avoid having to cut clocks from my primary applications by limiting the clocks necessary for secondary applications and hardware support.
Currently, I'm working on making a single-pin flip-flop from a 4013. Any ideas there?
Reading a key/switch takes more clocks due to communication, but using the interrupt means that you only read it when necessary. Probably a net gain.
With 16 GPIO pins, a matrix could be 8x8, 12x4, etc. The general idea is described in this Microchip application note. I used this scheme years ago on a BS2P project. Full disclosure, I did not test simultaneous presses of multiple keys.
If it isn't your cup of tea, then no harm.
The PCF8575 provides an open-drain interrupt (INT) output, which can be connected to the interrupt input of a microcontroller.
An interrupt is generated by any rising or falling edge of the port inputs in the input mode.
http://www.ti.com/lit/ds/symlink/pcf8575.pdf
Appreciate it, but no decoding an imperative. I have to stick to parallel output, but thanks.
The plan is to chain 4017 and a 4022 for sequential triggering based only on a clock line. If you have any advise there I'd sure appreciate it.
I found the attached picture here
It's close but it still uses a reset and a clock. I'd like to get it down to the clock. Trying to add a capacitor to do so.
Sorry, the 4022 is also a binary counter so you would have the same problem as the 4040 has.
What should work is a 4017 and a '165 shift register. That would allow for up to 80 keys, but needs a micro (2 pins) to do the clocking and decoding. The posted doodle was an idea I had for a project that never got off the ground so I can't guarantee it will work without a bit of tweaking.
PS - you would also need to add diodes to the 4017 for protection from shorting the 4017 lines together.
Either way works but the '165 works particularly well with the 4017 and I usually have several. It also allows me to save an I/O pin by using an RC circuit to differentiate between a shift clock pulse and a load clock pulse.
I would think you should be able to do the debounce in software.
With all politeness possible, I am new to these chips so I didn't want to contradict something you said until I could prove it. So I made a the circuit that I was talking about to demonstrate the 4022 used as a decade counter.
Also, they share the same data sheet.
Here I cascaded a 4017 and a 4022 to count to 12 the off for a clock. It uses a 4027 as an SR latch for reset and clock enable, and a 555 for timing. It can easily use 2 4017s by adjusting the pin out a tiny bit.
Per your quality suggestion I will use a 1N4148 one each counter output, that probably saved me a huge headache down the road.
Your schematic is very slick and I will likely use that on a different project. I will share the results if I do. Thank you for the contribution.
For this one I need to stick to 5 pin sequenced parallel read (1+4), and it looks great so far.
Read discharge
Read charge
Clock up
Clock down
Read
Shift
Store
Jump to start
8 clocks per read channel
X 12 read channels
+ 2 clocks to reset
= 98 clocks
80MHz / 8 clocks = 10MHz required from this circuit.
I don't know if it will do it. If not I'll redesign it in 74xx.
I will post the schematic, drivers, and results as I produce them.
Thanks for helping.
Once you get to that many parts, it can pay to look at the sub 30c MCUs, like N76E003
Years ago, we used a HEF4894 ( 12 op) for one package IO expansion, but I note here in 2017, that shift-register Logic part, costs more than a N76E003 MCU !!
Even a 4017 is quite price variable, and many distis want more than the small MCUs..
We also did simple clocked key board scanners in PLDs, where a known excess pattern is sent, so no reset/sync pin is needed. Software just clocks and looks for N bits low, then knows where it is in the scan.
Costs 2 pins initially, but you can add remote keypads with one added pin.
Running at 3V, the 4000 series parts have quite feeble drive, so will not be bothered by shorted pins.
There are indeed many better choices than discreet logic for a keyboard scanner/decoder, but for a one off project making do with parts you already have or can easily get locally can be an irresistible challenge.
You are correct, it is a lot of work for a simple project and there are potentially better ways to do so, but what may have slipped by you is the extremely limited number of clocks that my setup requires to receive already decoded parallel data. I only have to raise my clock pin 13 times to complete the entire read/decode cycle; in contrast I'm curious how many clocks @ 80MHz that yours would take? (10Mhz controller read from 80MHz Prop)
I believe your suggested method requires a lot more clocks to read the keys and even more clocks to decode that data.
Also, my method uses a diode on each button and capacitive read, so it does not require a debounce circuit because it can only be triggered once before it's read/reset.
While I am saving a lot of pins over a traditional 2D matrix, I choose not to sacrifice speed to gain the last 2 pins in savings.
Now that I have it figured out on the forgiving 40xx series I need to kick it up to the 74xx chips so I can get my required 10MHz.
I appreciate your observation and directions, they make a lot of sense. I'm just going a different way, but thank you for taking the time to reply. I appreciate it
All this is assuming that I haven't misinterpreted anything; that's always a big assumption.
That MCU is the best thing I've ever seen for 2 bits ($0.25 that is).
Thank you so much for linking them.
I feel compelled to see what I can do with 100 of them. I mean I really can't think of a better way to waste $25 results to follow.
In order to use this with my project I believe it would need to read, then translate to write @ 2 clocks per my Prop clock pulse. My math says I'd need a 20MHz model to achieve my goal of a 10MHz read. Do you know of a similar MCU that runs at 20MHz? My budget is $0.70 because that's what I pay for the current 3 IC setup. I'm going to look as well.
Your alt tech solution is the only one that still gives me that parallel read that I need. I appreciate that detail.
Great Tip, thanks for taking the time!
Attached is the current implementation that works. For clarity I omitted the LED outputs and their associated 470ohm resistors.
The resistor is 4.7k
The cap is 100uf, 16v
The pot is 10k
The power rails deliver 5v.
On power up it requires 6 clocks for alignment.
Then each clock steps through this pin sequence:
1 ) 4017 Q1
2 ) 4017 Q2
3 ) 4017 Q3
4 ) 4017 Q4
5 ) 4017 Q5
6 ) 4017 Q6
7 ) 4017 Q7
8 ) 4017 Q8
9 ) 4022 Q1
10 ) 4022 Q2
11 ) 4022 Q3
12 ) 4022 Q4
13 ) ALL OFF
On each of these pulses I can read any/all of the (up to) 4 keys on the associated row, in parallel, already decoded.
Using a 1:1 case it will take another apx 120 clocks to return a single word made up of 4 chars. This is the maximum number of key presses that I'll accept.
You can see the first working model on youtube here.
This way I can use a single register for the keypad buffer.
I need 10MHz so I will need to change these out for 74xx ICs to complete this particular design. I'm also investigating @jmg great suggestion of a $0.25 MCU, but it was important for me to complete the first intended goal. I'm not one to abandon a project until the darn thing works. Guess I've got a bit of Ahab in my blood.
After I make a cleaner model for the keypad I will post the pictures, video of it working, and the Prop ASM code (by way of gcc) to drive it.
Thanks to everyone who helped so far.
If your target is smallest read clock count, then I'd suggest the N76E003 in SPI slave mode.
They claim Sysclk/2 max SPI slave speed, but I'd start testing lower than that.
That 10MHz is going to be tough on a Prop anyway, as you need to do 4 operations per bit in an unrolled loop, 5 in a loop.
So ~ 4MHz is more practical, and for 8b SPI, you only need 8 clocks, down from your 13, and decode is done in the MCU, saving more Prop code & time.
Or, you could use the 1MBd uart, for a more standard interface ?
I'd suggest toggle 1 bit every read, so you know the MCU is present and alive, plus that allows you to confirm SPI bit align, with just CLK.DAT wires.
That leaves 7 bits to encode your 48 keys - enough to do close and open signaling ?
For the most part I prefer parallel for the speed, but I may have misunderstood.
My background is in teaching 3rd and 4th level languages and their abstractions as well as discrete math. I've designed circuits using only logic gates in a simulator as a hobby for many years and I've built a number of radio kits, but this is my first foray into actual IC design.
The best way for me to tell is to build and test all three. Which is exactly what I'm going to do. I have many other pieces to build so the theory that I establish here will be quite useful.
I will have my 40xx results by the end of today, probably.
You clearly understand this better than I currently do. Do you see any problems with me remapping this same circuit (breadboard picture above) to 74xx for the next step? Specifically voltage and resistors. I am aware that the pin maps will likely be different.
I started with the 40xx because they are more forgiving. I know because I accidentally cross-wired this thing 2 or 3 times without burning anything up
After the 74xx I will read all about your uMCU and begin the diagrams. Any help you can provide after I post my initial ideas would be greatly appreciated.
I'm not sure you need HCMOS, as 4000 specs 12MHz typ at 5v, and around 4MHz is a practical/compact limit with a Prop
You might be able to use 2 x 4017, for 20 scan lines, if you wire opposite edge clocks ?
The 2 sets of 10 outputs will interleave, but for every edge one pin changes, and you look for changes.
Now there is a concept. So you are saying use both the rising and falling edges of the clock from the Prop to trigger events in my keypad?
Would you have an example of a circuit that allows for that double clock rate?
I'm happy to read and begin the integration on my own.
I've bookmarked the 74HC4017 in case I need it. Thanks a bunch.
Keypad matrices are not rocket science, I used to scan large POS terminal keyboards directly with n-key rollover, debouncing, and buffering straight from parallel I/O, in the 80's under background timer interrupts. These days if I have I/O to spare and the keypad is part of the Prop board I will scan them directly, after all that's what the cogs are for. In fact with Tachyon I don't need an extra cog, I just use my background timer cog and have an arbitrary matrix of any configuration on any spare I/O, grouped, or ungrouped. It's all built into Tachyon so there is not even a "driver" required.
Most of the time I don't have spare I/O so I either use the I2C bus pins that connect to the EEPROM which is effectively zero I/O or I use a single input pin. In the case of I2C I could use a 16-bit expander to give me 64 keys and they have their own pullups and most of the time all the columns are driven low ready to sense a key press. Once it is detected then a simple or binary scan can find the correct key. If you limit the speed you scan at it helps to prevent ghosting and bounce but software should also stop this anyway.
However most of the time I just use a very cheap micro, such as a 20-pin PIC or Silabs parts and it is just as easy to encode the keypad and send ASCII codes asynchronously or via I2C. The interesting thing is if you transmit serially at a very slow speed then this makes it easy for a background function to receive it without tying up a whole cog. So at 300 baud or 30 keystrokes per second a 1ms background tick can receive the transmission easily. This is what I basically do for a 20-key numeric keypad where I replace the tiny encoder USB interface with one of my own serial interfaces, to make it Prop friendly.
None of these methods I described requires diodes or more than a single cheap chip btw.
Some new theory for me to study, thanks.
I'm time-slicing my GUI, hypervisor, and peripherals all into one cog program.
The biggest thing that I gained from your comment is the idea of using the cheap MCU to send only the finalized key to the cog on interrupt. Thereby offloading all scan functions to the cheap MCU. I could have it scan for the interrupt every 1/8th of a second and read the key as a byte on the 4 available pins in two chunks, and in literally no time.
The N76E003 will work wonderfully for this. What do you think @jmg?
This does have caveats, as the scan looks like this
If you have buttons on same-column closed on both A.Q0 and A.Q1, then you mask seeing B.Q0, unless you use an ADC read.
You do now have 20 row scan lines, so can make the keyboard more sparse if needed.
Any 4 buttons in the same row, can sense any or all, it is the multi column case that gives issues...