A (Hopefuly) Useful Analog Button Library

I use analog buttons on my products, to save pins. I have a simple library I use to do the grunt work. It allows the caller to specify the A/D pin to use, as well as the voltage ranges corresponding to each button on that pin. Using this, at least 8 or more buttons can be connected to a single pin, using a resistor network to ensure each button, when pressed, results in a unique voltage on the A/D pin.

The user can also specify an integer "button code" to be associated with each button.

The library does debounce, to eliminate false events. In addition to reporting button presses several "gestures" are recognized:

SHORT PRESS - this is a quick press and release of a button. The minumum duration of the press is the debounce interval (50 mS by default). The maximum duration of the press is 250mS.

DOUBLE PRESS - this is two quick, back-to-back SHORT PRESSES on a single button. Press and release timing is identical to SHORT PRESS. The maximum period between the two presses is the same as the SHORT PRESS maximum duration

LONG PRESS - this is a press-and-hold of a button. The minimum hold time is twice the SHORT PRESS maximum duration, or 500 mS.

An optional REPEAT mode can be enabled which will cause REPEAT events to be generated at four evennts/second between the time a LONG PRESS event is reported, and the button is released.

The ReadButtons function must be called periodically in the loop() function. Use of delay() with long periods will very likely result in missed events. ReadButtons will return a structure which contains an event type, and a button code. The button code is the user-provided code for the button that generated the event.

The event types are:

BUTTON_EVENT_NONE - NO button events to report
BUTTON_EVENT_PRESSED - A button has been pressed
BUTTON_EVENT_SHORTPRESS - A button has been SHORT pressed
BUTTON_EVENT_LONGPRESS - A button has bene LONG pressed
BUTTON_EVENT_REPEAT - A button has been LONG pressed, and is being held
BUTTON_EVENT_RELEASED - A button has been released
BUTTON_EVENT_DOUBLEPRESS - A button has been DOUBLE pressed

In most applications, only BUTTON_EVENT_SHORTPRESS, and perhaps BUTTON_EVENT_DOUBLEPRESS will be used. If BUTTON_EVENT_LONGPRESS is used, then BUTTON_EVENT_RELEASED should also be used to tell when the button has been released.

The event sequences are:

SHORT PRESS:
BUTTON_EVENT_PRESSED
BUTTON_EVENT_SHORTPRESS

LONG PRESS:
BUTTON_EVENT_PRESSED
BUTTON_EVENT_LONGPRESS
BUTTON_EVENT_REPEAT ==> Only issued if REPEAT is enabled
BUTTON_EVENT_RELEASED

DOUBLE PRESS:
BUTTON_EVENT_PRESSED
BUTTON_EVENT_SHORTPRESS
BUTTON_EVENT_PRESSED
BUTTON_EVENT_DOUBLEPRESS

Note that rollover is NOT supported!! pressing multiple buttons will result in erroneous event reports unless your hardware configuration takes rollover into account.

There is a Test directory in the ZIP file which contains a simple test program that demonstrates how to use the library. You will probably want to re-define the Buttons structure in the test program to match your hardware configuration. The configuration I used here is described in the file.

The library is below. I won't guarantee this is 100% bug-free, but I believe it is.

Regards,
Ray L.

NewAnalogButtons.zip (4.5 KB)

You should take a look at this video

A Youtube Video

Basically, this guy uses a 74HC595 (or multiple of them) to increase the number of button inputs.
Its hard to explain, so you should just watch it, and it has the benefit of detecting multiple buttons pressed at the same time...

Too tedious to watch, 20 minutes, and there's a part 2! How about just presenting the schematic?

So basically what you would do is keep all pins on the shift register HIGH, then when your input reads HIGH, then you run a routine or ISR that cycles through all the bits with buttons on them, so you would shift out 1, 2, 4, 8, 16, 32, 64, 128, ...
When your input reads HIGH again, it means that button connected to that pin of the shift register is being pressed, but you can continue cycling even after you found the pressed button to see if there are multiple buttons being pressed.

Does that make any sense?

Seems like a coding nightmare.
Why not just use a shift-in register, 74HC165 with inputs pulled high, and capture all the pins at once then go thru and act on any 0s that are detected?
Simple SPI.transfer to bring them in, then look at the 8 bits one by one.
You're using IO pins either way, this way you're not dealing with slowness of an ADC pin too.

Ahem cough...no comment :astonished:

Not a bad idea

Btw " this way you're not dealing with slowness of an ADC pin too.". You dont need to use an ADC pin, unless your talking to OP

Would like to use library. Need circuit diagram for buttons which does not appear in forum .cpp or .h

RayLivingston:
I use analog buttons on my products, to save pins. I have a simple library I use to do the grunt work. It allows the caller to specify the A/D pin to use, as well as the voltage ranges corresponding to each button on that pin. Using this, at least 8 or more buttons can be connected to a single pin, using a resistor network to ensure each button, when pressed, results in a unique voltage on the A/D pin.

Nice! I was contemplating something like this for a couple of salvaged keypads. I decided to check prior art and, ta da! It's already done. Thanks!