Author Topic: Fun Project: Using only one analog pin for a 5 keys kepad  (Read 10595 times)

0 Members and 1 Guest are viewing this topic.

Offline Rick LawTopic starter

  • Super Contributor
  • ***
  • Posts: 3442
  • Country: us
Fun Project: Using only one analog pin for a 5 keys kepad
« on: August 07, 2016, 03:10:53 am »
Many of us at time wish we have more IO pins for the Arduino.  I got used to a 5-key keypad I made early on.  But using up 5 digital pins on the ATMEGA328 is using up a lot.  So, I got into this experiment to see if I can use one single analog pin to support 5 tact-switches with a voltage divider alone.

The design is simple: just a voltage divider setup with each tact-switch shorting out the specific resistor of specific value for that specific key.


Net-net is, it works!  The 10bit ADC has just good enough resolution to do the job for 5-keys.  It can discern all 32 combinations 00000 to 11111 easily.  Easily means results are not ambiguous and with a reasonable margin for safety.    The center key is ENTER (1K), then UP (2K), RIGHT (4K), DOWN (8K), LEFT (16K).

EDIT: before you ask...  I use 3K+1K for the 31K, 2K+2K for the 4K, so on.  That is why there are so many resistors.

I had some misconceptions before I actually thought this thought.  So experience to share:

-  Before I thought it through, with the USB power going through diode drop and deltas with different 5V regulator, I though that is a show stopper.  If that isn't enough, high current draw causing a drop is another show stoppers.  In actually doing the feasibility analysis, these kinds of voltage drop turns out to be irrelevant - as long as it is stable at the time of key press, that the board is running a good bit below 5V doesn't matter.   The ADC count is the fractions of supplied voltage, and giving fractions of supplied voltage is exactly what voltage dividers do.  So, there is even no need to convert counts to actual volts.  The ADC counts alone suffice.

-  The logic of choosing resistor values as 2^n was obvious, so I use 1K, 2K, 4K, 8K, 16K.  What was less obvious to me, a novice, is the choice of R-Reference.  The minimum change in voltage is when Key0 is pressed (ie: 1K resistor is shorted).  I need the minimum change to be as big as possible so the ADC can easily see the change.   When I actually do the math for the best R-Reference, I realized function has a max: 31K.  Even when maximized, the smallest theoretical change is just 8.4 counts on the ADC.  Per datasheet, ATMEGA328 ADC is rated +/- 2 counts, so it can comfortably discern an 8-counts change.

-  Using 2^n resistor value makes the math easier.  But, 8-count is 8/1023=0.78%.  With 1% parts, I need to use the measured value instead of the nominal value - which means I need to store the measured values.   Net-net: using a data-table of results actually use less flash-space, faster, and easier to code.  I ended up just storing the 32 actual ADC values in an array int[32] rather than calculating it on-the-fly.  For the compare, I use:
    for (idx=0;idx<31;idx++) { // if nothing matched, assume it is 31 - no key pressed
      if (stored[idx]-4 <=  adcValue  &&  adcValue <=  stored[idx]+4) break;
    }
    // now idx has the key combination

-  To see if the actual ADC counts varies against environment, I switched between different Arduino boards, different power source, different power drain, so on.  Thus far, I have not seen the counts change more than 2 counts.  So a tolerance of 4 works very nicely even when I switch the keypad and between different setups.

-  Draw back is, for every such keypad (with its resistors), one needs to get the 32 actual ADC values specific to that keypad.
« Last Edit: August 07, 2016, 03:33:01 am by Rick Law »
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: Fun Project: Using only one analog pin for a 5 keys kepad
« Reply #1 on: August 07, 2016, 03:35:38 am »
The arduino screen plus keypad uses analog buttons too. And others before that. No need for 2-based resistors either.

Try to make your code recognize multiple key presses and add denounce too.
================================
https://dannyelectronics.wordpress.com/
 

Offline Rick LawTopic starter

  • Super Contributor
  • ***
  • Posts: 3442
  • Country: us
Re: Fun Project: Using only one analog pin for a 5 keys kepad
« Reply #2 on: August 07, 2016, 03:39:29 am »
The arduino screen plus keypad uses analog buttons too. And others before that. No need for 2-based resistors either.

Try to make your code recognize multiple key presses and add denounce too.

What's the fun in just buying!

This setup recognizes multiple key presses.  5 keys = 32 combinations from 00000 to 11111.

(Sorry, can't resist) Not only do I denounce the keys, I denounce the whole machine when it doesn't work - with language too harsh to repeat.
« Last Edit: August 07, 2016, 03:41:54 am by Rick Law »
 

Offline boffin

  • Supporter
  • ****
  • Posts: 1027
  • Country: ca
Re: Fun Project: Using only one analog pin for a 5 keys kepad
« Reply #3 on: August 07, 2016, 04:40:00 am »
You're wasting half the resolution of the A/D by using 31K reference.  Drop that to 1K and you'll get a much bigger range across the AD, and probably a little more consistency.
 

Offline voltsandjolts

  • Supporter
  • ****
  • Posts: 2300
  • Country: gb
Re: Fun Project: Using only one analog pin for a 5 keys kepad
« Reply #4 on: August 07, 2016, 10:47:06 am »

Quote
Draw back is, for every such keypad (with its resistors), one needs to get the 32 actual ADC values specific to that keypad.

You could have a calibration routine, get user to press each key in turn.
 

Offline b_force

  • Super Contributor
  • ***
  • Posts: 1381
  • Country: 00
    • One World Concepts
Re: Fun Project: Using only one analog pin for a 5 keys kepad
« Reply #5 on: August 07, 2016, 11:13:28 am »
If you're thinking smart, you could even use a potentiometer AND switches at the same time.

Offline Rick LawTopic starter

  • Super Contributor
  • ***
  • Posts: 3442
  • Country: us
Re: Fun Project: Using only one analog pin for a 5 keys kepad
« Reply #6 on: August 07, 2016, 06:28:30 pm »
If you're thinking smart, you could even use a potentiometer AND switches at the same time.

Good thought - use the VR like an encoder.  Would be fun to think that through next time around.


Quote
Draw back is, for every such keypad (with its resistors), one needs to get the 32 actual ADC values specific to that keypad.

You could have a calibration routine, get user to press each key in turn.

Yup, I did that the first go round...

But first, it is not the calibration trouble but the lost of portability.  Pressing 32 key-combos and type in the ADC count is easy.  But needing keypad-dependent calibration data means codes I would bind the Arduino to the keypad.  I have two  5keys keypads (5 digital pins kind) "at large" that I plug into different Arduinos each playing with different things.  Needing pad-individual data in the program or the eeProm defeats that.

So I have very tentative plans to try an ATTINY85-driven I2C keypad just for the fun of it.  Ideally ATTINY13a, but I doubt I2C could be done with 1K flash.

Back to storing individual resistor values:

I needed only int[6] to store the resistor values but the evaluation needs float to do the math.  That math ended up using a lot more flash (code) space.  So I changed it to minimal code and store the entire int[32].

I have plans to test a bit-field array and how much code space that would take.  The theoretical max is 511 counts, so 9 bit per element would be just right, but I plan to do full 10 bits for future full adc resolution "enhancement" to this silly little thing.  uint9_t[32] would take 36 bytes.  uint10_t[32] would take 40.

Messing around with that is the fun part of it.




 

Offline Rick LawTopic starter

  • Super Contributor
  • ***
  • Posts: 3442
  • Country: us
Re: Fun Project: Using only one analog pin for a 5 keys kepad
« Reply #7 on: August 07, 2016, 07:36:37 pm »
You're wasting half the resolution of the A/D by using 31K reference.  Drop that to 1K and you'll get a much bigger range across the AD, and probably a little more consistency.

Good spot but wrong!   I had the exact same misconception at the start.

With such a simple little contraption, I started with using just my gut feel alone and I too selected 1K as R-reference at the get-go.  But the thing doesn't work.  It forced me to sit down and do the math and rethink what I thought I knew.  That is a reason I wrote the OP, and talked about misconceptions.

The change in counts is what tells if a key is pressed.  So, what is important here is not the range but the delta.  What one gained by having a larger range are lost many times over by having a much smaller delta.

Here is the math:

First the method of translating into counts:
Using Rs for R(switches, adding the 1K to the 16K)
Using Rr for R(reference)
Therefore, total divider resistance = Rs+Rr
The proportion that feed the ADC  = Rs/(Rs+Rr)
Converting that into counts = 1023*(Rs/(Rs+Rr))

With 1K Refrence:
Rs = 31K with 1K switch NOT pressed,
Rs = 30K with 1K switch pressed thus shorting it.
Rf = 1K
Switch NOT pressed: 1023*(Rs/(Rs+Rr))=1023*(31/(31+1)) = 1023*31/32=991.031250
Switch IS    pressed: 1023*(Rs/(Rs+Rr))=1023*(30/(30+1)) = 1023*30/31=990.000000

This is a 1.03 counts change when the 1K key is pressed and 1 count is what I saw in the first implementation.  With merely a 1 count delta, it can hardly tell whether the 1K is pressed at all.

With 31K Refrence:
Rs = 31K with 1K switch NOT pressed,
Rs = 30K with 1K switch pressed thus shorting it.
Rf = 31K
Switch NOT pressed: 1023*(Rs/(Rs+Rr))=1023*(31/(31+31)) = 1023*31/62=511.500000
Switch IS    pressed: 1023*(Rs/(Rs+Rr))=1023*(30/(30+31)) = 1023*30/61=503.114754

This is an 8.38 counts change when the 1K key is pressed.  An 8 counts change is what I saw after I replaced the 1K reference with the mathematically derived 31K resistor.

---

If implementation permits, a better way is to use another voltage divider for AREF.  Say 31K+31K and use the center to feed the AREF.  So, ADC full count is the same as the full count for 31K(ref)+31K(switch).

That is how I plan to do it if/when I do a ATTINY85-I2C-keypad.  With the entire ATTINY85 for the job, I can change the AREF without affecting the host-Ardunino - whichever Arduino I plan to use the keypad on.

[EDIT: The first write-up with verbose explanation was awful and way too hard to read.  Reworded.]
« Last Edit: August 07, 2016, 09:15:07 pm by Rick Law »
 
The following users thanked this post: thm_w

Offline boffin

  • Supporter
  • ****
  • Posts: 1027
  • Country: ca
Re: Fun Project: Using only one analog pin for a 5 keys kepad
« Reply #8 on: August 09, 2016, 10:45:09 pm »

Good spot but wrong!   I had the exact same misconception at the start.

How wonderfully un-obvious.  You're quite right in that by wasting half the range of the AD you get a little more consistency between button presses, my brain says it's wrong initially, but pumping the numbers in you're quire right.  However, even 8 counts is still < 1% so I'm not sure it's a great solution for 5 buttons.  Drop it to 3 or 4....., or situations where there are distinct buttons (not multiple presses) and reliability will go way up.

 

Offline bitseeker

  • Super Contributor
  • ***
  • Posts: 9057
  • Country: us
  • Lots of engineer-tweakable parts inside!
Re: Fun Project: Using only one analog pin for a 5 keys kepad
« Reply #9 on: August 10, 2016, 12:03:54 am »
Thanks, Rick. This project has more to it than initially meets the eye.
TEA is the way. | TEA Time channel
 

Offline ludzinc

  • Supporter
  • ****
  • Posts: 506
  • Country: au
    • My Misadventures In Engineering
Re: Fun Project: Using only one analog pin for a 5 keys kepad
« Reply #10 on: August 10, 2016, 01:14:21 am »
It's interesting to see where people's exploration takes them.

So to expand on this idea, why not use an R2R ladder?
https://en.wikipedia.org/wiki/Resistor_ladder

Made a 5 bit D2A, feed your 1024 bit A2D and just like that you have a 32 count minimum difference between all possible button states. 



With 1% resistors and 5 bits of resolution, totally do-able.

 

Offline bobaruni

  • Regular Contributor
  • *
  • Posts: 156
  • Country: au
Re: Fun Project: Using only one analog pin for a 5 keys kepad
« Reply #11 on: August 10, 2016, 03:07:08 am »
Another way....
Make the switches common ground for safety and usability, and using only 4 resistors, it's possible to have 5 switch inputs by enabling the internal pull up on the ADC input.


 

Offline LabSpokane

  • Super Contributor
  • ***
  • Posts: 1899
  • Country: us
Re: Fun Project: Using only one analog pin for a 5 keys kepad
« Reply #12 on: August 10, 2016, 03:46:56 am »
This is an OK way of multiplexing keys to a single pin, but get a dirty switch contact and you'll start getting erroneous inputs. 
 

Offline ludzinc

  • Supporter
  • ****
  • Posts: 506
  • Country: au
    • My Misadventures In Engineering
Re: Fun Project: Using only one analog pin for a 5 keys kepad
« Reply #13 on: August 10, 2016, 03:53:27 am »
This is an OK way of multiplexing keys to a single pin, but get a dirty switch contact and you'll start getting erroneous inputs.

Just filter / fix it in software :)
 

Offline LabSpokane

  • Super Contributor
  • ***
  • Posts: 1899
  • Country: us
Re: Fun Project: Using only one analog pin for a 5 keys kepad
« Reply #14 on: August 10, 2016, 06:28:44 am »
This is an OK way of multiplexing keys to a single pin, but get a dirty switch contact and you'll start getting erroneous inputs.

Just filter / fix it in software :)

This issue is different than a simple debounce fix. Even crappy eBay microswitches put out sweet square waves, but get a bad switch and it's easy for the micro to read a different, but legitimate value.
 

Offline Rick LawTopic starter

  • Super Contributor
  • ***
  • Posts: 3442
  • Country: us
Re: Fun Project: Using only one analog pin for a 5 keys kepad
« Reply #15 on: August 10, 2016, 06:52:10 am »

Good spot but wrong!   I had the exact same misconception at the start.

How wonderfully un-obvious.  You're quite right in that by wasting half the range of the AD you get a little more consistency between button presses, my brain says it's wrong initially, but pumping the numbers in you're quire right.  However, even 8 counts is still < 1% so I'm not sure it's a great solution for 5 buttons.  Drop it to 3 or 4....., or situations where there are distinct buttons (not multiple presses) and reliability will go way up.

"re:my brain says it's wrong initially"

Yeah...  I had a shock too.  I was mind-locked on accuracy.  After doing the math about 3 times to make sure I was right, I had to rethink and I realize it was the deltas/derivatives I should be looking at.

That 8 counts <1% really gives me the chill in "deploying" it as a solution.  If I can put a voltage divider and drop the AREF to 2.5V, that would make it easier to swallow.

The result shows doing a 3 key keypad with a single analog line should be (for lack of a better term) a slam dunk!  No sweat, easy as pie...

But - rather than the "easy as pie" solution, I am going to throw an ATTINY85 at this 5 keys keypad.  The TINY's only job will be just an I2C analog keypad so I can modify AREF (maintaining portability between Arduinos).  See what other lessons I can learn.
 

Offline Rick LawTopic starter

  • Super Contributor
  • ***
  • Posts: 3442
  • Country: us
Re: Fun Project: Using only one analog pin for a 5 keys kepad
« Reply #16 on: August 10, 2016, 07:41:23 am »
This is an OK way of multiplexing keys to a single pin, but get a dirty switch contact and you'll start getting erroneous inputs.

Just filter / fix it in software :)

This issue is different than a simple debounce fix. Even crappy eBay microswitches put out sweet square waves, but get a bad switch and it's easy for the micro to read a different, but legitimate value.

Yup.  Besides a bad switch, a real key press change during sampling can occur.

I sample the ADC 8 times to stretch the resolution.  It takes 1 to 2 ms.  It is entirely possible that a real key press change occurs.  If the first 4 ADC-read was the 4K switch and the second 4 ADC-read was the 2K switch, I could easily have a false match for the 1K+2K switch.  (Not a perfect match,.  Only numerator changed by perfect average value but the denomintors changed differently.)

With each of the 8 samples, I start over if abs(thisRead - lastRead)>4.  4 is my selected tolerance since the smallest delta caused by a key change should be 8.4.  That gives me some measure of safety, but I have not yet done the analysis to determine how close to the cliff I am.

But for the fun... else this analog keypad is a suitable only for ones suffering a serious case of digital pin famine.
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: Fun Project: Using only one analog pin for a 5 keys kepad
« Reply #17 on: August 10, 2016, 10:51:52 am »
"So to expand on this idea, why not use an R2R ladder? "

Woukd definitively work - have used it before.

A minor tweak: switch's are often used active low. Flipping your schematic will make it so.
================================
https://dannyelectronics.wordpress.com/
 

Offline wraper

  • Supporter
  • ****
  • Posts: 16864
  • Country: lv
Re: Fun Project: Using only one analog pin for a 5 keys kepad
« Reply #18 on: August 10, 2016, 11:19:58 am »
This is an OK way of multiplexing keys to a single pin, but get a dirty switch contact and you'll start getting erroneous inputs.

Just filter / fix it in software :)
Seen a lot of devices fail because of this approach, especially in TVs, monitors where this approach is used quiet often. Current is too low for proper contact wetting and switch no longer can make a good contact. Also because of ion migration, tact switches often become a little bit conductive in off state and weird stuff start to happen as this approach is not resistant to a little bit of leakage.
 

Offline GK

  • Super Contributor
  • ***
  • Posts: 2607
  • Country: au
Re: Fun Project: Using only one analog pin for a 5 keys kepad
« Reply #19 on: August 10, 2016, 12:38:06 pm »
It's interesting to see where people's exploration takes them.

So to expand on this idea, why not use an R2R ladder?
https://en.wikipedia.org/wiki/Resistor_ladder

Made a 5 bit D2A, feed your 1024 bit A2D and just like that you have a 32 count minimum difference between all possible button states. 



With 1% resistors and 5 bits of resolution, totally do-able.


That won't work as a proper R2R DAC unless the switches/buttons are SPDT and wired such that each respective resistor is grounded when its switch off (logic 0).
Bzzzzt. No longer care, over this forum shit.........ZZzzzzzzzzzzzzzzz
 

Offline plazma

  • Frequent Contributor
  • **
  • Posts: 472
  • Country: fi
    • Homepage
Re: Fun Project: Using only one analog pin for a 5 keys kepad
« Reply #20 on: August 10, 2016, 01:01:09 pm »


Another way....
Make the switches common ground for safety and usability, and using only 4 resistors, it's possible to have 5 switch inputs by enabling the internal pull up on the ADC input.



Push SW5 and nothing else is recognised.
 

Offline bobaruni

  • Regular Contributor
  • *
  • Posts: 156
  • Country: au
Re: Fun Project: Using only one analog pin for a 5 keys kepad
« Reply #21 on: August 10, 2016, 02:06:25 pm »
Of course SW5 will block all others, but I was showing a way to save components (make it smaller if required, the op could easily put another resistor in series with SW5 (4K7) if simultaneous button presses are required) although this is not the best way to decode 5 simultaneous button actions!
 

Offline rrinker

  • Super Contributor
  • ***
  • Posts: 2046
  • Country: us
Re: Fun Project: Using only one analog pin for a 5 keys kepad
« Reply #22 on: August 10, 2016, 02:52:55 pm »
 Just saw one in a 2001 issue of Elektor that uses the voltage divider technique for a full 12 key keypad on one of their projects. Based on the values shown on the schematic, it looks like it would have easily handled a 16 key keypad. Not sure what micro they were connecting it to, an 80C52 variant I believe.



 

Online helius

  • Super Contributor
  • ***
  • Posts: 3642
  • Country: us
Re: Fun Project: Using only one analog pin for a 5 keys kepad
« Reply #23 on: August 10, 2016, 04:24:42 pm »
A variant of the R2R approach is used by the Alesis LRC and the Fostex 8312.
http://www.dnd.utwente.nl/~mrjb/electro/lrcdecoder/

They decode 17 different button combinations with just two wires (and know when the device is connected or not, because there is no open circuit when it's plugged in).
 

Offline Paul Price

  • Super Contributor
  • ***
  • Posts: 1419
Re: Fun Project: Using only one analog pin for a 5 keys kepad
« Reply #24 on: August 10, 2016, 05:04:07 pm »
Easy to debounce and reliable switch selection, fewest parts using common 5% resistor values. Even with 9-switches there is ~.5V between each switch for high noise immunity. Good to go with at least 10 or more switches.

Debounce code simply oversamples analog voltage measured, a sw-press is valid if the voltage for two debounce time separated readings is stable. To qualify as valid the 1st and 2nd readings for a sw. press voltage must be within the calculated voltage +/- error limits for each sw.
« Last Edit: August 10, 2016, 05:21:54 pm by Paul Price »
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf