Pages: [1]   Go Down
Author Topic: AnalogDebounce: New Library for debouncing Analog Keypads  (Read 2626 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Full Member
***
Karma: 1
Posts: 127
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I have a fairly complex project I am working on and I wanted to clean up the code and make some of it re-usable in the form of libraries.  One of those libraries is AnalogDebounce, a library for debouncing button keypads that utilize voltage division and analog input for single pin operation.  I could not find a single library or example for it so I made my own!

You can get the library at https://github.com/MatCat/AnalogDebounce

It will work out of the box for shields such as Cytron LCD and Keypad shield, or the SainsSmart (Which I think is identical? to the Cytron one). 

As I work on the library I will keep the GIT repo up to date and announce changes here.
Logged

Offline Offline
Full Member
***
Karma: 1
Posts: 127
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I updated the library today with the following:

int minPressTime - Miliseconds to consider before calling it a press
int repeatDelay    - Miliseconds to wait before firing a button press again while still being held down.

Also added relevant keywords context as well.
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 170
Posts: 12483
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for sharing your library!

in your code you hard code the inner array.
Code:
    adc_key_val[0] = 30;
    adc_key_val[1] = 160;
    adc_key_val[2] = 360;
    adc_key_val[3] = 550;
    adc_key_val[4] = 780;
It would be nice if I could give an array of the resistor values and that the constructor calculated the internal key_values.

something like this ...
Code:
AnalogDebounce::AnalogDebounce(byte pin,button_callback f, int count, int * resistorArray) // assuming all values in same unit KOhm
{
  uint16_t sum = 0;
  for( int i=0; i< count; i++)
  {
    sum += resistorArray[i];
  }
  uint16_t partial = 0;
  for(int i=0; i< count; i++)
  {
    partial += resistorArray[i];
    adc_key_val[i] = (partial * 1024) / sum;  // partial might need an initial correction factor
  }
   etc...
It is a bit more code but the user only has to fill in the resistors used. No magic numbers smiley

What do you think of this idea?

Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 170
Posts: 12483
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


    minPressTime = 70;
    repeatDelay = 150;

These magic numbers should appear in the constructor interface too, with above mentionaed as default.
Or be a property of the class imho.

just thinking out loud ..
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Offline Offline
Full Member
***
Karma: 1
Posts: 127
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The minPressTime and repeatDelay are properties of the class. 

As far as specifying the resistors that is interesting...  I will have to experiment around with the idea and see if it would work well.  I do want to make it easier to specify buttons and values beyond the standard set now.

I do appreciate the feedback!
Logged

Greenville, IL
Offline Offline
Edison Member
*
Karma: 11
Posts: 1310
Warning Novice on board! 0 to 1 chance of errors!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


  I want to share a thought but, I will have to use an example to do it.

 I have a Olimex STM 32 (LeafLabs Maple clone) and the counts are different when using analog buttons in comparison to the Arduino Uno. To use the DFRobot sketches, I had to adjust the values by testing each button with the serial monitor showing the analogRead results. This is because of the higher bit resolution of the analogRead.

 That being said, to be able to port the library to other boards such as the Due, you may need a way to work with a spread of analogRead results.
Logged


Offline Offline
Full Member
***
Karma: 1
Posts: 127
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Indeed you are correct, the current defaults are based on a 10bit ADC, though really once you set it up you could do button.adc_key_val[0-4] = whatever.

I am going to figure out a much better way to handle the number of buttons and different resistor values. 
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 170
Posts: 12483
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

using the resitor values will work

Quick python sketch shows it can be done quite easily (C++ will need array size parameter)
Code:
def analogValues(resistors):
"""
builds a list of values for analogRead() based upon resistor values
"""
sum = 0
for val in resistors:
sum += val
partial = 0
av = [0]
for val in resistors:
partial += val
# print partial, (partial * 1023) / sum
av.append( (partial * 1023) / sum)
return av

def findClosestIndex(val, values):
"""
finds the index in values that matches val best
"""
min = val
idx = 0
for i in range(len(values)):
dist = abs(val-values[i])
if (dist < min):
min = dist
idx = i
# print dist
return idx

#
# prog starts here
#
resistors = [100,400,100,200,400,300,400,100,200,400,300,100]
av = analogValues(resistors)
print av

for i in range(103):
val = i * 10
idx = findClosestIndex(val, av)
print val, idx, av[idx], abs(val-av[idx])

findClosestIndex() can be optimized by stopping the search when the distance rises again (~ factor 2)

1023 in the code is a hard coded max value of the ADC; could be a parametrized.
« Last Edit: October 19, 2012, 04:18:29 am by robtillaart » Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Pages: [1]   Go Up
Jump to: