Tactile switch - measuring contact time

Hi guys,

I'm very new to Arduino, but am very keen to learn and am hoping that people might be able to point me in the right direction.

As part of my final year university project, I'm looking to find a way to use an Arduino board to measure the duration of a switch being closed. I've been looking at a number of different ways, but none of it seems to work. I was hoping that someone might be able to point me in the right direction as to how to write some code capable of measuring this. I may have missed this, but I thought that there may be some functions available which measure contact time or something along those lines.

If anyone has any advice or potential solutions to my problem, I would very much appreciate it.

Thanks!

Hi

but I thought that there may be some functions available which measure contact time

Explain this better, what you mean by contact time ?

I want the Arduino board to be able to tell me how long a switch is closed for once it has been pressed. So when the button is high, I'd like to be able to take a reading and measure time.

Use the external interrupt and the CHANGE option. When the switch is pressed record the value of micros() and also when it is released. Subtract one from the other for the duration.

HOWEVER switch contacts frequently bounce so you may not get a simple answer.

Maybe create an array to hold a succession of 8 or 16 micros() readings.

...R

I want the Arduino board to be able to tell me how long a switch is closed for once it has been pressed. So when the button is high, I’d like to be able to take a reading and measure time.

It is more simple to use these tactile buttons with INPUT_PULLUP and the pressed state will be LOW.

pinMode(buttonPin, INPUT_PULLUP);

If your tactile button is one of the common square ones, you will wire diagonally across the switch. One lead goes to ground, the other to the input pin,

Some of what you do next is dependent upon how you want to use the knowledge of the duration of the press. If you are trying to distinguish between a long and a short press for an operator interface you don’t need interrupts, but you will need debouncing. You can choose to use one of the many button libraries available, and Bounce2 is a good one.

If there is some precise timing to microseconds you could use interrupts, but the debouncing may be better in hardware.

Your next task is to write the code which detects the moment when a button is pressed. Save justPressed = millis().
Then write code which detect the moment a button is released. Save the justReleased = millis().
Subtract the values.

Here’s a pretty basic example using Bounce2

// Include the Bounce2 library found here :
// https://github.com/thomasfredericks/Bounce2
#include <Bounce2.h>

#define buttonPin 5

// Instantiate a Bounce object called button 
Bounce button = Bounce();

unsigned long buttonPressStartTimeStamp;
unsigned long buttonPressDuration;

void setup() {
  Serial.begin(115200);
  // Setup the button with an internal pull-up
  pinMode(buttonPin, INPUT_PULLUP);
  button.attach(buttonPin);
  button.interval(20);//set debounce interval
}

void loop() {

  // Update the Bounce instance, does digitalRead of button
  button.update();

  // Button press transition from HIGH to LOW)
  if (button.fell())
  {
    buttonPressStartTimeStamp = millis();
  }

  // Button release transition from LOW to HIGH) :
  if (button.rose())
  {
    buttonPressDuration = (millis() - buttonPressStartTimeStamp);
    Serial.print("Button pressed for ");
    Serial.print(buttonPressDuration); 
    Serial.println(" milliseconds");   
  }
}

cattledog: Here's a pretty basic example using Bounce2

Won't the Bounce library disguise the actual switch-pressed time?

I assume that is its purpose?

...R

Thank you all for your comments and suggestions. I really appreciate the time you've taken to comment and I'm hopefully now a step closer with my project.

Won't the Bounce library disguise the actual switch-pressed time?

Yes.

First, in that the button is polled, the press detection will be dependent upon the loop speed of the code.

Second, Bounce2 has two different methods of debounce.

The default method of the Bounce2 library looks for a stable reading longer than the debounce interval. So indeed, that will shift the captured time of the press and release by the debounce interval. For a human interface scheme, to detect short, or long presses, this is no issue. If you are timing two button presses against each other like in a game and the buttons have different bounce characteristics, and order of reading, it may be a problem.

There is a second method BOUNCE_WITH_PROMPT_DETECTION which accepts the initial change and then locks out any subsequent changes for a given period of time. With this method you can capture the initial and trailing edge time when seen by digitalRead().

// Uncomment the following line for "BOUNCE_WITH_PROMPT_DETECTION" debounce method
//#define BOUNCE_WITH_PROMPT_DETECTION

The lock out vs stable period debounce methods are a matter of choice for the application. When using interrupts, the lock out method is the only one available. The stable interval method is resistant to noise on the signal line.

Thanks for your responses. I've been successful using the Bounce 2 suggestion. I'm now looking to increase it to include multiple switches, but am struggling to overcome this issue. Does anyone have any ideas on the coding for measuring contact time of multiple switches?

Thanks

The way this forum works is that you post your code (within the code tags of course), and explain what it is doing that you don't want it to do, and what it is not doing which you want it to do. Don't say "it doesn't work". If your code does not compile, post complete error messages.

A Google or forum search for "Bounce2 multiple buttons" will give you many ideas.

The Bounce2 library has an example for 2 buttons. Start with this and your currently working sketch. It's really just duplication. You should be able to do this for many buttons. However, with many more buttons you might want to work with arrays to keep the code cleaner.

Please explain the purpose of your program, and what you want to do with the press durations.